Pygame僵尸生存游戏:修复P键商店动画与暂停冲突问题
修复Pygame僵尸生存商店卡顿与暂停逻辑问题
核心解决思路
用状态机模式明确区分游戏的不同阶段,严格控制P键的响应时机,同时用时间驱动的动画/倒计时逻辑替代帧率依赖的实现,彻底解决按住P键反复切换导致的卡顿问题。
具体代码修改步骤
1. 定义游戏状态常量
先在代码开头添加状态枚举,清晰划分游戏阶段:
# 游戏状态定义 GAME_RUNNING = "running" SHOP_OPENING = "shop_opening" SHOP_OPEN = "shop_open" SHOP_CLOSING = "shop_closing" COUNTDOWN = "countdown"
2. 初始化状态与动画变量
在游戏初始化部分添加这些变量,控制商店位置、动画进度和倒计时:
import pygame import sys pygame.init() screen_width, screen_height = 800, 600 screen = pygame.display.set_mode((screen_width, screen_height)) font = pygame.font.Font(None, 100) # 用于倒计时文本 # 状态与动画变量 game_state = GAME_RUNNING shop_animation_duration = 500 # 商店弹出/收回动画时长(毫秒) countdown_duration = 3000 # 倒计时时长(3秒) shop_x = -400 # 商店初始位置(屏幕外左侧,假设商店宽度400) animation_start_time = 0 # 动画开始时间戳 countdown_start_time = 0 # 倒计时开始时间戳
3. 修改事件循环的P键处理逻辑
只在允许的状态下响应P键的KEYDOWN事件(避免按住重复触发):
while True: 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_p: # 只有在游戏运行中或商店已打开时,才响应P键 if game_state == GAME_RUNNING: game_state = SHOP_OPENING animation_start_time = pygame.time.get_ticks() elif game_state == SHOP_OPEN: game_state = SHOP_CLOSING animation_start_time = pygame.time.get_ticks()
4. 实现动画与状态切换逻辑
用pygame.time.get_ticks()计算时间差,驱动动画和状态过渡:
current_time = pygame.time.get_ticks() # 商店弹出动画逻辑 if game_state == SHOP_OPENING: elapsed = current_time - animation_start_time if elapsed >= shop_animation_duration: shop_x = 0 # 商店完全弹出到屏幕左侧 game_state = SHOP_OPEN else: # 线性插值计算商店位置,实现平滑动画 shop_x = -400 + (400 * (elapsed / shop_animation_duration)) # 商店收回动画逻辑 elif game_state == SHOP_CLOSING: elapsed = current_time - animation_start_time if elapsed >= shop_animation_duration: shop_x = -400 # 商店完全收回至屏幕外 game_state = COUNTDOWN countdown_start_time = current_time else: shop_x = 0 - (400 * (elapsed / shop_animation_duration)) # 倒计时逻辑 elif game_state == COUNTDOWN: elapsed = current_time - countdown_start_time if elapsed >= countdown_duration: game_state = GAME_RUNNING else: # 计算剩余倒计时秒数(向下取整) countdown_seconds = 3 - (elapsed // 1000)
5. 渲染游戏内容
根据当前状态绘制对应内容,并且仅在GAME_RUNNING状态更新游戏逻辑:
# 游戏逻辑更新(仅在运行状态执行) if game_state == GAME_RUNNING: # 这里写玩家移动、僵尸生成、碰撞检测等原有逻辑 pass # 绘制背景 screen.fill((30, 30, 30)) # 绘制商店(弹出/收回/打开状态都显示) if game_state in (SHOP_OPENING, SHOP_OPEN, SHOP_CLOSING): # 替换成你的商店表面绘制代码,示例用红色矩形代替 pygame.draw.rect(screen, (0, 100, 200), (shop_x, 0, 400, screen_height)) # 绘制倒计时 if game_state == COUNTDOWN: countdown_text = font.render(str(countdown_seconds), True, (255, 0, 0)) text_rect = countdown_text.get_rect(center=(screen_width//2, screen_height//2)) screen.blit(countdown_text, text_rect) pygame.display.flip()
关键修复点说明
- 状态隔离:动画过程(
SHOP_OPENING/SHOP_CLOSING)和倒计时阶段(COUNTDOWN)完全忽略P键输入,彻底解决按住P反复切换的问题。 - 按键事件触发:仅响应
KEYDOWN事件,而非key.get_pressed(),避免按住按键时重复触发状态切换。 - 时间驱动动画:用时间差计算动画进度,不依赖帧率,动画效果更稳定,适配不同性能的设备。
内容的提问来源于stack exchange,提问作者Emmanuel_exe
相关产品推荐
相关产品推荐

