MC.Steve 发表于 2 小时前

Pygame的入门与进阶(开发实践仅供参考)

本帖最后由 MC.Steve 于 2026-2-13 12:17 编辑


推荐网站:pygame首页
https://cn.bing.com/images/search?view=detailV2&ccid=P1FiX7hO&id=B0DA5FA0944A43E97A9EBD7B92DD1AC1D811D411&thid=OIP.P1FiX7hOx62IzeREcITkmgHaEW&mediaurl=https%3a%2f%2fi-blog.csdnimg.cn%2fblog_migrate%2f38cf92632ad4e8b4bd05441dfdbb1b75.png&exph=612&expw=1041&q=python%e5%9b%be%e7%89%87&form=IRPRST&ck=0BDAFFB4266C3B65576A7BEDEA672D5C&selectedindex=4&itb=0&ajaxhist=0&ajaxserp=0&first=1



观看须知!!!:
请务必在Python中下载好Pygmae
此文章篇幅较长,请做好心理准备{:9_218:}
纯文字,无图
适合萌新观看{:9_228:}
如没有下载,请输入以下指令:
pip install pygame
好的,正片马上开始!!!
本文章均为原创,无任何抄袭


入门篇
1.1了解Pygame
Pygame 是一个开源的 Python 模块集合,用于创建 2D 游戏和多媒体应用程序。它简单易学,非常适合初学者入门游戏开发,同时也被广泛用于教学、原型设计和小型项目。

Pygame 的主要功能:
图形显示:创建窗口、绘制形状、加载图片、动画渲染、
事件处理:响应键盘、鼠标、游戏手柄等用户输入
声音播放:支持加载和播放 .wav、.mp3 等音频文件
时间控制:控制帧率(FPS),实现平滑动画
碰撞检测:提供多种方式判断对象是否相撞
字体与文本:显示自定义字体的文字信息

Pygame 核心模块简介
pygame.display:控制窗口和屏幕显示
pygame.event:获取用户的输入事件(如点击关闭按钮)
pygame.draw:绘制基本图形(线、圆、矩形等)
pygame.image:加载和保存图像(支持 PNG、JPG 等格式)
pygame.mixer:播放音效和音乐
pygame.font:渲染文字
pygame.time:控制时间和帧率
pygame.sprite:管理游戏中的角色(精灵)和组
pygame.Rect:表示矩形区域,常用于位置和碰撞检测

开发小游戏的基本结构:
import pygame
pygame.init()
# 1. 设置游戏窗口
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("小游戏")
# 2. 加载资源(图片、声音、字体)
font = pygame.font.SysFont('SimHei', 32)
sound = pygame.mixer.Sound('click.wav')   # 示例音效
# 3. 游戏变量
score = 0
player_pos =
# 4. 主循环
clock = pygame.time.Clock()
running = True
while running:
    dt = clock.tick(60) / 1000# 时间增量(秒)
    # 5. 事件处理
    for event in pygame.event.get():
      if event.type == pygame.QUIT:
            running = False
      elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                score += 1
                sound.play()
    # 6. 键盘输入检测(持续按下)
    keys = pygame.key.get_pressed()
    if keys:
      player_pos -= 200 * dt
    if keys:
      player_pos += 200 * dt
    # 7. 更新逻辑(如移动、碰撞等)
    # 8. 绘图
    screen.fill((0, 0, 0))
    pygame.draw.rect(screen, (255, 0, 0), (*player_pos, 50, 50))
    # 显示分数(注意中文字体可能需要额外处理)
    text = font.render(f"得分: {score}", True, (255, 255, 255))
    screen.blit(text, (10, 10))
    pygame.display.flip()
pygame.quit()


注意事项:
Pygame 不适合开发大型 3D 游戏。
对中文支持有限(字体路径问题),建议使用英文或提前准备中文字体文件(如 simhei.ttf)。

1.2入门(1)
1.2.1基础知识
熟悉基本结构,能创建窗口、处理事件、绘制图形和响应输入。

核心知识点
pygame.init():初始化所有子模块
pygame.display.set_mode():创建游戏窗口
pygame.event.get():获取用户事件(如关闭窗口)
pygame.draw.*:绘制形状(矩形、圆形、线条等)
pygame.time.Clock():控制帧率(FPS)
pygame.key.get_pressed():检测按键是否被按下

基本程序结构模板:
import pygame

pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
running = True

while running:
    # 事件处理
    for event in pygame.event.get():
      if event.type == pygame.QUIT:
            running = False

    # 清屏
    screen.fill("black")

    # 绘图逻辑(例如画一个圆)
    pygame.draw.circle(screen, "red", (400, 300), 50)

    # 更新屏幕
    pygame.display.flip()

    # 控制帧率
    clock.tick(60)

pygame.quit()

1.2.2坐标系与颜色系统
坐标系(左上角为原点)
(0,0) ──→ x轴


↓ y轴
(0,0) 是左上角
向右 x 增加,向下 y 增加

颜色表示法
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
# 也可以用字符串(仅限基本颜色)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
# 也可以用字符串(仅限基本颜色)
screen.fill("red")
pygame.draw.circle(screen, "blue", (100, 100), 30)


1.2.3 绘图基础(pygame.draw)
draw.rect(surface, color, rect):画矩形
draw.circle(surface, color, center, radius):画圆
draw.line(surface, color, start_pos, end_pos, width):画线
draw.polygon(surface, color, points):画多边形
示例:# 画一个红色矩形
pygame.draw.rect(screen, "red", )

# 画一条蓝线
pygame.draw.line(screen, "blue", (0, 0), (800, 600), 5)


1.2.4显示文字(支持中文需指定字体路径)
例如:
# 方法一:使用系统字体(可能不支持中文)
font = pygame.font.SysFont("SimHei", 32, bold=True)# Windows 黑体

# 方法二:加载本地字体文件(更可靠)
font = pygame.font.Font("fonts/SimHei.ttf", 32)

# 创建文本表面
text_surface = font.render("得分: 100", True, (255, 255, 255))# anti-aliasing=True
screen.blit(text_surface, (10, 10))

中文乱码解决办法:

使用 .ttf 字体文件
确保文件编码为 UTF-8
不要用默认字体如 "arial" 显示中文


1.2.5.1输入事件处理
空格      K_SPACE      空格键
回车      K_RETURN      Enter 键
ESC      K_ESCAPE      退出菜单
方向键      K_LEFT, K_RIGHT, K_UP, K_DOWN      ← ↑ → ↓
字母键      K_a, K_b, ..., K_z      小写形式
数字键      K_0 ~ K_9      主键盘数字
功能键      K_F1, K_TAB, K_LSHIFT      F1、Tab、左Shift等

小技巧:可以用 pygame.key.name(event.key) 获取按键名称字符串
print(pygame.key.name(event.key))# 输出 'space', 'a', 'up' 等


1.2.5.2使用 pygame.key.get_pressed()
适用于 需要持续响应的操作,比如角色移动。

它返回一个布尔数组,表示当前哪些键正处于“被按下”的状态。
keys = pygame.key.get_pressed()

if keys or keys:
    player.x -= 5
if keys or keys:
    player.x += 5
if keys:
    player.y -= 5
if keys:
    player.y += 5

优点:
支持组合键(如同时按 W+A 斜向移动)
更适合高频控制(如平台跳跃)
缺点:
无法区分是第几次按下(不适合“按一下切换模式”类功能)

1.2.6精灵系统与碰撞检测
精灵系统实现:
#基础精灵类(专业OOP设计)
class GameObject(pygame.sprite.Sprite):
    """所有游戏对象的基类"""
    def __init__(self, image_path, position):
      super().__init__()
      self.image = pygame.image.load(image_path).convert_alpha()
      self.rect = self.image.get_rect(center=position)
      self.mask = pygame.mask.from_surface(self.image)# 像素级碰撞掩码
   
    def update(self, delta_time):
      """子类应重写此方法实现具体行为"""
      pass

#玩家类(继承与多态应用)
class Player(GameObject):
    def __init__(self, position):
      super().__init__('assets/player.png', position)
      self.speed = 300# 像素/秒(专业单位设定)
      self.health = 100
   
    def update(self, delta_time):
      # 获取键盘状态(帧率无关移动)
      keys = pygame.key.get_pressed()
      dx, dy = 0, 0
      
      if keys: dx -= 1
      if keys: dx += 1
      if keys: dy -= 1
      if keys: dy += 1
      
      # 对角线移动归一化(专业数学处理)
      if dx != 0 and dy != 0:
            magnitude = (dx**2 + dy**2)**0.5
            dx, dy = dx/magnitude, dy/magnitude
      
      # 应用速度与时间增量
      self.rect.x += dx * self.speed * delta_time
      self.rect.y += dy * self.speed * delta_time
      
      # 边界限制(专业实践)
      screen_rect = pygame.display.get_surface().get_rect()
      self.rect.clamp_ip(screen_rect)

#碰撞检测系统(专业实现)
def check_collisions(player, enemies):
    #矩形碰撞(快速筛选)
    collisions = pygame.sprite.spritecollide(
      player, enemies, False,
      collided=pygame.sprite.collide_rect
    )
   
    # 像素级碰撞(精确检测)
    precise_collisions = [
      enemy for enemy in collisions
      if pygame.sprite.collide_mask(player, enemy)
    ]
   
    return precise_collisions


知识点:
精灵组管理:pygame.sprite.Group实现高效对象管理
碰撞检测优化:
第一级:边界框检测(collide_rect)
第二级:圆形粗略检测(collide_circle)
第三级:像素级精确检测(collide_mask)
帧率无关运动:速度 × delta_time 实现跨设备一致体验
向量归一化:解决对角线移动速度过快问题


进阶篇
2.1.1游戏状态管理

状态机实现

class GameState:
    """游戏状态管理基类"""
    def handle_events(self, events):
      pass
   
    def update(self, delta_time):
      pass
   
    def render(self, screen):
      pass

class MainMenuState(GameState):
    def __init__(self):
      self.font = pygame.font.SysFont(None, 48)
      self.options = ["开始游戏", "设置", "退出"]
      self.selected = 0
   
    def handle_events(self, events):
      for event in events:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP:
                  self.selected = (self.selected - 1) % len(self.options)
                elif event.key == pygame.K_DOWN:
                  self.selected = (self.selected + 1) % len(self.options)
                elif event.key == pygame.K_RETURN:
                  if self.selected == 0:
                        return GameState.PLAYING
                  elif self.selected == 2:
                        return GameState.QUIT
   
    def render(self, screen):
      screen.fill((0, 0, 0))
      for i, option in enumerate(self.options):
            color = (255, 255, 0) if i == self.selected else (255, 255, 255)
            text = self.font.render(option, True, color)
            screen.blit(text, (400, 200 + i * 60))

# 游戏主循环中的状态管理
current_state = MainMenuState()
while running:
    events = pygame.event.get()
    for event in events:
      if event.type == pygame.QUIT:
            running = False
   
    # 状态转换
    next_state = current_state.handle_events(events)
    if next_state == GameState.QUIT:
      running = False
    elif next_state:
      current_state = next_state
   
    # 状态更新与渲染
    current_state.update(delta_time)
    current_state.render(screen)
   
    pygame.display.flip()
    delta_time = clock.tick(FPS) / 1000.0

优势:

关注点分离:每个状态独立处理自身逻辑
可扩展性:轻松添加新状态(如暂停、设置菜单)
避免巨型条件语句:符合软件工程最佳实践
状态堆栈支持:实现嵌套状态(如"游戏内暂停"→"主菜单")

2.2 高级渲染技术

渲染技巧
def create_gradient_surface(width, height, start_color, end_color):
    """创建垂直渐变背景(专业图形技术)"""
    surface = pygame.Surface((width, height), pygame.SRCALPHA)
    for y in range(height):
      # 线性插值计算颜色
      r = int(start_color + (end_color - start_color) * y / height)
      g = int(start_color + (end_color - start_color) * y / height)
      b = int(start_color + (end_color - start_color) * y / height)
      pygame.draw.line(surface, (r, g, b), (0, y), (width, y))
    return surface

def render_with_shadows(screen, game_objects):
    """带阴影效果的渲染(专业视觉效果)"""
    # 创建离屏表面用于阴影渲染
    shadow_surface = pygame.Surface(screen.get_size(), pygame.SRCALPHA)
   
    # 绘制阴影(模糊效果)
    for obj in game_objects:
      shadow_rect = obj.rect.inflate(10, 10)
      pygame.draw.rect(shadow_surface, (0, 0, 0, 100), shadow_rect, border_radius=5)
   
    # 应用高斯模糊(简化版)
    for _ in range(3):# 模拟多次模糊
      shadow_surface.blit(shadow_surface, (1, 0))
      shadow_surface.blit(shadow_surface, (-1, 0))
      shadow_surface.blit(shadow_surface, (0, 1))
      shadow_surface.blit(shadow_surface, (0, -1))
   
    # 4. 绘制阴影和游戏对象
    screen.blit(shadow_surface, (0, 0))
    for obj in game_objects:
      screen.blit(obj.image, obj.rect)


图形学概念:

离屏渲染:先绘制到隐藏表面,再合成到主屏幕
线性插值:实现平滑颜色过渡
高斯模糊:通过多次偏移叠加模拟真实模糊效果
Alpha混合:利用透明度通道实现半透明效果



开发实践篇
3.1 项目组织最佳实践
my_game/
├── main.py                # 主程序入口
├── game/
│   ├── __init__.py      # 包声明
│   ├── game.py            # 游戏主逻辑
│   ├── states/            # 游戏状态模块
│   │   ├── __init__.py
│   │   ├── menu.py
│   │   ├── playing.py
│   │   └── game_over.py
│   ├── entities/          # 游戏实体
│   │   ├── __init__.py
│   │   ├── player.py
│   │   ├── enemy.py
│   │   └── bullet.py
│   └── utils/             # 工具函数
│       ├── __init__.py
│       ├── resources.py   # 资源管理
│       └── collision.py   # 碰撞检测工具
├── assets/                # 资源目录
│   ├── images/            # 图像资源
│   ├── sounds/            # 音频资源
│   └── fonts/             # 字体资源
└── requirements.txt       # 依赖声明


3.2 专业开发流程
需求分析:明确游戏核心机制和功能
架构设计:确定模块划分和交互方式
原型开发:快速实现核心玩法
迭代完善:逐步添加新功能和优化
测试验证:确保功能正确性和性能
文档编写:记录设计决策和使用说明


辅助篇(选看)
4.1常见问题
游戏卡顿        未使用delta_time        实现帧率无关运动
内存增长        未清理不再需要的对象        使用kill()方法,定期清理
碰撞检测慢        未优化碰撞检测                实现分层碰撞检测策略
资源加载慢        运行时加载资源                预加载资源到内存

#性能分析工具
import cProfile
cProfile.run('main_game_loop()', 'profile_stats')

#可视化调试辅助
def draw_debug_info(screen, player, clock):
    """绘制调试信息(专业开发实践)"""
    font = pygame.font.SysFont(None, 24)
   
    # FPS显示
    fps_text = font.render(f"FPS: {clock.get_fps():.1f}", True, (255, 255, 0))
    screen.blit(fps_text, (10, 10))
   
    # 玩家状态
    pos_text = font.render(f"Position: ({player.rect.x:.1f}, {player.rect.y:.1f})", True, (255, 255, 0))
    screen.blit(pos_text, (10, 40))
   
    # 碰撞框可视化(专业调试技巧)
    pygame.draw.rect(screen, (255, 0, 0), player.rect, 1)



结语
建议:
从模仿开始:分析优秀游戏代码,理解设计思路
小步快跑:每次只添加一个功能,确保稳定
文档先行:设计前先写注释,明确目标
持续学习:关注Pygame社区,了解最新实践

拓展学习路径
深入Pygame:研究源码,理解底层机制
游戏设计理论:学习游戏平衡性、关卡设计
其他引擎:探索Unity、Godot等专业引擎
计算机图形学:理解渲染管线、着色器

完结~~~~~~

你们的评分就是我最大的支持(累晕了{:10_261:} {:5_99:} {:9_231:} {:13_459:} )
你们的鱼币也是喔~~~~
页: [1]
查看完整版本: Pygame的入门与进阶(开发实践仅供参考)