文章目录
- import pygame import sys class Game: def __init__(self): “””初始化游戏””” pygame.init() # 1. 创建游戏窗口 self.screen_width = 800 self.screen_height = 600 self.screen = pygame.display.set_mode( (self.screen_width, self.screen_height) ) pygame.display.set_caption(“我的游戏”) # 2. 初始化游戏时钟(控制帧率) self.clock = pygame.time.Clock() self.FPS = 60 # 3. 游戏状态 self.running = True self.game_over = False # 4. 颜色定义(RGB) self.BLACK = (0, 0, 0) self.WHITE = (255, 255, 255) self.RED = (255, 0, 0) self.GREEN = (0, 255, 0) self.BLUE = (0, 0, 255) # 5. 初始化游戏资源 self.load_resources() def load_resources(self): “””加载游戏资源””” # 字体 self.font_small = pygame.font.SysFont(None, 36) self.font_large = pygame.font.SysFont(None, 72) # 加载图片 try: self.player_image = pygame.image.load(“player.png”).convert_alpha() except: # 如果图片不存在,创建一个矩形代替 self.player_image = pygame.Surface((50, 50)) self.player_image.fill(self.BLUE) # 加载音效 try: self.jump_sound = pygame.mixer.Sound(“jump.wav”) except: self.jump_sound = None # 背景音乐 pygame.mixer.music.load(“bgm.mp3”) pygame.mixer.music.play(-1) # -1表示循环播放
- def run(self): “””主游戏循环””” while self.running: # 1. 处理事件 self.handle_events() # 2. 更新游戏状态(只有游戏没结束时才更新) if not self.game_over: self.update() # 3. 绘制画面 self.render() # 4. 控制帧率 self.clock.tick(self.FPS) # 游戏结束,退出 self.quit() def handle_events(self): “””事件处理””” for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = False # 键盘按下事件 elif event.type == pygame.KEYDOWN: self.on_key_down(event.key) # 键盘释放事件 elif event.type == pygame.KEYUP: self.on_key_up(event.key) # 鼠标事件 elif event.type == pygame.MOUSEBUTTONDOWN: self.on_mouse_click(event.pos, event.button)
- class Player(pygame.sprite.Sprite): “””玩家角色类””” def __init__(self, x, y): super().__init__() # 创建图像和矩形 self.image = pygame.Surface((50, 50)) self.image.fill((0, 0, 255)) # 加载动画帧 self.frames = [] self.load_animation_frames() self.current_frame = 0 self.animation_speed = 0.2 self.animation_timer = 0 self.rect = self.image.get_rect() self.rect.center = (x, y) # 物理属性 self.velocity = pygame.Vector2(0, 0) self.speed = 5 self.jump_power = -15 self.gravity = 0.8 self.on_ground = False # 游戏属性 self.health = 100 self.score = 0 def load_animation_frames(self): “””加载动画帧””” for i in range(4): frame = pygame.Surface((50, 50)) frame.fill((0, 0, 200 + i * 15)) self.frames.append(frame) def update(self, platforms): “””更新玩家状态””” # 处理用户输入 keys = pygame.key.get_pressed() # 水平移动 self.velocity.x = 0 if keys[pygame.K_LEFT]: self.velocity.x = -self.speed if keys[pygame.K_RIGHT]: self.velocity.x = self.speed # 跳跃 if keys[pygame.K_SPACE] and self.on_ground: self.velocity.y = self.jump_power self.on_ground = False # 应用重力 self.velocity.y += self.gravity # 水平移动 self.rect.x += self.velocity.x # 水平碰撞检测 self.check_horizontal_collision(platforms) # 垂直移动 self.rect.y += self.velocity.y # 垂直碰撞检测 self.check_vertical_collision(platforms) # 更新动画 self.update_animation() # 边界检查 self.check_bounds() def check_horizontal_collision(self, platforms): for platform in platforms: if self.rect.colliderect(platform): if self.velocity.x > 0: # 向右移动 self.rect.right = platform.left elif self.velocity.x < 0: # 向左移动 self.rect.left = platform.right def check_vertical_collision(self, platforms): self.on_ground = False for platform in platforms: if self.rect.colliderect(platform): if self.velocity.y > 0: # 向下移动 self.rect.bottom = platform.top self.velocity.y = 0 self.on_ground = True elif self.velocity.y < 0: # 向上移动 self.rect.top = platform.bottom self.velocity.y = 0 def update_animation(self): “””更新动画帧””” self.animation_timer += self.animation_speed if self.animation_timer >= 1: self.current_frame = (self.current_frame + 1) % len(self.frames) self.image = self.frames[self.current_frame] self.animation_timer = 0 def check_bounds(self): “””检查边界””” if self.rect.top > 600: # 掉落屏幕 self.health = 0
- class GameScene: “””游戏场景基类””” def __init__(self, game): self.game = game def handle_events(self): pass def update(self): pass def render(self): pass class MainMenuScene(GameScene): “””主菜单场景””” def __init__(self, game): super().__init__(game) self.buttons = [] self.create_buttons() def create_buttons(self): “””创建菜单按钮””” button_width, button_height = 200, 50 # 开始游戏按钮 start_rect = pygame.Rect( self.game.screen_width // 2 – button_width // 2, 200, button_width, button_height ) self.buttons.append({ ‘rect’: start_rect, ‘text’: ‘开始游戏’, ‘action’: self.start_game }) # 退出游戏按钮 quit_rect = pygame.Rect( self.game.screen_width // 2 – button_width // 2, 280, button_width, button_height ) self.buttons.append({ ‘rect’: quit_rect, ‘text’: ‘退出游戏’, ‘action’: self.quit_game }) def handle_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self.game.running = False elif event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1: # 左键 self.check_button_click(event.pos) def check_button_click(self, pos): “””检查按钮点击””” for button in self.buttons: if button[‘rect’].collidepoint(pos): button[‘action’]() def start_game(self): “””切换到游戏场景””” self.game.current_scene = GamePlayScene(self.game) def quit_game(self): self.game.running = False def render(self): # 绘制背景 self.game.screen.fill((30, 30, 70)) # 绘制标题 title_font = pygame.font.SysFont(None, 72) title_text = title_font.render(“我的游戏”, True, (255, 255, 255)) title_rect = title_text.get_rect(center=(self.game.screen_width//2, 100)) self.game.screen.blit(title_text, title_rect) # 绘制按钮 for button in self.buttons: # 绘制按钮背景 pygame.draw.rect(self.game.screen, (50, 150, 200), button[‘rect’]) pygame.draw.rect(self.game.screen, (255, 255, 255), button[‘rect’], 3) # 绘制按钮文字 button_font = pygame.font.SysFont(None, 36) button_text = button_font.render(button[‘text’], True, (255, 255, 255)) text_rect = button_text.get_rect(center=button[‘rect’].center) self.game.screen.blit(button_text, text_rect)
- import pygame import sys import random class PlatformGame: def __init__(self): pygame.init() # 屏幕设置 self.WIDTH = 800 self.HEIGHT = 600 self.screen = pygame.display.set_mode((self.WIDTH, self.HEIGHT)) pygame.display.set_caption(“平台跳跃”) # 颜色 self.SKY_BLUE = (135, 206, 235) self.GROUND_COLOR = (101, 67, 33) self.PLATFORM_COLOR = (0, 200, 100) # 游戏状态 self.clock = pygame.time.Clock() self.FPS = 60 self.running = True self.score = 0 self.font = pygame.font.SysFont(None, 36) # 游戏对象 self.player = pygame.Rect(100, 300, 30, 30) self.player_vel_y = 0 self.gravity = 0.8 self.jump_strength = -15 self.on_ground = False # 平台 self.platforms = [ pygame.Rect(0, 500, 800, 100), # 地面 pygame.Rect(200, 400, 200, 20), pygame.Rect(450, 350, 150, 20), pygame.Rect(300, 250, 200, 20), pygame.Rect(100, 200, 150, 20), pygame.Rect(550, 150, 200, 20), ] # 金币 self.coins = [] self.generate_coins() # 敌人 self.enemies = [] self.spawn_timer = 0 self.spawn_interval = 2000 # 毫秒 def generate_coins(self): “””生成金币””” for platform in self.platforms[1:]: # 除了地面 x = random.randint(platform.left + 10, platform.right – 20) y = platform.top – 30 self.coins.append(pygame.Rect(x, y, 15, 15)) def handle_events(self): 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 and self.on_ground: self.player_vel_y = self.jump_strength self.on_ground = False elif event.key == pygame.K_r: # 重新开始 self.__init__() def update(self): # 键盘输入 keys = pygame.key.get_pressed() # 水平移动 player_speed = 5 if keys[pygame.K_LEFT]: self.player.x -= player_speed if keys[pygame.K_RIGHT]: self.player.x += player_speed # 应用重力 self.player_vel_y += self.gravity self.player.y += self.player_vel_y # 边界检查 if self.player.left < 0: self.player.left = 0 if self.player.right > self.WIDTH: self.player.right = self.WIDTH # 平台碰撞检测 self.on_ground = False for platform in self.platforms: if self.player.colliderect(platform): if self.player_vel_y > 0: # 下落 self.player.bottom = platform.top self.player_vel_y = 0 self.on_ground = True elif self.player_vel_y < 0: # 上升 self.player.top = platform.bottom self.player_vel_y = 0 # 金币收集 for coin in self.coins[:]: if self.player.colliderect(coin): self.coins.remove(coin) self.score += 10 # 生成敌人 current_time = pygame.time.get_ticks() if current_time – self.spawn_timer > self.spawn_interval: self.enemies.append(pygame.Rect( random.randint(0, self.WIDTH – 30), -30, 30, 30 )) self.spawn_timer = current_time # 更新敌人 for enemy in self.enemies[:]: enemy.y += 3 if enemy.top > self.HEIGHT: self.enemies.remove(enemy) # 玩家与敌人碰撞 if self.player.colliderect(enemy): self.game_over() def game_over(self): “””游戏结束””” game_over_font = pygame.font.SysFont(None, 72) game_over_text = game_over_font.render(“游戏结束!”, True, (255, 0, 0)) score_text = self.font.render(f”最终得分: {self.score}”, True, (255, 255, 255)) restart_text = self.font.render(“按 R 重新开始”, True, (255, 255, 255)) # 绘制半透明背景 overlay = pygame.Surface((self.WIDTH, self.HEIGHT), pygame.SRCALPHA) overlay.fill((0, 0, 0, 180)) self.screen.blit(overlay, (0, 0)) # 绘制文字 self.screen.blit(game_over_text, (self.WIDTH//2 – game_over_text.get_width()//2, self.HEIGHT//2 – 100)) self.screen.blit(score_text, (self.WIDTH//2 – score_text.get_width()//2, self.HEIGHT//2)) self.screen.blit(restart_text, (self.WIDTH//2 – restart_text.get_width()//2, self.HEIGHT//2 + 50)) pygame.display.flip() # 等待玩家按键 waiting = True while waiting: for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = False waiting = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_r: self.__init__() waiting = False def render(self): # 绘制背景 self.screen.fill(self.SKY_BLUE) # 绘制平台 for platform in self.platforms: pygame.draw.rect(self.screen, self.PLATFORM_COLOR, platform) # 绘制地面 pygame.draw.rect(self.screen, self.GROUND_COLOR, self.platforms[0]) # 绘制金币 for coin in self.coins: pygame.draw.circle(self.screen, (255, 215, 0), coin.center, coin.width//2) # 绘制敌人 for enemy in self.enemies: pygame.draw.rect(self.screen, (255, 0, 0), enemy) # 绘制玩家 pygame.draw.rect(self.screen, (0, 0, 255), self.player) # 绘制分数 score_text = self.font.render(f”分数: {self.score}”, True, (255, 255, 255)) self.screen.blit(score_text, (10, 10)) pygame.display.flip() def run(self): while self.running: self.handle_events() self.update() self.render() self.clock.tick(self.FPS) pygame.quit() sys.exit() if __name__ == “__main__”: game = PlatformGame() game.run()
- # 1. 使用双缓冲 screen = pygame.display.set_mode((width, height), pygame.DOUBLEBUF) # 2. 图像转换优化 image = pygame.image.load(“image.png”).convert() # 普通转换 image = pygame.image.load(“image.png”).convert_alpha() # 带透明度转换 # 3. 脏矩形更新(只更新变化的部分) dirty_rects = [] dirty_rects.append(player.rect) pygame.display.update(dirty_rects) # 4. 对象池(减少对象创建销毁) class ObjectPool: def __init__(self, create_func, max_size=100): self.pool = [] self.create_func = create_func self.max_size = max_size def get(self): if self.pool: return self.pool.pop() return self.create_func() def recycle(self, obj): if len(self.pool) < self.max_size: self.pool.append(obj)
- class StateMachine: def __init__(self): self.states = {} self.current_state = None def add_state(self, name, state): self.states[name] = state def change_state(self, name): if self.current_state: self.current_state.exit() self.current_state = self.states[name] self.current_state.enter() def update(self): if self.current_state: self.current_state.update() def render(self): if self.current_state: self.current_state.render() class GameState: def enter(self): pass def exit(self): pass def update(self): pass def render(self): pass
- class Particle: def __init__(self, x, y): self.x = x self.y = y self.vx = random.uniform(-2, 2) self.vy = random.uniform(-5, -2) self.lifetime = 60 self.color = random.choice([(255, 255, 0), (255, 165, 0)]) def update(self): self.x += self.vx self.y += self.vy self.vy += 0.1 self.lifetime -= 1 def draw(self, screen): radius = max(1, self.lifetime // 15) pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), radius)
目录
- 一、Pygame 核心架构
- 二、完整开发流程详解
- 1.基础框架搭建
- 2.主游戏循环
- 3.精灵系统(Sprite System)
- 4.游戏场景管理
- 5.完整游戏示例:平台跳跃游戏
- 三、最佳实践和优化技巧
- 1.性能优化
- 2.状态机管理
- 3.粒子系统
- 四、调试技巧
- 五、项目结构建议
- 总结
游戏主循环
├── 事件处理 (Event Handling)
├── 游戏逻辑更新 (Game Logic)
├── 渲染绘制 (Rendering)
└── 帧率控制 (FPS Control)
import pygame
import sys
class Game:
def __init__(self):
"""初始化游戏"""
pygame.init()
# 1. 创建游戏窗口
self.screen_width = 800
self.screen_height = 600
self.screen = pygame.display.set_mode(
(self.screen_width, self.screen_height)
)
pygame.display.set_caption("我的游戏")
# 2. 初始化游戏时钟(控制帧率)
self.clock = pygame.time.Clock()
self.FPS = 60
# 3. 游戏状态
self.running = True
self.game_over = False
# 4. 颜色定义(RGB)
self.BLACK = (0, 0, 0)
self.WHITE = (255, 255, 255)
self.RED = (255, 0, 0)
self.GREEN = (0, 255, 0)
self.BLUE = (0, 0, 255)
# 5. 初始化游戏资源
self.load_resources()
def load_resources(self):
"""加载游戏资源"""
# 字体
self.font_small = pygame.font.SysFont(None, 36)
self.font_large = pygame.font.SysFont(None, 72)
# 加载图片
try:
self.player_image = pygame.image.load("player.png").convert_alpha()
except:
# 如果图片不存在,创建一个矩形代替
self.player_image = pygame.Surface((50, 50))
self.player_image.fill(self.BLUE)
# 加载音效
try:
self.jump_sound = pygame.mixer.Sound("jump.wav")
except:
self.jump_sound = None
# 背景音乐
pygame.mixer.music.load("bgm.mp3")
pygame.mixer.music.play(-1) # -1表示循环播放
def run(self):
"""主游戏循环"""
while self.running:
# 1. 处理事件
self.handle_events()
# 2. 更新游戏状态(只有游戏没结束时才更新)
if not self.game_over:
self.update()
# 3. 绘制画面
self.render()
# 4. 控制帧率
self.clock.tick(self.FPS)
# 游戏结束,退出
self.quit()
def handle_events(self):
"""事件处理"""
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
# 键盘按下事件
elif event.type == pygame.KEYDOWN:
self.on_key_down(event.key)
# 键盘释放事件
elif event.type == pygame.KEYUP:
self.on_key_up(event.key)
# 鼠标事件
elif event.type == pygame.MOUSEBUTTONDOWN:
self.on_mouse_click(event.pos, event.button)
class Player(pygame.sprite.Sprite):
"""玩家角色类"""
def __init__(self, x, y):
super().__init__()
# 创建图像和矩形
self.image = pygame.Surface((50, 50))
self.image.fill((0, 0, 255))
# 加载动画帧
self.frames = []
self.load_animation_frames()
self.current_frame = 0
self.animation_speed = 0.2
self.animation_timer = 0
self.rect = self.image.get_rect()
self.rect.center = (x, y)
# 物理属性
self.velocity = pygame.Vector2(0, 0)
self.speed = 5
self.jump_power = -15
self.gravity = 0.8
self.on_ground = False
# 游戏属性
self.health = 100
self.score = 0
def load_animation_frames(self):
"""加载动画帧"""
for i in range(4):
frame = pygame.Surface((50, 50))
frame.fill((0, 0, 200 + i * 15))
self.frames.append(frame)
def update(self, platforms):
"""更新玩家状态"""
# 处理用户输入
keys = pygame.key.get_pressed()
# 水平移动
self.velocity.x = 0
if keys[pygame.K_LEFT]:
self.velocity.x = -self.speed
if keys[pygame.K_RIGHT]:
self.velocity.x = self.speed
# 跳跃
if keys[pygame.K_SPACE] and self.on_ground:
self.velocity.y = self.jump_power
self.on_ground = False
# 应用重力
self.velocity.y += self.gravity
# 水平移动
self.rect.x += self.velocity.x
# 水平碰撞检测
self.check_horizontal_collision(platforms)
# 垂直移动
self.rect.y += self.velocity.y
# 垂直碰撞检测
self.check_vertical_collision(platforms)
# 更新动画
self.update_animation()
# 边界检查
self.check_bounds()
def check_horizontal_collision(self, platforms):
for platform in platforms:
if self.rect.colliderect(platform):
if self.velocity.x > 0: # 向右移动
self.rect.right = platform.left
elif self.velocity.x < 0: # 向左移动
self.rect.left = platform.right
def check_vertical_collision(self, platforms):
self.on_ground = False
for platform in platforms:
if self.rect.colliderect(platform):
if self.velocity.y > 0: # 向下移动
self.rect.bottom = platform.top
self.velocity.y = 0
self.on_ground = True
elif self.velocity.y < 0: # 向上移动
self.rect.top = platform.bottom
self.velocity.y = 0
def update_animation(self):
"""更新动画帧"""
self.animation_timer += self.animation_speed
if self.animation_timer >= 1:
self.current_frame = (self.current_frame + 1) % len(self.frames)
self.image = self.frames[self.current_frame]
self.animation_timer = 0
def check_bounds(self):
"""检查边界"""
if self.rect.top > 600: # 掉落屏幕
self.health = 0
class GameScene:
"""游戏场景基类"""
def __init__(self, game):
self.game = game
def handle_events(self):
pass
def update(self):
pass
def render(self):
pass
class MainMenuScene(GameScene):
"""主菜单场景"""
def __init__(self, game):
super().__init__(game)
self.buttons = []
self.create_buttons()
def create_buttons(self):
"""创建菜单按钮"""
button_width, button_height = 200, 50
# 开始游戏按钮
start_rect = pygame.Rect(
self.game.screen_width // 2 - button_width // 2,
200,
button_width,
button_height
)
self.buttons.append({
'rect': start_rect,
'text': '开始游戏',
'action': self.start_game
})
# 退出游戏按钮
quit_rect = pygame.Rect(
self.game.screen_width // 2 - button_width // 2,
280,
button_width,
button_height
)
self.buttons.append({
'rect': quit_rect,
'text': '退出游戏',
'action': self.quit_game
})
def handle_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.game.running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # 左键
self.check_button_click(event.pos)
def check_button_click(self, pos):
"""检查按钮点击"""
for button in self.buttons:
if button['rect'].collidepoint(pos):
button['action']()
def start_game(self):
"""切换到游戏场景"""
self.game.current_scene = GamePlayScene(self.game)
def quit_game(self):
self.game.running = False
def render(self):
# 绘制背景
self.game.screen.fill((30, 30, 70))
# 绘制标题
title_font = pygame.font.SysFont(None, 72)
title_text = title_font.render("我的游戏", True, (255, 255, 255))
title_rect = title_text.get_rect(center=(self.game.screen_width//2, 100))
self.game.screen.blit(title_text, title_rect)
# 绘制按钮
for button in self.buttons:
# 绘制按钮背景
pygame.draw.rect(self.game.screen, (50, 150, 200), button['rect'])
pygame.draw.rect(self.game.screen, (255, 255, 255), button['rect'], 3)
# 绘制按钮文字
button_font = pygame.font.SysFont(None, 36)
button_text = button_font.render(button['text'], True, (255, 255, 255))
text_rect = button_text.get_rect(center=button['rect'].center)
self.game.screen.blit(button_text, text_rect)
import pygame
import sys
import random
class PlatformGame:
def __init__(self):
pygame.init()
# 屏幕设置
self.WIDTH = 800
self.HEIGHT = 600
self.screen = pygame.display.set_mode((self.WIDTH, self.HEIGHT))
pygame.display.set_caption("平台跳跃")
# 颜色
self.SKY_BLUE = (135, 206, 235)
self.GROUND_COLOR = (101, 67, 33)
self.PLATFORM_COLOR = (0, 200, 100)
# 游戏状态
self.clock = pygame.time.Clock()
self.FPS = 60
self.running = True
self.score = 0
self.font = pygame.font.SysFont(None, 36)
# 游戏对象
self.player = pygame.Rect(100, 300, 30, 30)
self.player_vel_y = 0
self.gravity = 0.8
self.jump_strength = -15
self.on_ground = False
# 平台
self.platforms = [
pygame.Rect(0, 500, 800, 100), # 地面
pygame.Rect(200, 400, 200, 20),
pygame.Rect(450, 350, 150, 20),
pygame.Rect(300, 250, 200, 20),
pygame.Rect(100, 200, 150, 20),
pygame.Rect(550, 150, 200, 20),
]
# 金币
self.coins = []
self.generate_coins()
# 敌人
self.enemies = []
self.spawn_timer = 0
self.spawn_interval = 2000 # 毫秒
def generate_coins(self):
"""生成金币"""
for platform in self.platforms[1:]: # 除了地面
x = random.randint(platform.left + 10, platform.right - 20)
y = platform.top - 30
self.coins.append(pygame.Rect(x, y, 15, 15))
def handle_events(self):
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 and self.on_ground:
self.player_vel_y = self.jump_strength
self.on_ground = False
elif event.key == pygame.K_r: # 重新开始
self.__init__()
def update(self):
# 键盘输入
keys = pygame.key.get_pressed()
# 水平移动
player_speed = 5
if keys[pygame.K_LEFT]:
self.player.x -= player_speed
if keys[pygame.K_RIGHT]:
self.player.x += player_speed
# 应用重力
self.player_vel_y += self.gravity
self.player.y += self.player_vel_y
# 边界检查
if self.player.left < 0:
self.player.left = 0
if self.player.right > self.WIDTH:
self.player.right = self.WIDTH
# 平台碰撞检测
self.on_ground = False
for platform in self.platforms:
if self.player.colliderect(platform):
if self.player_vel_y > 0: # 下落
self.player.bottom = platform.top
self.player_vel_y = 0
self.on_ground = True
elif self.player_vel_y < 0: # 上升
self.player.top = platform.bottom
self.player_vel_y = 0
# 金币收集
for coin in self.coins[:]:
if self.player.colliderect(coin):
self.coins.remove(coin)
self.score += 10
# 生成敌人
current_time = pygame.time.get_ticks()
if current_time - self.spawn_timer > self.spawn_interval:
self.enemies.append(pygame.Rect(
random.randint(0, self.WIDTH - 30),
-30,
30, 30
))
self.spawn_timer = current_time
# 更新敌人
for enemy in self.enemies[:]:
enemy.y += 3
if enemy.top > self.HEIGHT:
self.enemies.remove(enemy)
# 玩家与敌人碰撞
if self.player.colliderect(enemy):
self.game_over()
def game_over(self):
"""游戏结束"""
game_over_font = pygame.font.SysFont(None, 72)
game_over_text = game_over_font.render("游戏结束!", True, (255, 0, 0))
score_text = self.font.render(f"最终得分: {self.score}", True, (255, 255, 255))
restart_text = self.font.render("按 R 重新开始", True, (255, 255, 255))
# 绘制半透明背景
overlay = pygame.Surface((self.WIDTH, self.HEIGHT), pygame.SRCALPHA)
overlay.fill((0, 0, 0, 180))
self.screen.blit(overlay, (0, 0))
# 绘制文字
self.screen.blit(game_over_text,
(self.WIDTH//2 - game_over_text.get_width()//2,
self.HEIGHT//2 - 100))
self.screen.blit(score_text,
(self.WIDTH//2 - score_text.get_width()//2,
self.HEIGHT//2))
self.screen.blit(restart_text,
(self.WIDTH//2 - restart_text.get_width()//2,
self.HEIGHT//2 + 50))
pygame.display.flip()
# 等待玩家按键
waiting = True
while waiting:
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
waiting = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_r:
self.__init__()
waiting = False
def render(self):
# 绘制背景
self.screen.fill(self.SKY_BLUE)
# 绘制平台
for platform in self.platforms:
pygame.draw.rect(self.screen, self.PLATFORM_COLOR, platform)
# 绘制地面
pygame.draw.rect(self.screen, self.GROUND_COLOR, self.platforms[0])
# 绘制金币
for coin in self.coins:
pygame.draw.circle(self.screen, (255, 215, 0), coin.center, coin.width//2)
# 绘制敌人
for enemy in self.enemies:
pygame.draw.rect(self.screen, (255, 0, 0), enemy)
# 绘制玩家
pygame.draw.rect(self.screen, (0, 0, 255), self.player)
# 绘制分数
score_text = self.font.render(f"分数: {self.score}", True, (255, 255, 255))
self.screen.blit(score_text, (10, 10))
pygame.display.flip()
def run(self):
while self.running:
self.handle_events()
self.update()
self.render()
self.clock.tick(self.FPS)
pygame.quit()
sys.exit()
if __name__ == "__main__":
game = PlatformGame()
game.run()
# 1. 使用双缓冲
screen = pygame.display.set_mode((width, height), pygame.DOUBLEBUF)
# 2. 图像转换优化
image = pygame.image.load("image.png").convert() # 普通转换
image = pygame.image.load("image.png").convert_alpha() # 带透明度转换
# 3. 脏矩形更新(只更新变化的部分)
dirty_rects = []
dirty_rects.append(player.rect)
pygame.display.update(dirty_rects)
# 4. 对象池(减少对象创建销毁)
class ObjectPool:
def __init__(self, create_func, max_size=100):
self.pool = []
self.create_func = create_func
self.max_size = max_size
def get(self):
if self.pool:
return self.pool.pop()
return self.create_func()
def recycle(self, obj):
if len(self.pool) < self.max_size:
self.pool.append(obj)
class StateMachine:
def __init__(self):
self.states = {}
self.current_state = None
def add_state(self, name, state):
self.states[name] = state
def change_state(self, name):
if self.current_state:
self.current_state.exit()
self.current_state = self.states[name]
self.current_state.enter()
def update(self):
if self.current_state:
self.current_state.update()
def render(self):
if self.current_state:
self.current_state.render()
class GameState:
def enter(self):
pass
def exit(self):
pass
def update(self):
pass
def render(self):
pass
class Particle:
def __init__(self, x, y):
self.x = x
self.y = y
self.vx = random.uniform(-2, 2)
self.vy = random.uniform(-5, -2)
self.lifetime = 60
self.color = random.choice([(255, 255, 0), (255, 165, 0)])
def update(self):
self.x += self.vx
self.y += self.vy
self.vy += 0.1
self.lifetime -= 1
def draw(self, screen):
radius = max(1, self.lifetime // 15)
pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), radius)
- 显示帧率
fps_text = font.render(f"FPS: {int(clock.get_fps())}", True, WHITE)
- 显示调试信息
def draw_debug_info():
debug_info = [
f"玩家位置: ({player.rect.x}, {player.rect.y})",
f"速度: ({player.velocity.x:.1f}, {player.velocity.y:.1f})",
f"金币数量: {len(coins)}",
f"敌人数量: {len(enemies)}"
]
for i, info in enumerate(debug_info):
text = font.render(info, True, WHITE)
screen.blit(text, (10, 30 + i * 25))
- 碰撞框显示
pygame.draw.rect(screen, (255, 0, 0), object.rect, 2) # 红色边框
my_game/
├── main.py # 游戏主入口
├── game.py # 游戏主类
├── player.py # 玩家类
├── enemy.py # 敌人类
├── platform.py # 平台类
├── powerup.py # 道具类
├── scene/
│ ├── menu_scene.py # 菜单场景
│ ├── game_scene.py # 游戏场景
│ └── game_over_scene.py
├── assets/
│ ├── images/
│ ├── sounds/
│ └── fonts/
├── config.py # 配置文件
└── utils.py # 工具函数
按照这个流程,你可以从简单到复杂逐步开发完整的Pygame游戏。记住:先实现核心玩法,再添加特效和优化!
到此这篇关于Pygame开发游戏详细流程记录的文章就介绍到这了,更多相关Pygame开发游戏内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!
您可能感兴趣的文章:
- 使用python+pygame开发消消乐游戏附完整源码
- pygame实现雷电游戏雏形开发
- Pygame游戏开发之太空射击实战子弹与碰撞处理篇
- Pygame游戏开发实例讲解之图形绘制与键鼠事件
- Pygame游戏开发之太空射击实战入门篇
- Pygame游戏开发之太空射击实战敌人精灵篇