对于Python初学者来说,最容易陷入“学完语法却不知道能做什么”的困境。想要真正掌握编程,最好的方式就是动手做项目。而雷霆战机作为一代人的经典回忆,不仅逻辑清晰、趣味性强,还能完美覆盖Python图形界面、面向对象、键盘监听、碰撞检测等核心知识点。
本文将从零开始,使用Python自带的 pygame 库,一步步实现一款完整的雷霆战机小游戏。全文包含环境搭建、项目结构、代码逐行解析、运行效果,全程通俗易懂,适合零基础小白跟着敲,也可直接复制代码运行。
一、项目准备
1.1 开发环境
- Python 3.x
- 游戏库: pygame
1.2 安装依赖
打开命令行,执行安装命令:
bash
pip install pygame
1.3 游戏功能规划
本次实现的核心功能:
1. 玩家战机控制(上下左右移动)
2. 敌机自动生成与移动
3. 战机发射子弹
4. 子弹击中敌机判定(碰撞检测)
5. 计分系统
6. 游戏结束判定
7. 背景滚动效果
二、完整项目代码
python
import pygame
import random
import sys
# 初始化pygame
pygame.init()
# 游戏窗口设置
SCREEN_WIDTH = 480
SCREEN_HEIGHT = 700
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("雷霆战机")
# 帧率控制
clock = pygame.time.Clock()
FPS = 60
# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
# 玩家战机类
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((50, 50))
self.image.fill(BLUE)
self.rect = self.image.get_rect()
self.rect.centerx = SCREEN_WIDTH // 2
self.rect.bottom = SCREEN_HEIGHT - 10
self.speed = 8
self.shield = 100
def update(self):
# 键盘控制移动
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and self.rect.left > 0:
self.rect.x -= self.speed
if keys[pygame.K_RIGHT] and self.rect.right < SCREEN_WIDTH:
self.rect.x += self.speed
if keys[pygame.K_UP] and self.rect.top > 0:
self.rect.y -= self.speed
if keys[pygame.K_DOWN] and self.rect.bottom < SCREEN_HEIGHT:
self.rect.y += self.speed
def shoot(self, all_sprites, bullets):
bullet = Bullet(self.rect.centerx, self.rect.top)
all_sprites.add(bullet)
bullets.add(bullet)
# 敌机类
class Enemy(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((40, 40))
self.image.fill(RED)
self.rect = self.image.get_rect()
self.rect.x = random.randint(0, SCREEN_WIDTH - self.rect.width)
self.rect.y = random.randint(-100, -40)
self.speed = random.randint(3, 6)
def update(self):
self.rect.y += self.speed
# 敌机飞出屏幕后重置位置
if self.rect.top > SCREEN_HEIGHT:
self.rect.x = random.randint(0, SCREEN_WIDTH - self.rect.width)
self.rect.y = random.randint(-100, -40)
self.speed = random.randint(3, 6)
# 子弹类
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((5, 15))
self.image.fill(WHITE)
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.bottom = y
self.speed = 10
def update(self):
self.rect.y -= self.speed
# 子弹飞出屏幕后删除
if self.rect.bottom < 0:
self.kill()
# 爆炸效果类(简化版)
class Explosion(pygame.sprite.Sprite):
def __init__(self, center):
super().__init__()
self.image = pygame.Surface((30, 30))
self.image.fill(WHITE)
self.rect = self.image.get_rect(center=center)
self.life_time = 10
self.counter = 0
def update(self):
self.counter += 1
if self.counter >= self.life_time:
self.kill()
# 显示分数
def draw_text(surf, text, size, x, y):
font = pygame.font.Font(None, size)
text_surface = font.render(text, True, WHITE)
text_rect = text_surface.get_rect()
text_rect.midtop = (x, y)
surf.blit(text_surface, text_rect)
# 主游戏函数
def main():
# 创建精灵组
all_sprites = pygame.sprite.Group()
enemies = pygame.sprite.Group()
bullets = pygame.sprite.Group()
# 创建玩家
player = Player()
all_sprites.add(player)
# 生成敌机
for i in range(8):
enemy = Enemy()
all_sprites.add(enemy)
enemies.add(enemy)
score = 0
running = True
game_over = False
# 背景滚动
bg_y = 0
bg = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
bg.fill(BLACK)
while running:
clock.tick(FPS)
# 事件处理
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
player.shoot(all_sprites, bullets)
if event.key == pygame.K_ESCAPE:
running = False
if not game_over:
# 更新精灵
all_sprites.update()
# 子弹击中敌机
hits = pygame.sprite.groupcollide(enemies, bullets, True, True)
for hit in hits:
score += 10
expl = Explosion(hit.rect.center)
all_sprites.add(expl)
enemy = Enemy()
all_sprites.add(enemy)
enemies.add(enemy)
# 敌机撞击玩家
hits = pygame.sprite.spritecollide(player, enemies, True)
if hits:
game_over = True
# 背景滚动
bg_y += 2
if bg_y >= SCREEN_HEIGHT:
bg_y = 0
screen.blit(bg, (0, bg_y))
screen.blit(bg, (0, bg_y - SCREEN_HEIGHT))
# 绘制所有元素
all_sprites.draw(screen)
draw_text(screen, f"Score: {score}", 30, SCREEN_WIDTH // 2, 10)
if game_over:
draw_text(screen, "GAME OVER", 64, SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 - 50)
draw_text(screen, "Press ESC to exit", 30, SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 20)
pygame.display.flip()
pygame.quit()
sys.exit()
if __name__ == "__main__":
main()
三、逐模块深度解析
3.1 库导入与初始化
python
import pygame
import random
import sys
- pygame :游戏核心库,负责窗口、图形、键盘、碰撞等
- random :随机生成敌机位置与速度
- sys :用于安全退出程序
python
pygame.init()
初始化 pygame 所有模块,必须放在最前面。
3.2 游戏窗口与基础设置
python
SCREEN_WIDTH = 480
SCREEN_HEIGHT = 700
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("雷霆战机")
设置窗口大小与标题,符合竖版战机游戏比例。
python
clock = pygame.time.Clock()
FPS = 60
控制游戏帧率,保证所有设备运行速度一致。
3.3 玩家战机类(Player)
这是游戏核心角色,负责移动、射击。
1. __init__ :初始化战机大小、颜色、出生位置、速度
2. update() :监听键盘方向键,实现上下左右移动
3. shoot() :创建子弹并加入精灵组
移动边界限制:
python
if keys[pygame.K_LEFT] and self.rect.left > 0:
self.rect.x -= self.speed
防止战机飞出屏幕。
3.4 敌机类(Enemy)
敌机自动从顶部出现,向下移动,飞出屏幕后重置。
- 随机X轴出生位置
- 随机速度,增加游戏难度
- 超出屏幕底部自动“复活”在顶部
3.5 子弹类(Bullet)
由玩家发射,向上飞行,超出屏幕自动销毁。
- 从玩家机头位置生成
- 垂直向上移动
- 离开屏幕后调用 kill() 删除,节省内存
3.6 碰撞检测(核心逻辑)
pygame.sprite 提供了高效碰撞检测:
1. 子弹打敌机
python
hits = pygame.sprite.groupcollide(enemies, bullets, True, True)
- 两个组碰撞后,敌机和子弹同时消失
- 每击中一次加分,并生成新敌机
2. 敌机撞玩家
python
hits = pygame.sprite.spritecollide(player, enemies, True)
一旦碰撞,触发 game_over 。
3.7 背景滚动
python
bg_y += 2
if bg_y >= SCREEN_HEIGHT:
bg_y = 0
通过背景图Y轴不断偏移并循环,实现飞行前前进视觉效果。
3.8 计分与游戏结束
- 击中敌机+10分
- 游戏结束后显示“GAME OVER”
- 按ESC退出游戏
四、游戏运行说明
1. 将代码复制到 .py 文件
2. 确保已安装 pygame
3. 运行程序
4. 操作方式:
- 方向键:控制战机移动
- 空格:发射子弹
- ESC:退出游戏
五、项目扩展方向(进阶优化)
1. 替换图片素材:将纯色方块换成战机、敌机、背景图
2. 添加音效:射击声、爆炸声、背景音乐
3. 增加BOSS战机
4. 实现技能道具(护盾、双倍子弹)
5. 加入生命系统,而非一碰就死
6. 难度随分数递增(敌机变多、速度变快)
7. 添加开始界面、暂停功能
六、总结
通过这个雷霆战机项目,你已经掌握了:
- pygame窗口与精灵系统使用
- 面向对象编程思想
- 键盘事件监听
- 碰撞检测逻辑
- 游戏循环与帧率控制
- 计分与游戏状态管理