forked from wesleywerner/mvc-game-design
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodel.py
100 lines (85 loc) · 2.62 KB
/
model.py
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
import pygame
from eventmanager import *
class GameEngine(object):
"""
Tracks the game state.
"""
def __init__(self, evManager):
"""
evManager (EventManager): Allows posting messages to the event queue.
Attributes:
running (bool): True while the engine is online. Changed via QuitEvent().
"""
self.evManager = evManager
evManager.RegisterListener(self)
self.running = False
self.state = StateMachine()
def notify(self, event):
"""
Called by an event in the message queue.
"""
if isinstance(event, QuitEvent):
self.running = False
if isinstance(event, StateChangeEvent):
# pop request
if not event.state:
# false if no more states are left
if not self.state.pop():
self.evManager.Post(QuitEvent())
else:
# push a new state on the stack
self.state.push(event.state)
def run(self):
"""
Starts the game engine loop.
This pumps a Tick event into the message queue for each loop.
The loop ends when this object hears a QuitEvent in notify().
"""
self.running = True
self.evManager.Post(InitializeEvent())
self.state.push(STATE_MENU)
while self.running:
newTick = TickEvent()
self.evManager.Post(newTick)
# State machine constants for the StateMachine class below
STATE_INTRO = 1
STATE_MENU = 2
STATE_HELP = 3
STATE_ABOUT = 4
STATE_PLAY = 5
class StateMachine(object):
"""
Manages a stack based state machine.
peek(), pop() and push() perform as traditionally expected.
peeking and popping an empty stack returns None.
"""
def __init__ (self):
self.statestack = []
def peek(self):
"""
Returns the current state without altering the stack.
Returns None if the stack is empty.
"""
try:
return self.statestack[-1]
except IndexError:
# empty stack
return None
def pop(self):
"""
Returns the current state and remove it from the stack.
Returns None if the stack is empty.
"""
try:
self.statestack.pop()
return len(self.statestack) > 0
except IndexError:
# empty stack
return None
def push(self, state):
"""
Push a new state onto the stack.
Returns the pushed value.
"""
self.statestack.append(state)
return state