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[执行渲染]
相关推荐
老白干1 小时前
jjwt 0.9.1 在 JDK 11+ 上的两个“坑”与完整解决方案
java·python·log4j
笨鸟先飞,勤能补拙7 小时前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
长和信泰光伏储能8 小时前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂9 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
Gu Gu Study9 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境10 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境10 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd12310 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy123931021611 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
bamb0011 小时前
一个项目带你入门AI应用开发01
python