Shooter
Shooter
# Background music
mixer.init()
mixer.music.load('space.ogg')
mixer.music.play()
fire_sound = mixer.Sound('fire.ogg')
# Every sprite must have the rect property that represents the rectangle it is
fitted in
self.rect = self.image.get_rect()
self.rect.x = player_x
self.rect.y = player_y
# Create sprites
ship = Player(img_hero, 5, win_height - 100, 80, 100, 10)
bullets = sprite.Group()
#The "game is over" variable: as soon as True is there, sprites stop working in the
main loop
finish = False
# The game itself: actions of sprites, checking the rules of the game, redrawing
if not finish:
# Update the background
window.blit(background, (0, 0))
#Check for a collision between a bullet and monsters (both monster and bullet
disappear upon a touch)
collides = sprite.groupcollide(monsters, bullets, True, True)
for c in collides:
# This loop will repeat as many times as the number of monsters hit
score = score + 1
monster = Enemy(img_enemy, randint(80, win_width - 80), -40, 80, 50,
randint(1, 5))
monsters.add(monster)
# Possible lose: missed too many monsters or the character collided with an
enemy
if sprite.spritecollide(ship, monsters, False) or lost >= max_lost:
finish = True # Lose, set the background and no longer control the
sprites.
window.blit(lose, (200, 200))
display.update()
time.delay(3000)
for i in range(1, 6):
monster = Enemy(img_enemy, randint(80, win_width - 80), -40, 80, 50,
randint(1, 5))
monsters.add(monster)
time.delay(50)
Steps to take:
1. Initialize Pygame and Load Resources:
Use pygame.init() to initialize Pygame.
Load font resources using font.init() and font.Font.
Load background music and sound effects using mixer.init() and mixer.Sound.
Load images using pygame.image.load().
2. Define Game Variables:
Define variables for the images and sounds required for the game.
Initialize variables for the game state such as score, goal, and maximum allowed
misses.
3. Define Sprite Classes:
Create a parent class GameSprite that inherits from pygame.sprite.Sprite.
Define initialization method (__init__) in GameSprite to set image, position, and
speed.
Implement reset method in GameSprite to draw the sprite on the window.
Create subclasses Player, Enemy, and Bullet inheriting from GameSprite.
Implement update method in each subclass to handle sprite movements.
4. Create Sprites:
Create instances of player, enemy, and bullet sprites.
Add enemies to a sprite group.
5. Game Loop:
Set up the main game loop (while run:).
Handle events such as quitting the game and firing bullets.
Update sprite movements and check for collisions within the loop.
Draw the background, sprites, and text on the screen.
Manage game over conditions (win or lose).
Provide an option for automatic restart of the game after a delay.
6. Display and Update:
Update the display using pygame.display.update() or pygame.display.flip().
Limit the frame rate using clock.tick() to control the speed of the game.
7. Cleanup and Exit:
Handle cleanup tasks such as quitting Pygame and releasing resources.
Use pygame.quit() to properly exit the game.
class Enemy(GameSprite):
# Enemy movement
def update(self):
# Update vertical position of the enemy sprite
self.rect.y += self.speed
# Check if the enemy sprite has reached beyond the bottom of the screen
if self.rect.y > win_height:
# If so, reposition the enemy sprite at a random position near the top of the screen
self.rect.x = randint(80, win_width - 80)
self.rect.y = 0
Explanation:
1. self.rect.y += self.speed: This line updates the vertical position of the enemy sprite by adding its speed. It makes
the enemy sprite move downwards on the screen.
2. global lost: This line declares that the variable lost is global, allowing it to be accessed and modified within this
method and throughout the entire script. In this case, lost is used to count how many enemies have been
missed.
3. if self.rect.y > win_height: This condition checks if the vertical position of the enemy sprite is beyond the height
of the screen. If it is, it means the enemy sprite has disappeared off the bottom of the screen.
4. self.rect.x = randint(80, win_width - 80): If the enemy sprite has gone off the screen, this line repositions it at a
random horizontal position near the top of the screen, leaving some space from the edges.
5. self.rect.y = 0: After repositioning the enemy sprite horizontally, this line sets its vertical position to 0, effectively
placing it at the top of the screen again.
6. lost = lost + 1: Finally, this line increments the count of missed enemies by 1, updating the global variable lost.
# Loop to create multiple instances of Enemy sprites and add them to the 'monsters' group
for i in range(1, 6):
# Create a new instance of the Enemy sprite with random initial position and speed
# The arguments for Enemy are: (player_image, player_x, player_y, size_x, size_y, player_speed)
monster = Enemy(img_enemy, randint(80, win_width - 80), -40, 80, 50, randint(1, 5))
Explanation:
1. monsters = sprite.Group(): This line creates a group of sprites specifically for enemy sprites. This group will allow
us to easily manage and update all the enemy sprites together.
2. for i in range(1, 6):: This loop iterates 5 times, creating 5 instances of the enemy sprite. Each iteration of the loop
creates a new enemy sprite with random initial position and speed.
3. monster = Enemy(...): Inside the loop, a new instance of the Enemy sprite is created using the provided image
(img_enemy), a random initial horizontal position (between 80 pixels and the width of the screen minus 80
pixels), an initial vertical position of -40 pixels (above the screen), a size of 80x50 pixels, and a random speed
between 1 and 5 pixels per frame.
4. monsters.add(monster): After creating each enemy sprite, it is added to the monsters group using the add()
method. This ensures that all enemy sprites are part of the same group, making it convenient to update and
manage them collectively during the game loop.