> 技术文档 > Python游戏开发:Pygame全面指南与实战_python pygame

Python游戏开发:Pygame全面指南与实战_python pygame


第一章 Pygame简介与安装

1.1 Pygame概述

Pygame是一个开源的Python模块,专门用于多媒体应用(如电子游戏)的开发。它基于SDL(Simple DirectMedia Layer)库构建,提供了对图形、声音、输入设备等游戏开发所需功能的访问接口。Pygame最初由Pete Shinners于2000年创建,至今已成为Python游戏开发最流行的库之一。

Pygame的主要特点包括:

  • 简单易用的API设计
  • 跨平台支持(Windows、Mac OS X、Linux等)
  • 无需复杂的环境配置
  • 丰富的功能模块
  • 活跃的社区支持

1.2 Pygame与其他游戏引擎的比较

与其他游戏开发工具相比,Pygame有其独特的优势和不足:

特性 Pygame Unity Unreal Engine Godot 学习曲线 平缓 中等 陡峭 中等 编程语言 Python C# C++ GDScript 2D支持 优秀 良好 一般 优秀 3D支持 有限 优秀 卓越 良好 性能 中等 高 极高 高 适合项目规模 小型 大中型 大型 中小型

1.3 安装Pygame

安装Pygame非常简单,可以通过pip直接安装:

pip install pygame

验证安装是否成功:

import pygameprint(pygame.__version__) # 应输出安装的版本号

1.4 Pygame基础架构

Pygame的核心架构围绕以下几个主要组件构建:

  1. 显示模块:管理窗口和屏幕显示
  2. 事件系统:处理用户输入和系统事件
  3. 图像模块:加载和操作图像
  4. 声音模块:播放音效和音乐
  5. 时间控制:管理游戏帧率和计时
  6. 精灵系统:游戏对象管理

第二章 Pygame基础:第一个游戏窗口

2.1 初始化Pygame

在开始使用Pygame之前,需要先初始化所有模块:

import pygame# 初始化所有Pygame模块pygame.init()# 设置窗口尺寸screen_width = 800screen_height = 600screen = pygame.display.set_mode((screen_width, screen_height))# 设置窗口标题pygame.display.set_caption(\"我的第一个Pygame窗口\")# 游戏主循环running = Truewhile running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 填充背景色(RGB) screen.fill((135, 206, 235)) # 天蓝色背景 # 更新显示 pygame.display.flip()# 退出Pygamepygame.quit()

2.2 游戏主循环解析

游戏主循环是Pygame程序的核心,通常包含以下步骤:

  1. 事件处理:检查用户输入和系统事件
  2. 游戏逻辑更新:更新游戏状态
  3. 渲染绘制:绘制当前帧的画面
  4. 帧率控制:控制游戏运行速度

2.3 基本绘图功能

Pygame提供了一系列基本绘图函数:

# 绘制矩形pygame.draw.rect(screen, (255, 0, 0), (100, 100, 200, 100)) # 红色矩形# 绘制圆形pygame.draw.circle(screen, (0, 255, 0), (400, 300), 50) # 绿色圆形# 绘制线条pygame.draw.line(screen, (0, 0, 255), (50, 50), (750, 550), 5) # 蓝色线条# 绘制多边形pygame.draw.polygon(screen, (255, 255, 0), [(200, 200), (300, 100), (400, 200)]) # 黄色多边形

2.4 完整示例:简单绘图板

import pygameimport syspygame.init()# 设置窗口screen = pygame.display.set_mode((800, 600))pygame.display.set_caption(\"简单绘图板\")# 颜色定义BLACK = (0, 0, 0)WHITE = (255, 255, 255)RED = (255, 0, 0)GREEN = (0, 255, 0)BLUE = (0, 0, 255)# 绘图设置drawing = Falselast_pos = Nonecolor = BLACKradius = 5# 游戏主循环while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # 鼠标按下开始绘图 elif event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1: # 左键 drawing = True last_pos = event.pos elif event.button == 3: # 右键 screen.fill(WHITE) # 清空画布 # 鼠标移动时绘图 elif event.type == pygame.MOUSEMOTION: if drawing and event.buttons[0]: # 左键拖动 if last_pos:  pygame.draw.line(screen, color, last_pos, event.pos, radius * 2)  last_pos = event.pos # 鼠标释放停止绘图 elif event.type == pygame.MOUSEBUTTONUP: if event.button == 1: drawing = False last_pos = None # 键盘控制 elif event.type == pygame.KEYDOWN: if event.key == pygame.K_r: color = RED elif event.key == pygame.K_g: color = GREEN elif event.key == pygame.K_b: color = BLUE elif event.key == pygame.K_UP: radius = min(50, radius + 1) elif event.key == pygame.K_DOWN: radius = max(1, radius - 1) # 显示当前设置 info_surface = pygame.Surface((200, 100)) info_surface.fill(WHITE) font = pygame.font.SysFont(None, 24) color_text = font.render(f\"颜色: {color}\", True, BLACK) radius_text = font.render(f\"粗细: {radius}\", True, BLACK) info_surface.blit(color_text, (10, 10)) info_surface.blit(radius_text, (10, 40)) screen.blit(info_surface, (10, 10)) pygame.display.flip()

第三章 Pygame图像处理与动画

3.1 加载和显示图像

Pygame支持多种图像格式,包括PNG、JPG、BMP等:

# 加载图像player_img = pygame.image.load(\"player.png\").convert_alpha()# 显示图像screen.blit(player_img, (100, 100))

convert()convert_alpha()方法可以优化图像显示性能,后者保留alpha通道(透明度)。

3.2 图像变换

Pygame提供了一些基本的图像变换功能:

# 缩放图像scaled_img = pygame.transform.scale(player_img, (50, 50))# 旋转图像rotated_img = pygame.transform.rotate(player_img, 45) # 旋转45度# 翻转图像flipped_img = pygame.transform.flip(player_img, True, False) # 水平翻转

3.3 动画实现原理

游戏动画通常通过快速连续显示一系列略有不同的图像(帧)来实现。在Pygame中,可以通过以下步骤创建动画:

  1. 加载所有动画帧
  2. 在游戏循环中按顺序显示这些帧
  3. 控制帧切换速度

3.4 完整示例:角色动画

import pygameimport ospygame.init()# 设置窗口screen_width = 800screen_height = 600screen = pygame.display.set_mode((screen_width, screen_height))pygame.display.set_caption(\"角色动画演示\")# 颜色定义WHITE = (255, 255, 255)BLACK = (0, 0, 0)# 加载动画帧animation_frames = []for i in range(1, 7): frame = pygame.image.load(f\"run_animation/frame_{i}.png\").convert_alpha() frame = pygame.transform.scale(frame, (100, 100)) animation_frames.append(frame)# 动画设置current_frame = 0animation_speed = 0.2 # 每秒切换几帧frame_count = 0# 角色位置player_x = 100player_y = 400player_speed = 3# 游戏时钟clock = pygame.time.Clock()# 游戏主循环running = Truewhile running: # 控制帧率 dt = clock.tick(60) / 1000 # 转换为秒 # 事件处理 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 获取按键状态 keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: player_x -= player_speed if keys[pygame.K_RIGHT]: player_x += player_speed # 更新动画帧 frame_count += animation_speed * dt * 60 if frame_count >= 1: current_frame = (current_frame + 1) % len(animation_frames) frame_count = 0 # 绘制 screen.fill(WHITE) screen.blit(animation_frames[current_frame], (player_x, player_y)) # 显示说明文字 font = pygame.font.SysFont(None, 36) text = font.render(\"使用左右方向键移动角色\", True, BLACK) screen.blit(text, (50, 50)) pygame.display.flip()pygame.quit()

第四章 Pygame精灵系统

4.1 Sprite类简介

Pygame的Sprite类是为游戏对象设计的基类,提供了以下功能:

  • 图像管理
  • 位置更新
  • 碰撞检测
  • 分组管理

4.2 创建自定义精灵

class Player(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() self.image = pygame.Surface((50, 50)) self.image.fill((255, 0, 0)) # 红色方块 self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y self.speed = 5 def update(self): keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: self.rect.x -= self.speed if keys[pygame.K_RIGHT]: self.rect.x += self.speed if keys[pygame.K_UP]: self.rect.y -= self.speed if keys[pygame.K_DOWN]: self.rect.y += self.speed

4.3 精灵组的使用

精灵组(Group)用于管理多个精灵,提供批量更新和绘制功能:

# 创建精灵组all_sprites = pygame.sprite.Group()player = Player(100, 100)all_sprites.add(player)# 在游戏循环中all_sprites.update() # 更新所有精灵all_sprites.draw(screen) # 绘制所有精灵

4.4 碰撞检测

Pygame提供了多种碰撞检测方法:

# 矩形碰撞检测if pygame.sprite.collide_rect(sprite1, sprite2): print(\"发生碰撞!\")# 圆形碰撞检测if pygame.sprite.collide_circle(sprite1, sprite2): print(\"圆形碰撞!\")# 精灵与组碰撞检测hits = pygame.sprite.spritecollide(player, enemy_group, True)for enemy in hits: player.health -= 10

4.5 完整示例:太空射击游戏

import pygameimport randomimport ospygame.init()# 屏幕设置WIDTH = 480HEIGHT = 600screen = pygame.display.set_mode((WIDTH, HEIGHT))pygame.display.set_caption(\"太空射击游戏\")# 颜色定义WHITE = (255, 255, 255)BLACK = (0, 0, 0)RED = (255, 0, 0)GREEN = (0, 255, 0)BLUE = (0, 0, 255)# 加载图像def load_image(name, scale=1): img = pygame.Surface((50, 40)) img.fill(BLUE if name == \"player\" else RED) return img# 玩家精灵class Player(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = load_image(\"player\") self.rect = self.image.get_rect() self.rect.centerx = WIDTH / 2 self.rect.bottom = HEIGHT - 10 self.speed_x = 0 self.health = 100 def update(self): self.speed_x = 0 keystate = pygame.key.get_pressed() if keystate[pygame.K_LEFT]: self.speed_x = -8 if keystate[pygame.K_RIGHT]: self.speed_x = 8 self.rect.x += self.speed_x # 边界检查 if self.rect.right > WIDTH: self.rect.right = WIDTH if self.rect.left < 0: self.rect.left = 0 def shoot(self): 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 = load_image(\"enemy\") self.rect = self.image.get_rect() self.rect.x = random.randrange(WIDTH - self.rect.width) self.rect.y = random.randrange(-100, -40) self.speedy = random.randrange(1, 5) self.speedx = random.randrange(-2, 2) def update(self): self.rect.y += self.speedy self.rect.x += self.speedx # 边界检查和重生 if self.rect.top > HEIGHT + 10 or self.rect.left < -25 or self.rect.right > WIDTH + 25: self.rect.x = random.randrange(WIDTH - self.rect.width) self.rect.y = random.randrange(-100, -40) self.speedy = random.randrange(1, 5)# 子弹类class Bullet(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() self.image = pygame.Surface((10, 20)) self.image.fill(GREEN) self.rect = self.image.get_rect() self.rect.centerx = x self.rect.bottom = y self.speedy = -10 def update(self): self.rect.y += self.speedy # 如果子弹飞出屏幕顶部,则删除 if self.rect.bottom < 0: self.kill()# 创建精灵组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 = 0font = pygame.font.SysFont(None, 36)# 游戏循环clock = pygame.time.Clock()running = Truewhile running: # 保持循环以正确的速度运行 clock.tick(60) # 处理输入事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: player.shoot() # 更新 all_sprites.update() # 检查子弹是否击中敌人 hits = pygame.sprite.groupcollide(enemies, bullets, True, True) for hit in hits: score += 10 enemy = Enemy() all_sprites.add(enemy) enemies.add(enemy) # 检查敌人是否撞到玩家 hits = pygame.sprite.spritecollide(player, enemies, False) if hits: player.health -= 1 if player.health <= 0: running = False # 渲染 screen.fill(BLACK) all_sprites.draw(screen) # 显示分数 score_text = font.render(f\"分数: {score}\", True, WHITE) screen.blit(score_text, (10, 10)) # 显示生命值 health_text = font.render(f\"生命: {player.health}\", True, WHITE) screen.blit(health_text, (10, 50)) # 刷新屏幕 pygame.display.flip()pygame.quit()

第五章 Pygame声音与音乐

5.1 加载和播放音效

# 加载音效shoot_sound = pygame.mixer.Sound(\"shoot.wav\")# 播放音效shoot_sound.play()

5.2 背景音乐控制

# 加载背景音乐pygame.mixer.music.load(\"background.mp3\")# 播放背景音乐(循环播放)pygame.mixer.music.play(-1)# 暂停音乐pygame.mixer.music.pause()# 继续播放pygame.mixer.music.unpause()# 停止音乐pygame.mixer.music.stop()

5.3 音量控制

# 设置主音量(0.0到1.0)pygame.mixer.music.set_volume(0.5)# 设置单个音效音量shoot_sound.set_volume(0.3)

5.4 完整示例:音乐播放器

import pygameimport ospygame.init()# 屏幕设置WIDTH = 400HEIGHT = 300screen = pygame.display.set_mode((WIDTH, HEIGHT))pygame.display.set_caption(\"简易音乐播放器\")# 颜色定义WHITE = (255, 255, 255)BLACK = (0, 0, 0)GRAY = (200, 200, 200)# 字体font = pygame.font.SysFont(None, 24)# 音乐列表music_files = [\"song1.mp3\", \"song2.mp3\", \"song3.mp3\"]current_song = 0# 加载第一首歌pygame.mixer.music.load(music_files[current_song])# 按钮类class Button: def __init__(self, x, y, width, height, text, color, hover_color): self.rect = pygame.Rect(x, y, width, height) self.text = text self.color = color self.hover_color = hover_color self.is_hovered = False def draw(self, surface): color = self.hover_color if self.is_hovered else self.color pygame.draw.rect(surface, color, self.rect) pygame.draw.rect(surface, BLACK, self.rect, 2) text_surf = font.render(self.text, True, BLACK) text_rect = text_surf.get_rect(center=self.rect.center) surface.blit(text_surf, text_rect) def check_hover(self, pos): self.is_hovered = self.rect.collidepoint(pos) return self.is_hovered def handle_event(self, event): if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1 and self.is_hovered: return True return False# 创建按钮play_button = Button(50, 200, 80, 40, \"播放\", GRAY, WHITE)pause_button = Button(160, 200, 80, 40, \"暂停\", GRAY, WHITE)stop_button = Button(270, 200, 80, 40, \"停止\", GRAY, WHITE)next_button = Button(270, 150, 80, 40, \"下一首\", GRAY, WHITE)prev_button = Button(50, 150, 80, 40, \"上一首\", GRAY, WHITE)# 游戏主循环running = Trueclock = pygame.time.Clock()while running: # 事件处理 mouse_pos = pygame.mouse.get_pos() for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 检查按钮悬停 play_button.check_hover(mouse_pos) pause_button.check_hover(mouse_pos) stop_button.check_hover(mouse_pos) next_button.check_hover(mouse_pos) prev_button.check_hover(mouse_pos) # 处理按钮点击 if play_button.handle_event(event): pygame.mixer.music.play() if pause_button.handle_event(event): if pygame.mixer.music.get_busy(): pygame.mixer.music.pause() else: pygame.mixer.music.unpause() if stop_button.handle_event(event): pygame.mixer.music.stop() if next_button.handle_event(event): current_song = (current_song + 1) % len(music_files) pygame.mixer.music.load(music_files[current_song]) pygame.mixer.music.play() if prev_button.handle_event(event): current_song = (current_song - 1) % len(music_files) pygame.mixer.music.load(music_files[current_song]) pygame.mixer.music.play() # 绘制 screen.fill(WHITE) # 显示当前歌曲 song_text = font.render(f\"当前播放: {music_files[current_song]}\", True, BLACK) screen.blit(song_text, (20, 50)) # 显示播放状态 status = \"播放中\" if pygame.mixer.music.get_busy() else \"已停止\" status_text = font.render(f\"状态: {status}\", True, BLACK) screen.blit(status_text, (20, 80)) # 绘制按钮 play_button.draw(screen) pause_button.draw(screen) stop_button.draw(screen) next_button.draw(screen) prev_button.draw(screen) # 更新显示 pygame.display.flip() clock.tick(30)pygame.quit()

第六章 Pygame高级主题

6.1 使用OpenGL加速

Pygame可以通过pygame.OPENGL标志与OpenGL结合使用:

import pygamefrom pygame.locals import *from OpenGL.GL import *from OpenGL.GLU import *def init(): glEnable(GL_DEPTH_TEST) glClearColor(0.5, 0.5, 0.5, 1.0) gluPerspective(45, (800/600), 0.1, 50.0) glTranslatef(0.0, 0.0, -5)def cube(): glBegin(GL_QUADS) # 前面 glColor3fv((1, 0, 0)) glVertex3fv((1, -1, -1)) glVertex3fv((1, 1, -1)) glVertex3fv((-1, 1, -1)) glVertex3fv((-1, -1, -1)) # 更多面... glEnd()def main(): pygame.init() display = (800, 600) pygame.display.set_mode(display, DOUBLEBUF|OPENGL) init() while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() return glRotatef(1, 3, 1, 1) glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) cube() pygame.display.flip() pygame.time.wait(10)if __name__ == \"__main__\": main()

6.2 使用Pygame制作GUI

虽然Pygame不是专门的GUI库,但可以用来创建简单的界面元素:

class Button: def __init__(self, x, y, width, height, text, color, hover_color): self.rect = pygame.Rect(x, y, width, height) self.text = text self.color = color self.hover_color = hover_color self.is_hovered = False def draw(self, surface): color = self.hover_color if self.is_hovered else self.color pygame.draw.rect(surface, color, self.rect) pygame.draw.rect(surface, (0, 0, 0), self.rect, 2) font = pygame.font.SysFont(None, 24) text_surf = font.render(self.text, True, (0, 0, 0)) text_rect = text_surf.get_rect(center=self.rect.center) surface.blit(text_surf, text_rect) def check_hover(self, pos): self.is_hovered = self.rect.collidepoint(pos) return self.is_hovered def handle_event(self, event): if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1 and self.is_hovered: return True return False

6.3 网络游戏开发

Pygame可以与socket模块结合开发简单的网络游戏:

import socketimport threadingimport pygameclass NetworkGame: def __init__(self): pygame.init() self.screen = pygame.display.set_mode((800, 600)) self.clock = pygame.time.Clock() self.running = True # 网络设置 self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.server_address = (\'localhost\', 12345) # 连接服务器 self.connect_to_server() def connect_to_server(self): try: self.socket.connect(self.server_address) # 启动接收线程 receive_thread = threading.Thread(target=self.receive_data) receive_thread.daemon = True receive_thread.start() except Exception as e: print(f\"连接服务器失败: {e}\") def receive_data(self): while self.running: try: data = self.socket.recv(1024).decode() if data:  self.handle_network_data(data) except Exception as e: print(f\"接收数据错误: {e}\") break def handle_network_data(self, data): # 处理接收到的网络数据 print(f\"收到数据: {data}\") def send_data(self, data): try: self.socket.sendall(data.encode()) except Exception as e: print(f\"发送数据失败: {e}\") def run(self): while self.running: for event in pygame.event.get(): if event.type == pygame.QUIT:  self.running = False elif event.type == pygame.KEYDOWN:  if event.key == pygame.K_SPACE: self.send_data(\"player_jump\") # 游戏逻辑和渲染 self.screen.fill((0, 0, 0)) pygame.display.flip() self.clock.tick(60) pygame.quit()if __name__ == \"__main__\": game = NetworkGame() game.run()

第七章 Pygame性能优化

7.1 图像优化技巧

  1. 使用convert()convert_alpha()

    # 普通图像image = pygame.image.load(\"image.png\").convert()# 带透明度的图像image = pygame.image.load(\"image.png\").convert_alpha()
  2. 避免频繁加载图像:在游戏初始化时加载所有需要的图像

  3. 使用精灵表:将多个小图像合并到一个大图像中

7.2 游戏循环优化

  1. 控制帧率

    clock = pygame.time.Clock()while True: clock.tick(60) # 限制为60FPS
  2. 脏矩形更新:只更新屏幕上发生变化的部分

    pygame.display.update(rect_list) # 只更新指定矩形区域
  3. 分批处理:将相似的绘制操作集中处理

7.3 内存管理

  1. 及时释放资源

    def unload_resources(self): for image in self.image_cache.values(): del image self.image_cache.clear()
  2. 使用对象池:对频繁创建销毁的对象进行重用

7.4 性能分析工具

  1. Python内置的cProfile

    python -m cProfile -s cumtime your_game.py
  2. Pygame内置的time模块

    start_time = pygame.time.get_ticks()# 执行代码end_time = pygame.time.get_ticks()print(f\"耗时: {end_time - start_time}毫秒\")

第八章 Pygame项目实战:平台游戏

8.1 游戏设计

我们将创建一个简单的平台游戏,包含以下功能:

  • 玩家角色可以左右移动和跳跃
  • 多个平台供玩家站立
  • 收集物品获得分数
  • 敌人会移动并伤害玩家
  • 简单的关卡设计

8.2 游戏架构

import pygameimport randomimport sys# 初始化pygame.init()WIDTH, HEIGHT = 800, 600screen = pygame.display.set_mode((WIDTH, HEIGHT))pygame.display.set_caption(\"平台游戏\")clock = pygame.time.Clock()# 颜色定义WHITE = (255, 255, 255)BLACK = (0, 0, 0)BLUE = (0, 0, 255)RED = (255, 0, 0)GREEN = (0, 255, 0)GRAY = (100, 100, 100)# 玩家类class Player(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = pygame.Surface((30, 50)) self.image.fill(BLUE) self.rect = self.image.get_rect() self.rect.center = (WIDTH // 2, HEIGHT // 2) self.velocity_y = 0 self.velocity_x = 0 self.jumping = False self.health = 100 self.score = 0 def update(self): # 重力 self.velocity_y += 0.5 if self.velocity_y > 10: self.velocity_y = 10 # 水平移动 self.rect.x += self.velocity_x # 检查水平边界 if self.rect.left < 0: self.rect.left = 0 if self.rect.right > WIDTH: self.rect.right = WIDTH # 垂直移动 self.rect.y += self.velocity_y # 检查是否落地 if self.rect.bottom >= HEIGHT - 50: self.rect.bottom = HEIGHT - 50 self.velocity_y = 0 self.jumping = False def jump(self): if not self.jumping: self.velocity_y = -12 self.jumping = True# 平台类class Platform(pygame.sprite.Sprite): def __init__(self, x, y, width, height): super().__init__() self.image = pygame.Surface((width, height)) self.image.fill(GREEN) self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y# 敌人类class Enemy(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() self.image = pygame.Surface((30, 30)) self.image.fill(RED) self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y self.direction = 1 self.speed = 2 def update(self): self.rect.x += self.speed * self.direction # 简单的AI:碰到边缘就回头 if self.rect.right > WIDTH or self.rect.left < 0: self.direction *= -1# 收集物品类class Item(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() self.image = pygame.Surface((20, 20)) self.image.fill((255, 255, 0)) # 黄色 self.rect = self.image.get_rect() self.rect.center = (x, y)# 创建精灵组all_sprites = pygame.sprite.Group()platforms = pygame.sprite.Group()enemies = pygame.sprite.Group()items = pygame.sprite.Group()# 创建玩家player = Player()all_sprites.add(player)# 创建地面ground = Platform(0, HEIGHT - 50, WIDTH, 50)all_sprites.add(ground)platforms.add(ground)# 创建平台platform_positions = [ (100, 400, 200, 20), (400, 300, 150, 20), (200, 200, 100, 20), (500, 150, 200, 20)]for pos in platform_positions: p = Platform(*pos) all_sprites.add(p) platforms.add(p)# 创建敌人enemy_positions = [(200, 350), (450, 250), (300, 150)]for pos in enemy_positions: e = Enemy(*pos) all_sprites.add(e) enemies.add(e)# 创建收集物品for i in range(10): x = random.randint(50, WIDTH - 50) y = random.randint(50, HEIGHT - 100) item = Item(x, y) all_sprites.add(item) items.add(item)# 游戏状态game_over = Falsefont = pygame.font.SysFont(None, 36)# 游戏主循环while not game_over: # 事件处理 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: player.jump() # 获取按键状态 keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: player.velocity_x = -5 elif keys[pygame.K_RIGHT]: player.velocity_x = 5 else: player.velocity_x = 0 # 更新 all_sprites.update() # 检查玩家是否站在平台上 if player.velocity_y > 0: # 正在下落 platform_hits = pygame.sprite.spritecollide(player, platforms, False) if platform_hits: player.rect.bottom = platform_hits[0].rect.top player.velocity_y = 0 player.jumping = False # 检查与敌人的碰撞 enemy_hits = pygame.sprite.spritecoll