-
Notifications
You must be signed in to change notification settings - Fork 0
/
StateMachine.lua
111 lines (102 loc) · 2.72 KB
/
StateMachine.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
--
-- StateMachine - a state machine
--
-- Usage:
--
-- -- States are only created as need, to save memory, reduce clean-up bugs and increase speed
-- -- due to garbage collection taking longer with more data in memory.
-- --
-- -- States are added with a string identifier and an intialisation function.
-- -- It is expect the init function, when called, will return a table with
-- -- Render, Update, Enter and Exit methods.
--
-- gStateMachine = StateMachine {
-- ['MainMenu'] = function()
-- return MainMenu()
-- end,
-- ['InnerGame'] = function()
-- return InnerGame()
-- end,
-- ['GameOver'] = function()
-- return GameOver()
-- end,
-- }
-- gStateMachine:change("MainGame")
--
-- Arguments passed into the Change function after the state name
-- will be forwarded to the Enter function of the state being changed too.
--
-- State identifiers should have the same name as the state table, unless there's a good
-- reason not to. i.e. MainMenu creates a state using the MainMenu table. This keeps things
-- straight forward.
--
-- =Doing Transitions=
--
StateMachine = Class{}
function StateMachine:init(states)
self.empty = {
render = function() end,
update = function() end,
pause = function() end,
back = function() end,
keypressed = function() end,
enter = function() end,
exit = function() end
}
self.states = states or {} -- [name] -> [function that returns states]
self.current = self.empty
self.state = nil
end
function StateMachine:change(stateName, enterParams, exitParams)
assert(self.states[stateName]) -- state must exist!
self.current:exit(exitParams)
if not exitParams then
love.audio.stop()
songs = {}
background = {}
elseif exitParams == 'music' then
background = {}
end
gui = {}
paused = false
mouseLocked = false
yscroll = 0
rawyscroll = 0
self.current = self.states[stateName]()
self.state = stateName
self.current:enter(enterParams)
if songs[1] and not exitParams then
currentSong = 1
songs[1]:play()
end
if not love.mouse.isVisible() and gui[1] then
repositionMouse(1)
end
if gui[#gui] then
maxScroll = math.max(gui[#gui].y + gui[#gui].height + 50 - 1080, 0)
else
maxScroll = 0
end
collectgarbage()
end
function StateMachine:update(dt)
self.current:update(dt)
end
function StateMachine:pause()
self.current:pause()
end
function StateMachine:back()
self.current:back()
end
function StateMachine:keypressed(key,isrepeat)
return self.current:keypressed(key,isrepeat)
end
function StateMachine:renderBackground()
return self.current:renderBackground()
end
function StateMachine:renderNormal()
self.current:renderNormal()
end
function StateMachine:renderForeground()
self.current:renderForeground()
end