1
2
4
5 """Manages time in a game."""
6
7 - def __init__(self, game_ticks_per_second=20):
8
9 """Create a Game Clock object.
10
11 game_ticks_per_second -- The number of logic frames a second.
12
13 """
14
15 self.game_ticks_per_second = float(game_ticks_per_second)
16 self.game_tick = 1. / self.game_ticks_per_second
17 self.speed = 1.
18
19 self.clock_time = 0.
20 self.virtual_time = 0.
21 self.game_time = 0.
22 self.game_frame_count = 0
23 self.real_time_passed = 0.
24
25 self.real_time = self.get_real_time()
26 self.started = False
27 self.paused = False
28 self.between_frame = 0.0
29
30 self.fps_sample_start_time = 0.0
31 self.fps_sample_count = 0
32 self.average_fps = 0
33
34
36
37 """Starts the Game Clock. Must be called once."""
38
39 if self.started:
40 return
41
42 self.clock_time = 0.
43 self.virtual_time = 0.
44 self.game_time = 0.
45 self.game_frame_count = 0
46 self.real_time_passed = 0.
47
48 self.real_time = self.get_real_time()
49 self.started = True
50
51 self.fps = 0.0
52 self.fps_sample_start_time = self.real_time
53 self.fps_sample_count = 0
54
55
57
58 """Sets the speed of the clock.
59
60 speed -- A time factor (1 is normal speed, 2 is twice normal)
61
62 """
63 assert isinstance(speed, float), "Must be a float"
64
65 if speed < 0.0:
66 raise ValueError("Negative speeds not supported")
67
68 self.speed = speed
69
70
72
73 """Pauses the Game Clock."""
74
75 self.pause = True
76
78
79 """Un-pauses the Game Clock."""
80
81 self.pause = False
82
83
85
86 """Returns the real time, as reported by the system clock.
87 This method may be overriden."""
88
89 import time
90 return time.clock()
91
92
94
95 """Retrieves the current frames per second as a tuple containing
96 the fps and average fps over a second."""
97
98 return self.fps, self.average_fps
99
100
102
103 """Returns the interpolant between the previous game tick and the
104 next game tick."""
105
106 return self.between_frame
107
108
109 - def update(self, max_updates = 0):
110
111 """Advances time, must be called once per frame. Yields tuples of
112 game frame count and game time.
113
114 max_updates -- Maximum number of game time updates to issue.
115
116 """
117
118 assert self.started, "You must call 'start' before using a GameClock."
119
120 real_time_now = self.get_real_time()
121
122 self.real_time_passed = real_time_now - self.real_time
123 self.real_time = real_time_now
124
125 self.clock_time += self.real_time_passed
126
127 if not self.paused:
128 self.virtual_time += self.real_time_passed * self.speed
129
130 update_count = 0
131 while self.game_time + self.game_tick < self.virtual_time:
132
133 self.game_frame_count += 1
134 self.game_time = self.game_frame_count * self.game_tick
135 yield (self.game_frame_count, self.game_time)
136
137 if max_updates and update_count == max_updates:
138 break
139
140 self.between_frame = ( self.virtual_time - self.game_time ) / self.game_tick
141
142 if self.real_time_passed != 0:
143 self.fps = 1.0 / self.real_time_passed
144 else:
145 self.fps = 0.0
146
147 self.fps_sample_count += 1
148
149 if self.real_time - self.fps_sample_start_time > 1.0:
150
151 self.average_fps = self.fps_sample_count / (self.real_time - self.fps_sample_start_time)
152 self.fps_sample_start_time = self.real_time
153 self.fps_sample_count = 0
154
155
156 if __name__ == "__main__":
157
158 import time
159 t = GameClock(20)
160 t.start()
161
162 while t.virtual_time < 2.0:
163
164 for (frame_count, game_time) in t.update():
165
166 print "Game frame #%i, %2.4f" % (frame_count, game_time)
167
168 virtual_time = t.virtual_time
169 print "\t%2.2f%% between game frame, time is %2.4f"%(t.between_frame*100., virtual_time)
170
171
172 time.sleep(0.2)
173