Pygame模块化实战:从零构建Aliens射击游戏全流程(一)

一.概览

本文通过一个经典的太空射击类游戏案例,系统梳理 Pygame 游戏开发的核心技术点。本项目通过分模块设计实现了飞船移动、子弹发射、屏幕渲染等基础功能,适合 Pygame 入门学习参考。

二.代码实例

项目采用清晰的分层架构,共包含4个核心模块:

project/

├── alien_invasion.py # 游戏主程序入口

├── settings.py # 游戏配置管理器

├── ship.py # 飞船行为控制类

└── bullet.py # 子弹实体类

alien_invasion.py

javascript 复制代码
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

javascript 复制代码
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

javascript 复制代码
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)

承担以下核心工作:

javascript 复制代码
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 类)

javascript 复制代码
# 移动控制逻辑
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 类)

javascript 复制代码
# 子弹创建
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. 游戏循环与事件监听

javascript 复制代码
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

javascript 复制代码
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)管理同类对象

javascript 复制代码
self.bullets = pygame.sprite.Group()

五.总结

  1. 模块化设计:清晰分离输入处理、物理模拟、画面渲染职责
  2. OO结构:通过继承实现Pygame精灵系统整合
  3. 配置隔离:避免游戏逻辑中硬编码参数

完整流程示意图

javascript 复制代码
graph LR
    A[用户输入] --> B(事件监听)
    B --> C{按键处理}
    C -->|移动键| D[飞船位置更新]
    C -->|空格键| E[创建子弹对象]
    D --> G[状态同步]
    E --> G[状态同步]
    G --> F[执行渲染]
相关推荐
☼←安于亥时→❦9 小时前
PyTorch 梯度与微积分
人工智能·pytorch·python
程序员三藏9 小时前
2025最新的软件测试面试八股文(800+道题)
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
Pocker_Spades_A10 小时前
Python快速入门专业版(二十三):for循环基础:遍历字符串、列表与range()函数(计数案例)
python
闲人编程10 小时前
图像去雾算法:从物理模型到深度学习实现
图像处理·人工智能·python·深度学习·算法·计算机视觉·去雾
Kyln.Wu11 小时前
【python实用小脚本-211】[硬件互联] 桌面壁纸×Python梦幻联动|用10行代码实现“开机盲盒”自动化改造实录(建议收藏)
开发语言·python·自动化
Ms_Big12 小时前
ppliteseg改rknn,部署在嵌入式板,加速模型
人工智能·python·深度学习
折翼的恶魔12 小时前
数据分析:合并
python·数据分析·pandas
百锦再13 小时前
在 CentOS 系统上实现定时执行 Python 邮件发送任务
java·linux·开发语言·人工智能·python·centos·pygame
I'm a winner13 小时前
第五章:Python 数据结构:列表、元组与字典(二)
数据结构·python