Aeroblasters: 2D Vertical Plane Shooter Game Using Python and Pygame With Source Code
Introduction :
Aeroblasters is an engaging 2D vertical plane shooter game developed usin Python and the Pygame library. Whether you’re playing on your PC or an Android device using Pydroid3, this game offers a thrilling experience where the player controls a plane, fighting off waves of enemy aircraft while avoiding their attacks and collecting essential power-ups. The objective is simple yet challenging: survive as long as possible while racking up points by destroying enemy planes. The game presents a perfect blend of strategic movement, precision shooting, and quick reflexes, ensuring players are kept on the edge of their seats.
In Aeroblasters, the player’s plane is constantly under attack by various enemy types, each with unique behavior and difficulty. To survive, the player must navigate through the barrage of enemy bullets, destroy enemy planes, and manage their fuel and health levels. The game mechanics are intuitive, making it easy for beginners to pick up, while the increasing difficulty levels provide a challenging experience for more seasoned players.
The player starts the game with 100 health and 100 fuel points. As the game progresses, these resources deplete, requiring the player to collect fuel power-ups scattered throughout the game. If the player’s health drops to zero or fuel drops below-10, the game ends. The game also features power-ups that allow the player to shoot multiple bullets simultaneously, increasing their chances of survival. The player’s score increases over time based on how long they survive and how many enemies they destroy, adding a competitive edge to the game.
What sets Aeroblasters apart from other 2D shooters is its balanced gameplay and engaging mechanics. The game’s background scrolls smoothly, creating a sense of motion, while the well-designed enemy planes and their varying attack patterns keep the gameplay fresh and exciting. The addition of explosions and other visual effects adds to the immersive experience, making every defeat of an enemy plane satisfying.
Whether you’re a fan of classic arcade shooters or just looking for a fun coding project, Aeroblasters offers both an entertaining gaming experience and a valuable learning opportunity for those interested in game development with Python.
Explanation :
Objective:
The primary goal in Aeroblasters is to pilot your plane through a hostile sky, taking down enemy aircraft, dodging their bullets, and collecting power-ups and fuel to stay alive. The longer you survive and the more enemies you destroy, the higher your score.
Controls:
MoveLeft: Left Arrow Key or Tap/Click on the left side of the screen.
MoveRight: Right Arrow Key or Tap/Click on the right side of the screen.
Shoot: Spacebar or Tap/Click directly on the plane.
Gameplay Mechanics:
Player:
- Movement: Players can manoeuvre their plane left or right within the boundaries of the screen
- Shooting: The plane can fire bullets to destroy incoming enemies.
- Health: Players start with 100 health points. Collisions with enemy planes or bullets reduce health, and the game ends when health reaches zero.
- Fuel: The plane also starts with 100 fuel points, which deplete over time. Players must collect fuel power-ups to replenish their supply, as the game ends if the fuel level drops below-10.
- Power-ups: Collecting power-ups enhances the plane’s abilities, such as allowing it to fire multiple bullets simultaneously for a limited period.
Enemies:
- Variety: The game features multiple types of enemy planes and helicopters, each with unique health and attack patterns.
- Shooting: Enemies fire bullets that the player must dodge. Being hit by enemy bullets decreases the player’s health.
- Health: Each enemy has a specific health value, and once it reaches zero, the enemy is destroyed.
Bullets:
- Player Bullets: These are the bullets fired by the player’s plane. Their effectiveness can be enhanced by collecting power-ups.
- EnemyBullets: These are fired by the enemies and pose a constant threat to the player.
- Explosions:When an enemy or the player’s plane is destroyed, an explosion animation occurs, adding a visual cue for the destruction.
Fuel and Power-ups:
- Fuel: Fuel icons periodically appear on the screen, and collecting them replenishes the player’s fuel supply.
- Power-ups: Power-ups grant temporary abilities, such as the ability to fire multiple bullets at once, which can help the player survive longer.
- Scoring: The player’s score increases over time, reflecting both the duration of survival and the number of enemies destroyed.
- Levels: As the player progresses, the game becomes more challenging, with more frequent and tougher enemy attacks.
- Core Classes and Methods:
Aeroblasters is built on a series of classes that define the game’s functionality.
Here’s a summary of some key classes:
Background: Manages the scrolling background to create the illusion of movement.
Methods: __init__, update, reset
Player: Controls the player’s plane, including movement, health, and shooting.
Methods: __init__, reset, update, draw
Enemy:Represents the various enemy planes, handling their movement, health, and attacks.
Methods: __init__, shoot, update, draw
Bullet: Represents bullets fired by both the player and enemies.
Methods: __init__, update, draw
Explosion: Manages the animation of explosions when planes are destroyed.
Methods: __init__, update, draw
Fuel: Handles the appearance and collection of fuel power-ups.
Methods: __init__, update, draw
Powerup: Manages the power-ups that enhance the player’s abilities.
Methods: __init__, update, draw
Button: Creates interactive buttons used in the game’s interface.
Methods: __init__, update_image, draw
Message: Displays text messages on the screen.
Methods: __init__, update
BlinkingText: Handles the display of blinking text messages.
Methods: __init__, update
Required Modules or Packages :-
git clone [repository_link]
To run Aeroblasters, you need to install the Pygame library, which is the backbone of the game’s graphical and audio components. Pygame is a set of Python modules designed for writing video games. It provides functionalities such as creating windows, drawing shapes, handling events, and more.
Here’s a breakdown of the essential module:
Pygame: This is the main library used to develop Aeroblasters. Pygame simplifies the process of game development by providing ready-made modules for handling graphics, sounds, and user input. In this game, Pygame handles everything from rendering the planes and bullets to detecting collisions and playing sounds.
To install Pygame, run the following command:
pip install pygame
If you’re running the game on an Android device using Pydroid3, Pygame is already installed, so you can skip this step.
How to Run the Code :
Running Aeroblasters is straightforward, whether you’re on a PC or using an Android device via Pydroid3.
Below are the steps for both platforms:
For Windows/Mac/Linux:
Clone the Repository: If the game’s source code is hosted on a repository, clone it using the
Navigate to the Project Directory: Change your current directory to the project’s directory
cd aeroblasters
Install Pygame: If you haven’t already, install the Pygame module
pip install pygame
Run the Game: Execute the main script to start the game:
python main.py
For Android (Using Pydroid3):
1. OpenPydroid3: Launch the Pydroid3 app on your Android device.
2. Load the Script: Open the main.py file in Pydroid3.
3. Runthe Game: Simply press the ‘Run’ button in Pydroid3 to start the game. No need to
install Pygame, as it is pre-installed in Pydroid3.
Code Explanation :
The game is built using several classes and methods that handle various aspects of the game.
Here’s an overview of some of the key components:
Background Class: This class manages the game’s background, ensuring it scrolls smoothly to create a dynamic environment.
class Background:
def __init__(self, win):
# Initializes the background with the window surface
self.win = win
# Load and set up the background images
# ...
def update(self, speed):
# Updates the background position based on the speed
# ...
def reset(self):
# Resets the background position when needed
# ...
Player Class: Manages the player’s plane, including movement, shooting, and health management
class Player:
def __init__(self, x, y):
# Initialize player attributes like position and health
self.x = x
self.y = y
self.health = 100
# Other player-specific setups
# ...
def update(self, moving_left, moving_right, explosion_group):
# Update the player's position and handle shooting
# ...
def draw(self, win):
# Draw the player on the screen
# ...
Enemy Class: This class is responsible for enemy planes, handling their movement, shooting,
and interactions with the player.
class Enemy:
def __init__(self, x, y, type_):
# Initialize enemy position and type-specific attributes
self.x = x
self.y = y
self.type = type_
# ...
def update(self, enemy_bullet_group, explosion_group):
# Handle enemy movement and shooting
# ...
def draw(self, win):
# Draw the enemy on the screen
# ...
Bullet Class: Represents the bullets fired by both the player and the enemies
class Bullet:
def __init__(self, x, y, type_, dx=None):
# Initialize bullet attributes like position and direction
self.x = x
self.y = y
self.type = type_
# ...
def update(self):
# Update the bullet's position based on its velocity
# ...
def draw(self, win):
# Draw the bullet on the screen
# ...
Explosion Class: Handles the animation of explosions when planes are destroyed
class Explosion:
def __init__(self, x, y, type_):
# Initialize explosion attributes
self.x = x
self.y = y
self.type = type_
# ...
def update(self):
# Update the explosion animation
# ...
def draw(self, win):
# Draw the explosion on the screen
# ...
These classes interact to create the game’s dynamic environment, where the player navigates, shoots, and survives against a backdrop of continuously spawning enemies and power-ups
Source Code :
main.py
import random
import pygame
from objects import Background, Player, Enemy, Bullet, Explosion, Fuel, Powerup, Button, Message, BlinkingText
pygame.init()
SCREEN = WIDTH, HEIGHT = 288, 512
info = pygame.display.Info()
width = info.current_w
height = info.current_h
if width >= height:
win = pygame.display.set_mode(SCREEN, pygame.NOFRAME)
else:
win = pygame.display.set_mode(SCREEN, pygame.NOFRAME | pygame.SCALED | pygame.FULLSCREEN)
clock = pygame.time.Clock()
FPS = 60
# COLORS **********************************************************************
WHITE = (255, 255, 255)
BLUE = (30, 144, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLACK = (0, 0, 20)
# IMAGES **********************************************************************
plane_img = pygame.image.load('Assets/plane.png')
logo_img = pygame.image.load('Assets/logo.png')
fighter_img = pygame.image.load('Assets/fighter.png')
clouds_img = pygame.image.load('Assets/clouds.png')
clouds_img = pygame.transform.scale(clouds_img, (WIDTH, 350))
home_img = pygame.image.load('Assets/Buttons/homeBtn.png')
replay_img = pygame.image.load('Assets/Buttons/replay.png')
sound_off_img = pygame.image.load("Assets/Buttons/soundOffBtn.png")
sound_on_img = pygame.image.load("Assets/Buttons/soundOnBtn.png")
# BUTTONS *********************************************************************
home_btn = Button(home_img, (24, 24), WIDTH // 4 - 18, HEIGHT // 2 + 120)
replay_btn = Button(replay_img, (36, 36), WIDTH // 2 - 18, HEIGHT // 2 + 115)
sound_btn = Button(sound_on_img, (24, 24), WIDTH - WIDTH // 4 - 18, HEIGHT // 2 + 120)
# FONTS ***********************************************************************
game_over_font = 'Fonts/ghostclan.ttf'
tap_to_play_font = 'Fonts/BubblegumSans-Regular.ttf'
score_font = 'Fonts/DalelandsUncialBold-82zA.ttf'
final_score_font = 'Fonts/DroneflyRegular-K78LA.ttf'
game_over_msg = Message(WIDTH // 2, 230, 30, 'Game Over', game_over_font, WHITE, win)
score_msg = Message(WIDTH - 50, 28, 30, '0', final_score_font, RED, win)
final_score_msg = Message(WIDTH // 2, 280, 30, '0', final_score_font, RED, win)
tap_to_play_msg = tap_to_play = BlinkingText(WIDTH // 2, HEIGHT - 60, 25, "Tap To Play", tap_to_play_font, WHITE, win)
# SOUNDS **********************************************************************
player_bullet_fx = pygame.mixer.Sound('Sounds/gunshot.wav')
click_fx = pygame.mixer.Sound('Sounds/click.mp3')
collision_fx = pygame.mixer.Sound('Sounds/mini_exp.mp3')
blast_fx = pygame.mixer.Sound('Sounds/blast.wav')
fuel_fx = pygame.mixer.Sound('Sounds/fuel.wav')
pygame.mixer.music.load('Sounds/Defrini - Spookie.mp3')
pygame.mixer.music.play(loops=-1)
pygame.mixer.music.set_volume(0.1)
# GROUPS & OBJECTS ************************************************************
bg = Background(win)
p = Player(144, HEIGHT - 100)
enemy_group = pygame.sprite.Group()
player_bullet_group = pygame.sprite.Group()
enemy_bullet_group = pygame.sprite.Group()
explosion_group = pygame.sprite.Group()
fuel_group = pygame.sprite.Group()
powerup_group = pygame.sprite.Group()
# FUNCTIONS *******************************************************************
def shoot_bullet():
x, y = p.rect.center[0], p.rect.y
if p.powerup > 0:
for dx in range(-3, 4):
b = Bullet(x, y, 4, dx)
player_bullet_group.add(b)
p.powerup -= 1
else:
b = Bullet(x - 30, y, 6)
player_bullet_group.add(b)
b = Bullet(x + 30, y, 6)
player_bullet_group.add(b)
player_bullet_fx.play()
def reset():
enemy_group.empty()
player_bullet_group.empty()
enemy_bullet_group.empty()
explosion_group.empty()
fuel_group.empty()
powerup_group.empty()
p.reset(p.x, p.y)
# VARIABLES *******************************************************************
level = 1
plane_destroy_count = 0
plane_frequency = 5000
start_time = pygame.time.get_ticks()
moving_left = False
moving_right = False
home_page = True
game_page = False
score_page = False
score = 0
sound_on = True
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE or event.key == pygame.K_q:
running = False
if event.type == pygame.KEYDOWN and game_page:
if event.key == pygame.K_LEFT:
moving_left = True
if event.key == pygame.K_RIGHT:
moving_right = True
if event.key == pygame.K_SPACE:
shoot_bullet()
if event.type == pygame.MOUSEBUTTONDOWN:
if home_page:
home_page = False
game_page = True
click_fx.play()
elif game_page:
x, y = event.pos
if p.rect.collidepoint((x, y)):
shoot_bullet()
elif x WIDTH // 2:
moving_right = True
if event.type == pygame.KEYUP:
moving_left = False
moving_right = False
if event.type == pygame.MOUSEBUTTONUP:
moving_left = False
moving_right = False
if home_page:
win.fill(BLACK)
win.blit(logo_img, (30, 80))
win.blit(fighter_img, (WIDTH // 2 - 50, HEIGHT // 2))
pygame.draw.circle(win, WHITE, (WIDTH // 2, HEIGHT // 2 + 50), 50, 4)
tap_to_play_msg.update()
if score_page:
win.fill(BLACK)
win.blit(logo_img, (30, 50))
game_over_msg.update()
final_score_msg.update(score)
if home_btn.draw(win):
home_page = True
game_page = False
score_page = False
reset()
click_fx.play()
plane_destroy_count = 0
level = 1
score = 0
if replay_btn.draw(win):
score_page = False
game_page = True
reset()
click_fx.play()
plane_destroy_count = 0
score = 0
if sound_btn.draw(win):
sound_on = not sound_on
if sound_on:
sound_btn.update_image(sound_on_img)
pygame.mixer.music.play(loops=-1)
else:
sound_btn.update_image(sound_off_img)
pygame.mixer.music.stop()
if game_page:
current_time = pygame.time.get_ticks()
delta_time = current_time - start_time
if delta_time >= plane_frequency:
if level == 1:
type = 1
elif level == 2:
type = 2
elif level == 3:
type = 3
elif level == 4:
type = random.randint(4, 5)
elif level == 5:
type = random.randint(1, 5)
x = random.randint(10, WIDTH - 100)
e = Enemy(x, -150, type)
enemy_group.add(e)
start_time = current_time
if plane_destroy_count:
if plane_destroy_count % 5 == 0 and level < 5:
level += 1
plane_destroy_count = 0
p.fuel -= 0.05
bg.update(1)
win.blit(clouds_img, (0, 70))
p.update(moving_left, moving_right, explosion_group)
p.draw(win)
player_bullet_group.update()
player_bullet_group.draw(win)
enemy_bullet_group.update()
enemy_bullet_group.draw(win)
explosion_group.update()
explosion_group.draw(win)
fuel_group.update()
fuel_group.draw(win)
powerup_group.update()
powerup_group.draw(win)
enemy_group.update(enemy_bullet_group, explosion_group)
enemy_group.draw(win)
if p.alive:
player_hit = pygame.sprite.spritecollide(p, enemy_bullet_group, False)
for bullet in player_hit:
p.health -= bullet.damage
x, y = bullet.rect.center
explosion = Explosion(x, y, 1)
explosion_group.add(explosion)
bullet.kill()
collision_fx.play()
for bullet in player_bullet_group:
planes_hit = pygame.sprite.spritecollide(bullet, enemy_group, False)
for plane in planes_hit:
plane.health -= bullet.damage
if plane.health = 0.3:
fuel = Fuel(x, y)
fuel_group.add(fuel)
plane_destroy_count += 1
blast_fx.play()
x, y = bullet.rect.center
explosion = Explosion(x, y, 1)
explosion_group.add(explosion)
bullet.kill()
collision_fx.play()
player_collide = pygame.sprite.spritecollide(p, enemy_group, True)
if player_collide:
x, y = p.rect.center
explosion = Explosion(x, y, 2)
explosion_group.add(explosion)
x, y = player_collide[0].rect.center
explosion = Explosion(x, y, 2)
explosion_group.add(explosion)
p.health = 0
p.alive = False
if pygame.sprite.spritecollide(p, fuel_group, True):
p.fuel += 25
if p.fuel >= 100:
p.fuel = 100
fuel_fx.play()
if pygame.sprite.spritecollide(p, powerup_group, True):
p.powerup += 2
fuel_fx.play()
if not p.alive or p.fuel <= -10:
if len(explosion_group) == 0:
game_page = False
score_page = True
reset()
score += 1
score_msg.update(score)
fuel_color = RED if p.fuel <= 40 else GREEN
pygame.draw.rect(win, fuel_color, (30, 20, p.fuel, 10), border_radius=4)
pygame.draw.rect(win, WHITE, (30, 20, 100, 10), 2, border_radius=4)
pygame.draw.rect(win, BLUE, (30, 32, p.health, 10), border_radius=4)
pygame.draw.rect(win, WHITE, (30, 32, 100, 10), 2, border_radius=4)
win.blit(plane_img, (10, 15))
pygame.draw.rect(win, WHITE, (0, 0, WIDTH, HEIGHT), 5, border_radius=4)
clock.tick(FPS)
pygame.display.update()
pygame.quit()
Objects.py
import pygame
SCREEN = WIDTH, HEIGHT = 288, 512
pygame.mixer.init()
class Background:
def __init__(self, win):
self.win = win
self.image = pygame.image.load('Assets/bg.png')
self.image = pygame.transform.scale(self.image, (WIDTH, HEIGHT))
self.rect = self.image.get_rect()
self.reset()
self.move = True
def update(self, speed):
if self.move:
self.y1 += speed
self.y2 += speed
if self.y1 >= HEIGHT:
self.y1 = -HEIGHT
if self.y2 >= HEIGHT:
self.y2 = -HEIGHT
self.win.blit(self.image, (self.x, self.y1))
self.win.blit(self.image, (self.x, self.y2))
def reset(self):
self.x = 0
self.y1 = 0
self.y2 = -HEIGHT
class Player:
def __init__(self, x, y):
self.image_list = []
for i in range(2):
img = pygame.image.load(f'Assets/player{i+1}.png')
img = pygame.transform.scale(img, (100, 86))
self.image_list.append(img)
self.x, self.y = x, y
self.reset(self.x, self.y)
def reset(self, x, y):
self.index = 0
self.image = self.image_list[self.index]
self.rect = self.image.get_rect(center=(x, y))
self.counter = 0
self.speed = 3
self.health = 100
self.fuel = 100
self.powerup = 0
self.alive = True
self.width = self.image.get_width()
def update(self, moving_left, moving_right, explosion_group):
if self.alive:
if moving_left and self.rect.x > 2:
self.rect.x -= self.speed
if moving_right and self.rect.x = HEIGHT:
self.kill()
if self.health == 60:
self.shoot(enemy_bullet_group)
self.bullet_counter = 0
self.counter += 1
if self.counter >= self.frame_fps:
self.index = (self.index + 1) % len(self.image_list)
self.image = self.image_list[self.index]
self.counter = 0
def draw(self, win):
win.blit(self.image, self.rect)
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y, type_, dx=None):
super(Bullet, self).__init__()
self.dx = dx
powerup_bullet = False
if self.dx in range(-3, 4):
powerup_bullet = True
if type_ == 1:
self.image = pygame.image.load('Assets/Bullets/1.png')
self.image = pygame.transform.scale(self.image, (20, 40))
if type_ == 2:
self.image = pygame.image.load('Assets/Bullets/2.png')
self.image = pygame.transform.scale(self.image, (15, 30))
if type_ == 3:
self.image = pygame.image.load('Assets/Bullets/3.png')
self.image = pygame.transform.scale(self.image, (20, 40))
if type_ in (4, 5):
self.image = pygame.image.load('Assets/Bullets/4.png')
self.image = pygame.transform.scale(self.image, (20, 20))
if type_ == 6:
self.image = pygame.image.load('Assets/Bullets/red_fire.png')
self.image = pygame.transform.scale(self.image, (15, 30))
self.rect = self.image.get_rect(center=(x, y))
if type_ == 6 or powerup_bullet:
self.speed = -3
else:
self.speed = 3
if self.dx is None:
self.dx = 0
self.damage_dict = {1: 5, 2: 10, 3: 15, 4: 25, 5: 25, 6: 20}
self.damage = self.damage_dict[type_]
if powerup_bullet:
self.damage = 25
def update(self):
self.rect.x += self.dx
self.rect.y += self.speed
if self.rect.bottom >= HEIGHT:
self.kill()
def draw(self, win):
win.blit(self.image, self.rect)
class Explosion(pygame.sprite.Sprite):
def __init__(self, x, y, type_):
super(Explosion, self).__init__()
self.img_list = []
if type_ == 1:
self.length = 3
elif type_ == 2:
self.length = 8
for i in range(self.length):
img = pygame.image.load(f'Assets/Explosion{type_}/{i+1}.png')
w, h = img.get_size()
width = int(w * 0.40)
height = int(w * 0.40)
img = pygame.transform.scale(img, (width, height))
self.img_list.append(img)
self.index = 0
self.image = self.img_list[self.index]
self.rect = self.image.get_rect(center=(x, y))
self.counter = 0
def update(self):
self.counter += 1
if self.counter >= 7:
self.index += 1
if self.index >= self.length:
self.kill()
else:
self.image = self.img_list[self.index]
self.counter = 0
def draw(self, win):
win.blit(self.image, self.rect)
class Fuel(pygame.sprite.Sprite):
def __init__(self, x, y):
super(Fuel, self).__init__()
self.image = pygame.image.load('Assets/fuel.png')
self.rect = self.image.get_rect(center=(x, y))
def update(self):
self.rect.y += 1
if self.rect.top >= HEIGHT:
self.kill()
def draw(self, win):
win.blit(self.image, self.rect)
class Powerup(pygame.sprite.Sprite):
def __init__(self, x, y):
super(Powerup, self).__init__()
self.image = pygame.image.load('Assets/powerup.png')
self.rect = self.image.get_rect(center=(x, y))
def update(self):
Output :
Find More Projects
Build a Quiz Game Using HTML CSS and JavaScript Introduction Hello coders, you might have played various games, but were you aware …
Emoji Catcher Game Using HTML CSS and JavaScript Introduction Hello Coders, Welcome to another new blog. In this article we’ve made a …
Typing Challenge Using HTML CSS and JavaScript Introduction Hello friends, all you developer friends are welcome to our new project. If you …
Breakout Game Using HTML CSS and JavaScript With Source Code Introduction Hello friends, welcome to today’s new blog post. All of you …
Digital and Analog Clock using HTML CSS and JavaScript Introduction : This project is a digital clock and stopwatch system, which allows …
Coffee Shop Website using HTML, CSS & JavaScript Introduction : This project is a website for coffee house business. It uses HTML …