This repository has been archived by the owner on Jan 29, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFrameLimit.py
128 lines (94 loc) · 3.84 KB
/
FrameLimit.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
from __future__ import division
import pygame
import time
import random
class GameTime(object):
def __init__(self, desired_fps=120, desired_ticks=60):
self.start_time = time.time()
self.desired_fps = desired_fps
self.desired_ticks = desired_ticks
self.ticks = 0
self.framerate_counter = 1
self.framerate_time = 0
def calculate_ticks(self, current_time):
"""Ensure the correct number of ticks have passed since the
start of the game.
This doesn't use the inbuilt pygame ticks.
"""
time_elapsed = current_time - self.start_time
total_ticks_needed = int(time_elapsed * self.desired_ticks)
ticks_this_frame = total_ticks_needed - self.ticks
self.ticks += ticks_this_frame
return ticks_this_frame
def calculate_fps(self, current_time, update_time=0.1):
"""Calculate the FPS from actual time, not ticks.
It will return a number every update_time seconds, and will
return None any other time.
"""
frame_time = current_time - self.framerate_time
if frame_time < update_time:
self.framerate_counter += 1
else:
self.framerate_time = current_time
fps = self.framerate_counter / frame_time
self.framerate_counter = 1
return int(fps)
def limit_fps(self, alternate_fps=None):
wanted_fps = alternate_fps or self.desired_fps
if wanted_fps:
pygame.time.Clock().tick(wanted_fps)
class GameTimeLoop(object):
"""This gets called every loop but uses GameTime."""
def __init__(self, GTObject):
self.GTObject = GTObject
GTObject.loop_start = time.time()
#Run the code once so the result can be called multiple times
self.ticks = GTObject.calculate_ticks(GTObject.loop_start)
self.fps = GTObject.calculate_fps(GTObject.loop_start)
self.temp_fps = None
def __enter__(self):
return self
def __exit__(self, *args):
self.GTObject.limit_fps(self.temp_fps)
self.temp_fps = None
def set_fps(self, fps):
self.GTObject.desired_fps = fps
def temp_fps(self, fps):
self.temp_fps = fps
def update_ticks(self, ticks):
self.GTObject.start_time = time.time()
self.GTObject.desired_ticks = ticks
self.ticks = 0
#Example use
def game():
pygame.init()
screen = pygame.display.set_mode((640, 480))
#clock = pygame.time.Clock()
max_fps = None
ticks_per_second = 60
FrameRate = GameTime(max_fps, ticks_per_second)
move_speed = 0.175
move_total = 0
while True:
with GameTimeLoop(FrameRate) as frame_time:
fps = frame_time.fps
if fps:
pygame.display.set_caption(str(fps))
#Calculations to be done once per tick
#Can multiply by the number of ticks or do a loop
ticks_this_frame = frame_time.ticks
for tick in xrange(frame_time.ticks):
pass
#Do normal stuff here
move_total += move_speed * ticks_this_frame
print move_total #Just print this to show it's correctly staying at the same speed
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
#Set a new fps
if event.type == pygame.MOUSEBUTTONDOWN:
new_fps = random.choice((None, 1, 5, 10, 30, 60, 120, 1000, 10000))
print 'set fps to: {}'.format(new_fps)
frame_time.set_fps(new_fps)
if __name__ == '__main__':
game()