一.概览
本文通过一个经典的太空射击类游戏案例,系统梳理 Pygame 游戏开发的核心技术点。本项目通过分模块设计实现了飞船移动、子弹发射、屏幕渲染等基础功能,适合 Pygame 入门学习参考。
二.代码实例
项目采用清晰的分层架构,共包含4个核心模块:
project/
├── alien_invasion.py # 游戏主程序入口
├── settings.py # 游戏配置管理器
├── ship.py # 飞船行为控制类
└── bullet.py # 子弹实体类
alien_invasion.py
import sys
import pygame
from settings import Settings
from ship import Ship
from bullet import Bullet
class AlienInvasion:
def __init__(self):
# 初始化游戏并创建游戏资源
pygame.init()
self.settings = Settings()
self.clock = pygame.time.Clock()
self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
self.settings.screen_width = self.screen.get_rect().width
self.settings.screen_height = self.settings.screen_height = self.screen.get_rect().height
self.bg_color = self.settings.bg_color
pygame.display.set_caption("Alien Invasion")
self.ship = Ship(self)
self.bullets = pygame.sprite.Group()
def run_game(self):
# 开始游戏的主循环
while True:
# 监听键盘和鼠标事件 辅助方法
self._check_events()
#更新
self.ship.update()
self.bullets.update()
self._update_bullets()
self._update_screen()
self.clock.tick(60)
def _check_events(self):
# 响应鼠标和键盘事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
self._check_keydown_events(event)
elif event.type == pygame.KEYUP:
self._check_keyup_events(event)
# 键盘按下
def _check_keydown_events(self,event):
if event.key == pygame.K_RIGHT:
# 向右移动飞船
self.ship.moving_right = True
elif event.key == pygame.K_LEFT:
# 向左移动飞船
self.ship.moving_left = True
elif event.key == pygame.K_ESCAPE:
# 退出
pygame.quit()
sys.exit()
elif event.key == pygame.K_SPACE:
# 发射子弹
self._fire_bullet()
# 键盘松开
def _check_keyup_events(self,event):
if event.key == pygame.K_RIGHT:
self.ship.moving_right = False
elif event.key == pygame.K_LEFT:
self.ship.moving_left = False
def _fire_bullet(self):
# 创建一颗子弹,并将其加入编组bullets
if len(self.bullets) < self.settings.bullets_allowed:
new_bullet = Bullet(self)
self.bullets.add(new_bullet)
# 更新屏幕上的图像,并切换到新屏幕
def _update_screen(self):
self.screen.fill(self.settings.bg_color)
for bullet in self.bullets.sprites():
bullet.draw_bullet()
self.ship.blitme()
pygame.display.flip()
# 更新子弹位置
def _update_bullets(self):
# 更新子弹的位置
self.bullets.update()
# 删除已消失的子弹
for bullet in self.bullets.copy():
if bullet.rect.bottom <= 0:
self.bullets.remove(bullet)
if __name__ == "__main__":
# 创建游戏实例并运行游戏
ai = AlienInvasion()
ai.run_game()
settings.py
class Settings:
def __init__(self):
# 屏幕设置
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (230, 230, 230)
# 飞船设置
self.ship_speed = 1.5
# 子弹设置
self.bullet_speed = 2.0
self.bullet_width = 3
self.bullet_height = 15
self.bullet_color = (100, 150, 240)
self.bullets_allowed = 10
**```
ship.py**
```javascript
import pygame
from pygame.sprite import Sprite
from pathlib import Path
current_dir = Path(__file__).resolve().parent
target_folder = str(current_dir / "images" / "ship.png") # 添加str()转换为字符串
class Ship:
# """管理飞船的类"""
def __init__(self, ai_game):
# """初始化飞船并设置其初始位置"""
self.screen = ai_game.screen
self.screen_rect = ai_game.screen.get_rect()
self.settings = ai_game.settings
# 加载飞船图像并获取其外接矩形
self.image = pygame.image.load(target_folder)
# 调整图片大小
self.image = pygame.transform.scale(self.image, (70, 100))
self.rect = self.image.get_rect()
# 每艘新飞船都放在屏幕底部的中央
self.rect.midbottom = self.screen_rect.midbottom
# 存储飞船属性x
self.x = float(self.rect.x)
# 移动标志(飞船一开始不移动)
self.moving_right = False
self.moving_left = False
def update(self) :
# 根据移动标志调整飞船的位置
if self.moving_right and self.rect.right < self.screen_rect.right:
self.x += self.settings.ship_speed
if self.moving_left and self.rect.left > 0:
self.x -= self.settings.ship_speed
self.rect.x = self.x
def blitme(self):
# """在指定位置绘制飞船"""
self.screen.blit(self.image, self.rect)
bullet.py
import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
# """管理飞船所发射子弹的类"""
def __init__(self, ai_game):
# """在飞船的当前位置创建一个子弹对象"""
super().__init__()
self.screen = ai_game.screen
self.settings = ai_game.settings
self.color = self.settings.bullet_color
# 在(0,0)处创建一个表示子弹的矩形,再设置正确的位置
self.rect = pygame.Rect(0, 0, self.settings.bullet_width,
self.settings.bullet_height)
self.rect.midtop = ai_game.ship.rect.midtop
# 存储用浮点数表示的子弹位置
self.y = float(self.rect.y)
def update(self):
# """向上移动子弹"""
# 更新子弹的准确位置
self.y -= self.settings.bullet_speed
# 更新表示子弹的 rect 的位置
self.rect.y = self.y
def draw_bullet(self):
pygame.draw.rect(self.screen, self.color, self.rect)
主程序(alien_invasion.py)
承担以下核心工作:
class AlienInvasion:
def __init__(self):
# 1. 初始化Pygame并设置游戏环境(屏幕、配置)
# 2. 初始化核心对象(飞船、子弹组)
def run_game(self):
while True:
# 主循环执行三大任务:事件监听->状态更新->画面渲染
self._check_events() # 事件处理
self._update_objects() # 更新对象
self._update_screen() # 渲染画面
三.核心功能实现要点
1. 飞船运动控制(Ship 类)
# 移动控制逻辑
def update(self):
if self.moving_right and self.rect.right < screen_rect.right:
self.x += self.settings.ship_speed
if self.moving_left and self.rect.left > 0:
self.x -= self.settings.ship_speed
self.rect.x = self.x
关键设计:
移动标志模式:通过moving_right/left布尔值记录方向
边界检测:确保飞船不超出屏幕左右边缘
2. 子弹发射系统(Bullet 类)
# 子弹创建
def _fire_bullet(self):
if len(self.bullets) < self.settings.bullets_allowed:
new_bullet = Bullet(ai_game=self)
self.bullets.add(new_bullet)
核心机制:
使用pygame.sprite.Group管理子弹对象
速度控制:通过self.y = float(self.rect.y)实现精确位移
子弹生命周期管理:在_update_bullets()中检查删除超出屏幕范围的子弹
3. 游戏循环与事件监听
def _check_events(self):
for event in pygame.event.get():
# 响应3种事件类型:
if event.type == pygame.QUIT : 处理退出
if event.type == pygame.KEYDOWN : 处理按键按下
if event.type == pygame.KEYUP : 处理按键释放
四.代码实现关键点
1. 配置管理(settings.py)
class Settings:
def __init__(self):
self.screen_width = 1200 # 屏幕尺寸
self.bg_color = (230,230,230) # 背景颜色
self.ship_speed = 1.5 # 飞船移动速度
self.bullet_speed = uz 2.0 # 子弹速度
self.bullets_allowed = 3 # 子弹数量限制
优点:
参数集中管理,方便后续调整
符号常量命名清晰规范
2. 对象管理的面向对象设计
Ship、Bullet均为pygame.sprite.Sprite的子类使用组(Group)管理同类对象
self.bullets = pygame.sprite.Group()
五.总结
- 模块化设计:清晰分离输入处理、物理模拟、画面渲染职责
- OO结构:通过继承实现Pygame精灵系统整合
- 配置隔离:避免游戏逻辑中硬编码参数
完整流程示意图
graph LR
A[用户输入] --> B(事件监听)
B --> C{按键处理}
C -->|移动键| D[飞船位置更新]
C -->|空格键| E[创建子弹对象]
D --> G[状态同步]
E --> G[状态同步]
G --> F[执行渲染]