Pygame Draw Moving Shapes Source Code
draw_shapes.py
1"""
2Moving Sprite Stress Test
3
4Simple program to test how fast we can draw sprites that are moving
5
6Artwork from http://kenney.nl
7"""
8
9# noinspection PyPackageRequirements
10import pygame
11import random
12import os
13from performance_timing import PerformanceTiming
14
15# Define some colors
16BLACK = (0, 0, 0)
17WHITE = (255, 255, 255)
18RED = (255, 0, 0)
19
20# --- Constants ---
21SPRITE_SCALING_COIN = 0.25
22SPRITE_NATIVE_SIZE = 128
23SPRITE_SIZE = int(SPRITE_NATIVE_SIZE * SPRITE_SCALING_COIN)
24
25RESULTS_FILE = "../../result_data/pygame/moving_shapes.csv"
26RESULTS_IMAGE = "../../result_data/pygame/moving_shapes.png"
27SCREEN_WIDTH = 1800
28SCREEN_HEIGHT = 1000
29SCREEN_TITLE = "Pygame - Moving Shapes Stress Test"
30
31
32class Shape:
33 """ Generic base shape class """
34 def __init__(self, x, y, width, height, angle, delta_x, delta_y,
35 delta_angle, color):
36 self.x = x
37 self.y = y
38 self.width = width
39 self.height = height
40 self.angle = angle
41 self.delta_x = delta_x
42 self.delta_y = delta_y
43 self.delta_angle = delta_angle
44 self.color = color
45
46 def move(self):
47 self.x += self.delta_x
48 self.y += self.delta_y
49 self.angle += self.delta_angle
50 if self.x < 0 and self.delta_x < 0:
51 self.delta_x *= -1
52 if self.y < 0 and self.delta_y < 0:
53 self.delta_y *= -1
54 if self.x > SCREEN_WIDTH and self.delta_x > 0:
55 self.delta_x *= -1
56 if self.y > SCREEN_HEIGHT and self.delta_y > 0:
57 self.delta_y *= -1
58
59class Rectangle(Shape):
60
61 def draw(self, surface):
62 rect = pygame.Rect(self.x, self.y, self.width, self.height)
63 pygame.draw.rect(surface, self.color, rect)
64
65class Ellipse(Shape):
66
67 def draw(self, surface):
68 rect = pygame.Rect(self.x, self.y, self.width, self.height)
69 pygame.draw.ellipse(surface, self.color, rect)
70
71class MyGame:
72 """ Our custom Window Class"""
73
74 def __init__(self):
75 """ Initializer """
76
77 # Set the working directory (where we expect to find files) to the same
78 # directory this .py file is in. You can leave this out of your own
79 # code, but it is needed to easily run the examples using "python -m"
80 # as mentioned at the top of this program.
81 file_path = os.path.dirname(os.path.abspath(__file__))
82 os.chdir(file_path)
83
84 # Variables that will hold sprite lists
85 self.shape_list = []
86
87 self.performance_timing = PerformanceTiming(results_file=RESULTS_FILE,
88 start_n=0,
89 increment_n=200,
90 end_time=60)
91
92
93 # Initialize Pygame
94 pygame.init()
95 pygame.display.set_caption(SCREEN_TITLE)
96
97 # Set the height and width of the screen
98 self.screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
99
100 # This is a list of every sprite. All blocks and the player block as well.
101 self.coin_list = pygame.sprite.Group()
102
103 self.font = pygame.font.SysFont('Calibri', 25, True, False)
104
105 def add_shapes(self, amount):
106 for i in range(amount):
107 x = random.randrange(0, SCREEN_WIDTH)
108 y = random.randrange(0, SCREEN_HEIGHT)
109 width = random.randrange(10, 30)
110 height = random.randrange(10, 30)
111 angle = random.randrange(0, 360)
112
113 d_x = random.randrange(-3, 4)
114 d_y = random.randrange(-3, 4)
115 d_angle = random.randrange(-3, 4)
116
117 red = random.randrange(256)
118 green = random.randrange(256)
119 blue = random.randrange(256)
120 # alpha = random.randrange(256)
121
122 shape_type = random.randrange(2)
123 shape_type = 0
124
125 if shape_type == 0:
126 shape = Rectangle(x, y, width, height, angle, d_x, d_y,
127 d_angle, (red, green, blue))
128 elif shape_type == 1:
129 shape = Ellipse(x, y, width, height, angle, d_x, d_y,
130 d_angle, (red, green, blue))
131 # elif shape_type == 2:
132 # shape = Line(x, y, width, height, angle, d_x, d_y,
133 # d_angle, (red, green, blue, alpha))
134
135 self.shape_list.append(shape)
136
137 def on_draw(self):
138 """ Draw everything """
139
140 # Start timing how long this takes
141 self.performance_timing.start_timer('draw')
142
143 # Clear the screen
144 self.screen.fill((0, 0, 0))
145
146 for shape in self.shape_list:
147 shape.draw(self.screen)
148
149 pygame.display.flip()
150
151 # Stop timing how long this takes
152 self.performance_timing.stop_timer('draw')
153
154 def update(self, _delta_time):
155 # Start update timer
156 self.performance_timing.start_timer('update')
157
158 for shape in self.shape_list:
159 shape.move()
160
161 # Stop timing the update
162 self.performance_timing.stop_timer('update')
163
164 # Figure out if we need more coins
165 if self.performance_timing.target_n > len(self.shape_list):
166 new_coin_amount = self.performance_timing.target_n - len(self.shape_list)
167 self.add_shapes(new_coin_amount)
168
169
170def main():
171 """ Main method """
172 window = MyGame()
173
174 # Loop until the user clicks the close button.
175 done = False
176
177 # Used to manage how fast the screen updates
178 clock = pygame.time.Clock()
179
180 # -------- Main Program Loop -----------
181 while not window.performance_timing.end_run() and not done:
182 for event in pygame.event.get():
183 if event.type == pygame.QUIT:
184 done = True
185 window.update(0)
186 window.on_draw()
187 clock.tick(60)
188
189 # Save screenshot
190 pygame.image.save(window.screen, RESULTS_IMAGE)
191
192 pygame.quit()
193
194
195if __name__ == "__main__":
196 main()