Simple Python Airplane Shooting Game Tutorial with Full Source Code
This article introduces a compact Python airplane shooting game, explains its main components such as player, enemies, bullets, and game loop, and provides complete, well‑commented source code so beginners can read, run, and extend the project.
Python is an easy language to learn, and after a quick start you can build many things such as web crawlers, data analysis, automation, machine learning, and even games. This article presents a fun 200‑line airplane shooting game that serves as a practical example for learning Python classes and modules.
The game consists of three main parts: the player aircraft, enemy aircraft, and the overall game logic. The player class handles image loading, movement, shooting, and collision detection, while the enemy class manages random spawning and simple downward motion.
# Player class
class Player(pygame.sprite.Sprite):
def __init__(self, plane_img, player_rect, init_pos):
pygame.sprite.Sprite.__init__(self)
self.image = [] # store player sprite images
for i in range(len(player_rect)):
self.image.append(plane_img.subsurface(player_rect[i]).convert_alpha())
self.rect = player_rect[0]
self.rect.topleft = init_pos
self.speed = 8
self.bullets = pygame.sprite.Group()
self.img_index = 0
self.is_hit = False
def shoot(self, bullet_img):
bullet = Bullet(bullet_img, self.rect.midtop)
self.bullets.add(bullet)
def moveUp(self):
if self.rect.top <= 0:
self.rect.top = 0
else:
self.rect.top -= self.speed
def moveDown(self):
if self.rect.top >= SCREEN_HEIGHT - self.rect.height:
self.rect.top = SCREEN_HEIGHT - self.rect.height
else:
self.rect.top += self.speed
def moveLeft(self):
if self.rect.left <= 0:
self.rect.left = 0
else:
self.rect.left -= self.speed
def moveRight(self):
if self.rect.left >= SCREEN_WIDTH - self.rect.width:
self.rect.left = SCREEN_WIDTH - self.rect.width
else:
self.rect.left += self.speedThe initialization part sets up the pygame environment, loads sounds, background images, and the sprite sheet for the aircraft:
# Initialize game
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('飞机大战')
# Load sounds
bullet_sound = pygame.mixer.Sound('resources/sound/bullet.wav')
enemy1_down_sound = pygame.mixer.Sound('resources/sound/enemy1_down.wav')
game_over_sound = pygame.mixer.Sound('resources/sound/game_over.wav')
bullet_sound.set_volume(0.3)
enemy1_down_sound.set_volume(0.3)
game_over_sound.set_volume(0.3)
pygame.mixer.music.load('resources/sound/game_music.wav')
pygame.mixer.music.play(-1, 0.0)
pygame.mixer.music.set_volume(0.25)
# Load background
background = pygame.image.load('resources/image/background.png').convert()
game_over = pygame.image.load('resources/image/gameover.png')
filename = 'resources/image/shoot.png'
plane_img = pygame.image.load(filename)The main game loop runs at 60 FPS, handles bullet firing, enemy spawning, movement, collision detection, drawing, and score calculation. The logic is kept simple so readers can follow each step:
while running:
clock.tick(60) # limit to 60 FPS
# Fire bullets
if not player.is_hit:
if shoot_frequency % 15 == 0:
bullet_sound.play()
player.shoot(bullet_img)
shoot_frequency = (shoot_frequency + 1) % 15
# Spawn enemies
if enemy_frequency % 50 == 0:
enemy1_pos = [random.randint(0, SCREEN_WIDTH - enemy1_rect.width), 0]
enemy1 = Enemy(enemy1_img, enemy1_down_imgs, enemy1_pos)
enemies1.add(enemy1)
enemy_frequency = (enemy_frequency + 1) % 100
# Update bullets
for bullet in player.bullets:
bullet.move()
if bullet.rect.bottom < 0:
player.bullets.remove(bullet)
# Update enemies and check collisions
for enemy in enemies1:
enemy.move()
if pygame.sprite.collide_circle(enemy, player):
enemies_down.add(enemy)
enemies1.remove(enemy)
player.is_hit = True
game_over_sound.play()
break
if enemy.rect.top > SCREEN_HEIGHT:
enemies1.remove(enemy)
# Collision between bullets and enemies
enemies1_down = pygame.sprite.groupcollide(enemies1, player.bullets, 1, 1)
for enemy_down in enemies1_down:
enemies_down.add(enemy_down)
# Draw everything
screen.fill(0)
screen.blit(background, (0, 0))
if not player.is_hit:
screen.blit(player.image[player.img_index], player.rect)
player.img_index = shoot_frequency // 8
else:
player.img_index = player_down_index // 8
screen.blit(player.image[player.img_index], player.rect)
player_down_index += 1
if player_down_index > 47:
running = False
for enemy_down in enemies_down:
if enemy_down.down_index == 0:
enemy1_down_sound.play()
if enemy_down.down_index > 7:
enemies_down.remove(enemy_down)
score += 1000
continue
screen.blit(enemy_down.down_imgs[enemy_down.down_index // 2], enemy_down.rect)
enemy_down.down_index += 1
player.bullets.draw(screen)
enemies1.draw(screen)The article concludes that the source code is short and clear, making it an excellent learning resource for beginners to understand Python OOP, pygame usage, and game development basics, and encourages readers to experiment by adding new features.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
