Skip to content

Commit 4b750c4

Browse files
committed
animated bullet + spritesheet
1 parent 0e0a4a3 commit 4b750c4

File tree

2 files changed

+76
-82
lines changed

2 files changed

+76
-82
lines changed

bullet.png

52 Bytes
Loading

main.py

Lines changed: 76 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import sys # Import the system module, literally just for quitting the game cleanly
1+
import sys
2+
import time
23
import pygame
34
from pygame.locals import *
4-
from random import randint, random # Import random functions from the random module
5+
from random import randint, random
56

67
FPS = 60
78
WIDTH, HEIGHT = 400, 400
@@ -14,104 +15,104 @@
1415
player_img = pygame.image.load("player.png").convert_alpha()
1516
player_img = pygame.transform.scale(player_img, (36, 56))
1617
cookie_img = pygame.image.load("cookie.png").convert_alpha()
17-
bullet_img = pygame.image.load("bullet.png").convert_alpha() # Load the bullet image
18-
bullet_img = pygame.transform.scale(bullet_img, (12, 28)) # Resize it to the correct size
19-
bg_img = pygame.image.load("background.png").convert() # We don't need the background to be transparent, so we use "convert"
18+
bullet_spritesheet = pygame.image.load("bullet.png").convert_alpha()
19+
bullet_imgs = []
20+
for x in range(4):
21+
bullet_img = bullet_spritesheet.subsurface(x * 3, 0, 3, 7)
22+
bullet_img = pygame.transform.scale(bullet_img, (12, 28))
23+
bullet_imgs.append(bullet_img)
24+
bg_img = pygame.image.load("background.png").convert()
2025

21-
class Player(pygame.sprite.Sprite): # Make the player have stuff that a pygame sprite needs to have (Inheriting from pygame.sprite.Sprite)
22-
def __init__(self): # The function that gets called when the sprite is created
23-
super().__init__() # Initialize the player as a pygame sprite
26+
class Player(pygame.sprite.Sprite):
27+
def __init__(self):
28+
super().__init__()
2429

25-
self.image = player_img # Set the player's image to the player image. Pygame uses this variable to draw the sprite
26-
self.rect = player_img.get_rect() # Generate the player's rect. Pygame uses this variable to know where to draw the sprite
30+
self.image = player_img
31+
self.rect = player_img.get_rect()
2732

28-
self.x = 180 # Custom x position variable
29-
self.y = 340 # Custom y position variable
33+
self.x = 180
34+
self.y = 340
3035

31-
def update(self): # The function that contains player logic
36+
def update(self):
3237
keys = pygame.key.get_pressed()
3338
if keys[K_LEFT]:
34-
self.x -= 4 # Get keys and move the player, we've done this before :P
39+
self.x -= 4
3540
if keys[K_RIGHT]:
3641
self.x += 4
3742

38-
self.rect.x = self.x # Update the player rect position to our x and y variables
43+
self.rect.x = self.x
3944
self.rect.y = self.y
4045

41-
if self.rect.left < 0: # Restrict the player's left to inside the screen
46+
if self.rect.left < 0:
4247
self.rect.left = 0
43-
self.x = self.rect.x # Re-update the rect after we do so
44-
elif self.rect.right > WIDTH: # Restrict the player's right to inside the screen
48+
self.x = self.rect.x
49+
elif self.rect.right > WIDTH:
4550
self.rect.right = WIDTH
46-
self.x = self.rect.x # Re-update the rect after we do so
47-
48-
# "spritecollide" detects collision between a sprite and sprites in a group
49-
# This function takes a sprite: "self" (the player)
50-
# takes a group: "cookies"
51-
# takes a boolean (True/False) that determines whether the collided sprite in the group gets deleted or not
52-
# and optionally takes a special function: "pygame.sprite.collide_rect_ratio(0.8)"
53-
# In this case, our special pygame function makes the rects of each sprite 0.8 times smaller (so it's harder to lose, you're welcome)
51+
self.x = self.rect.x
5452
if pygame.sprite.spritecollide(self, cookies, False, pygame.sprite.collide_rect_ratio(0.8)):
55-
pygame.quit() # If the player collided with something, quit the game
56-
sys.exit() # A new thingy that just makes sure the game closes correctly, don't worry about it
53+
pygame.quit()
54+
sys.exit()
5755

58-
def draw(self, screen): # Function that draw the player
59-
screen.blit(self.image, self.rect) # Draw the image at the position of the rect
56+
def draw(self, screen):
57+
screen.blit(self.image, self.rect)
6058

6159
class Cookie(pygame.sprite.Sprite):
62-
# The cookie takes 4 arguments in the brackets after __init__:
63-
# x: the x position of the cookie
64-
# y: the y position of the cookie
65-
# x_vel: the x velocity of the cookie
66-
# y_vel: the y_velocity of the cookie
6760
def __init__(self, x, y, x_vel, y_vel):
6861
super().__init__(cookies)
6962

70-
self.image = cookie_img # Set the cookie's image to cookie image
71-
self.rect = self.image.get_rect() # Generate a rect from the image
63+
self.image = cookie_img
64+
self.rect = self.image.get_rect()
7265

73-
self.x = x # The x position of the cookie
74-
self.y = y # The y position of the cookie
75-
self.x_vel = x_vel # The x velocity (speed) of the cookie
76-
self.y_vel = y_vel # The y velocity (speed) of the cookie
66+
self.x = x
67+
self.y = y
68+
self.x_vel = x_vel
69+
self.y_vel = y_vel
7770

7871
def update(self):
79-
self.x += self.x_vel # Add the x velocity to the x position
80-
self.y += self.y_vel # Add the y velocity to the y position
72+
self.x += self.x_vel
73+
self.y += self.y_vel
8174

82-
self.rect.x = self.x # Set the x position of the rect to draw the image at to be x
83-
self.rect.y = self.y # Set the y position of the rect to draw the image at to be y
75+
self.rect.x = self.x
76+
self.rect.y = self.y
8477

85-
if self.rect.left < 0 or self.rect.right > WIDTH: # If the left or right side of the rect is outside the window
86-
self.x_vel = -self.x_vel # Reverse the x velocity (bounce)
87-
if self.rect.top < 0 or self.rect.bottom > HEIGHT: # If the top or bottom side of the rect is outside the window
88-
self.y_vel = -self.y_vel # Reverse the y velocity (bounce)
78+
if self.rect.left < 0 or self.rect.right > WIDTH:
79+
self.x_vel = -self.x_vel
80+
if self.rect.top < 0 or self.rect.bottom > HEIGHT:
81+
self.y_vel = -self.y_vel
8982

9083
class Bullet(pygame.sprite.Sprite):
9184
def __init__(self, x, y):
9285
super().__init__(bullets)
9386

94-
self.image = bullet_img
87+
self.image = bullet_imgs[0]
88+
self.index = 0
89+
self.animation_time = time.time()
9590
self.rect = self.image.get_rect()
9691

9792
self.x = x
9893
self.y = y
9994

10095
def update(self):
101-
self.y -= 10 # Constantly move the bullet up
96+
self.image = bullet_imgs[self.index]
97+
if time.time() - self.animation_time > 0.1:
98+
self.animation_time = time.time()
99+
self.index += 1
100+
if self.index == 4:
101+
self.index = 0
102+
103+
self.y -= 10
102104

103-
# Update the center x and y position of the bullet, we are using "center" here so that it's easier to align the bullet with the player
104105
self.rect.centerx = self.x
105106
self.rect.centery = self.y
106107

107-
if self.rect.bottom < 0: # If the bottom side of the bullet goes above the top of the screen
108-
self.kill() # Remove the bullet, .kill() will remove the sprite from all groups, which will essentially delete it
108+
if self.rect.bottom < 0:
109+
self.kill()
109110

110-
bullets = pygame.sprite.Group() # Create a pygame group for bullets
111-
cookies = pygame.sprite.Group() # Create a pygame group for cookies
112-
player = Player() # Create the player
111+
bullets = pygame.sprite.Group()
112+
cookies = pygame.sprite.Group()
113+
player = Player()
113114

114-
spawn_chance = 1 / 100 # Extra: the percentage chance a cookie spawns every frame (starting at 1%)
115+
spawn_chance = 1 / 100
115116

116117
running = True
117118
while running:
@@ -120,35 +121,28 @@ def update(self):
120121
for event in pygame.event.get():
121122
if event.type == QUIT:
122123
running = False
123-
# We are using this type of key press detection because this only detects when the key is pressed down, instead of continuously
124-
if event.type == KEYDOWN: # If a key is pressed
125-
if event.key == K_SPACE: # If the key is space
126-
Bullet(player.rect.centerx, player.y) # Spawn a bullet at the correct position relative to the player
127-
128-
spawn_chance += 0.002 / 100 # Increase the spawn chance by 0.002% per frame
129-
if spawn_chance > 5 / 100: # If the spawn chance is greater than 5%
130-
spawn_chance = 5 / 100 # Cap it at 5% (if you want the game to be playable ;))
131-
if random() < spawn_chance: # If the random percentage generated is less than the spawn chance percentage
132-
# Spawn the cookie at roughly the top half of the screen
133-
# and also give it a randomized direction by passing in a random velocity
124+
125+
if event.type == KEYDOWN:
126+
if event.key == K_SPACE:
127+
Bullet(player.rect.centerx, player.y)
128+
129+
spawn_chance += 0.002 / 100
130+
if spawn_chance > 5 / 100:
131+
spawn_chance = 5 / 100
132+
if random() < spawn_chance:
134133
Cookie(randint(50, WIDTH - 50), randint(50, 100), randint(-5, 5), randint(-5, 5))
135134

136-
bullets.update() # Update all bullets
137-
cookies.update() # Update all cookies
138-
player.update() # Update the player
139-
# The "groupcollide" function detects collision between two sprite groups
140-
# This function takes two groups between which you want to test for collision
141-
# It also takes two booleans (True/False) that determines whether the collided sprites get deleted or not
142-
# The first and second boolean corresponds to the first and second group, respectively
143-
# It also takes an optional function, that pygame uses to modify the collision, we are not using that here
144-
# Go up the the player & cookie collision to see more about this optional function
135+
bullets.update()
136+
cookies.update()
137+
player.update()
138+
145139
pygame.sprite.groupcollide(bullets, cookies, True, True)
146140

147-
screen.blit(bg_img, (0, 0)) # Draw the background image
141+
screen.blit(bg_img, (0, 0))
148142

149-
bullets.draw(screen) # Draw all bullets
150-
cookies.draw(screen) # Draw all cookies
151-
player.draw(screen) # Draw the player
143+
bullets.draw(screen)
144+
cookies.draw(screen)
145+
player.draw(screen)
152146

153147
pygame.display.update()
154148

0 commit comments

Comments
 (0)