Pygame Collision Source Code
collision.py
1"""
2Sample Python/Pygame Programs
3Simpson College Computer Science
4http://programarcadegames.com/
5http://simpson.edu/computer-science/
6"""
7
8# noinspection PyPackageRequirements
9import pygame
10import random
11import os
12from performance_timing import PerformanceTiming
13
14# Define some colors
15BLACK = (0, 0, 0)
16WHITE = (255, 255, 255)
17RED = (255, 0, 0)
18
19# --- Constants ---
20SPRITE_SCALING_COIN = 0.09
21SPRITE_SCALING_PLAYER = 0.5
22SPRITE_NATIVE_SIZE = 128
23SPRITE_SIZE = int(SPRITE_NATIVE_SIZE * SPRITE_SCALING_COIN)
24
25SCREEN_WIDTH = 1800
26SCREEN_HEIGHT = 1000
27SCREEN_TITLE = "Pygame - Moving Sprite Stress Test"
28
29RESULTS_FILE = "../../result_data/pygame/collision.csv"
30RESULTS_IMAGE = "../../result_data/pygame/collision.png"
31
32
33class Coin(pygame.sprite.Sprite):
34 """
35 This class represents the ball
36 It derives from the "Sprite" class in Pygame
37 """
38 # Static coin image
39 coin_image = None
40
41 def __init__(self):
42 """ Constructor. Pass in the color of the block,
43 and its x and y position. """
44 # Call the parent class (Sprite) constructor
45 super().__init__()
46
47 # In Pygame, if we load and scale a coin image every time we create a sprite,
48 # this will result in a noticeable performance hit. Therefore we do it once,
49 # and re-use that image over-and-over.
50 if Coin.coin_image is None:
51 # Create an image of the block, and fill it with a color.
52 # This could also be an image loaded from the disk.
53 Coin.coin_image = pygame.image.load("../resources/coinGold.png")
54 rect = Coin.coin_image.get_rect()
55 Coin.coin_image = pygame.transform.scale(
56 Coin.coin_image,
57 (int(rect.width * SPRITE_SCALING_COIN), int(rect.height * SPRITE_SCALING_COIN)))
58 Coin.coin_image.convert()
59 Coin.coin_image.set_colorkey(BLACK)
60
61 self.image = Coin.coin_image
62
63 # Fetch the rectangle object that has the dimensions of the image
64 # image.
65 # Update the position of this object by setting the values
66 # of rect.x and rect.y
67 self.rect = self.image.get_rect()
68
69
70class Player(pygame.sprite.Sprite):
71 """
72 This class represents the ball
73 It derives from the "Sprite" class in Pygame
74 """
75
76 def __init__(self):
77 """ Constructor. Pass in the color of the block,
78 and its x and y position. """
79 # Call the parent class (Sprite) constructor
80 super().__init__()
81
82 # Create an image of the block, and fill it with a color.
83 # This could also be an image loaded from the disk.
84 image = pygame.image.load("../resources/femalePerson_idle.png")
85 rect = image.get_rect()
86 image = pygame.transform.scale(image, (
87 int(rect.width * SPRITE_SCALING_PLAYER), int(rect.height * SPRITE_SCALING_PLAYER)))
88 self.image = image.convert()
89 self.image.set_colorkey(BLACK)
90
91 # Fetch the rectangle object that has the dimensions of the image
92 # image.
93 # Update the position of this object by setting the values
94 # of rect.x and rect.y
95 self.rect = self.image.get_rect()
96
97 self.change_x = 0
98 self.change_y = 0
99
100 def update(self):
101 """ Called each frame. """
102 self.rect.x += self.change_x
103 self.rect.y += self.change_y
104
105
106class MyGame:
107 """ Our custom Window Class"""
108
109 def __init__(self):
110 """ Initializer """
111
112 # Set the working directory (where we expect to find files) to the same
113 # directory this .py file is in. You can leave this out of your own
114 # code, but it is needed to easily run the examples using "python -m"
115 # as mentioned at the top of this program.
116 file_path = os.path.dirname(os.path.abspath(__file__))
117 os.chdir(file_path)
118
119 # Variables that will hold sprite lists
120 self.coin_list = None
121
122 self.performance_timing = PerformanceTiming(results_file=RESULTS_FILE,
123 start_n=0,
124 increment_n=1000,
125 end_time=60)
126
127 # Initialize Pygame
128 pygame.init()
129
130 # Set the height and width of the screen
131 self.screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
132
133 # This is a list of every sprite. All blocks and the player block as well.
134 self.coin_list = pygame.sprite.Group()
135 self.player_list = pygame.sprite.Group()
136
137 # Create the player instance
138 self.player = Player()
139
140 self.player.rect.x = random.randrange(SPRITE_SIZE, SCREEN_WIDTH - SPRITE_SIZE)
141 self.player.rect.y = random.randrange(SPRITE_SIZE, SCREEN_HEIGHT - SPRITE_SIZE)
142 self.player.change_x = 3
143 self.player.change_y = 5
144
145 self.player_list.add(self.player)
146
147 self.font = pygame.font.SysFont('Calibri', 25, True, False)
148
149 def add_coins(self, amount):
150
151 # Create the coins
152 for i in range(amount):
153 # Create the coin instance
154 # Coin image from kenney.nl
155 coin = Coin()
156
157 # Position the coin
158 coin.rect.x = random.randrange(SPRITE_SIZE, SCREEN_WIDTH - SPRITE_SIZE)
159 coin.rect.y = random.randrange(SPRITE_SIZE, SCREEN_HEIGHT - SPRITE_SIZE)
160
161 # Add the coin to the lists
162 self.coin_list.add(coin)
163
164 def on_draw(self):
165 """ Draw everything """
166
167 # Start timing how long this takes
168 self.performance_timing.start_timer('draw')
169
170 # Clear the screen
171 self.screen.fill((59, 122, 87))
172
173 # Draw all the spites
174 self.coin_list.draw(self.screen)
175 self.player_list.draw(self.screen)
176
177 pygame.display.flip()
178
179 # Stop timing how long this takes
180 self.performance_timing.stop_timer('draw')
181
182 def update(self, _delta_time):
183 # Start update timer
184 self.performance_timing.start_timer('update')
185
186 # Start update timer
187 self.player_list.update()
188
189 if self.player.rect.x < 0 and self.player.change_x < 0:
190 self.player.change_x *= -1
191 if self.player.rect.y < 0 and self.player.change_y < 0:
192 self.player.change_y *= -1
193
194 if self.player.rect.x > SCREEN_WIDTH and self.player.change_x > 0:
195 self.player.change_x *= -1
196 if self.player.rect.y > SCREEN_HEIGHT and self.player.change_y > 0:
197 self.player.change_y *= -1
198
199 coin_hit_list = pygame.sprite.spritecollide(self.player, self.coin_list, False)
200 for coin in coin_hit_list:
201 coin.rect.x = random.randrange(SCREEN_WIDTH)
202 coin.rect.y = random.randrange(SCREEN_HEIGHT)
203
204 # Stop timing the update
205 self.performance_timing.stop_timer('update')
206
207 # Figure out if we need more coins
208 if self.performance_timing.target_n > len(self.coin_list):
209 new_coin_amount = self.performance_timing.target_n - len(self.coin_list)
210 self.add_coins(new_coin_amount)
211
212
213def main():
214 """ Main method """
215 window = MyGame()
216
217 # Loop until the user clicks the close button.
218 done = False
219
220 # Used to manage how fast the screen updates
221 clock = pygame.time.Clock()
222
223 # -------- Main Program Loop -----------
224 while not window.performance_timing.end_run() and not done:
225 for event in pygame.event.get():
226 if event.type == pygame.QUIT:
227 done = True
228 window.update(0)
229 window.on_draw()
230 clock.tick(60)
231
232 # Save screenshot
233 pygame.image.save(window.screen, RESULTS_IMAGE)
234
235 pygame.quit()
236
237
238if __name__ == "__main__":
239 main()