如何在Pygame中仅暂停if语句而不阻塞整个脚本?
Pygame 无敌帧伤害系统实现方案
直接用time.sleep()会卡死整个游戏循环——它会阻塞主线程,让所有渲染、事件处理彻底停摆。Pygame本身自带时间工具,用它实现无敌帧才是正确姿势,完全不需要async或threading,具体方案如下:
核心思路
用pygame.time.get_ticks()记录角色最后一次受击的时间戳,每次检测碰撞前,先判断当前时间与最后受击时间的差值是否超过无敌帧时长,只有满足条件才触发伤害逻辑。
完整代码示例
import pygame pygame.init() # 初始化游戏窗口 screen = pygame.display.set_mode((800, 600)) clock = pygame.time.Clock() # 角色与敌人碰撞矩形 player_rect = pygame.Rect(400, 300, 50, 50) baddude_rect = pygame.Rect(200, 300, 50, 50) # 无敌帧核心变量 invincibility_duration = 500 # 无敌帧时长,单位毫秒 last_hit_time = 0 # 最后一次受击的时间戳 running = True while running: screen.fill((0, 0, 0)) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 获取当前时间戳 current_time = pygame.time.get_ticks() # 碰撞检测+无敌帧判断 if player_rect.colliderect(baddude_rect): # 仅当当前时间与上次受击时间差超过无敌帧时长时,触发伤害 if current_time - last_hit_time > invincibility_duration: print('hit') last_hit_time = current_time # 更新受击时间戳 # 此处可添加扣血逻辑,例如: # player_health -= 10 # 绘制角色与敌人 pygame.draw.rect(screen, (0, 255, 0), player_rect) pygame.draw.rect(screen, (255, 0, 0), baddude_rect) pygame.display.flip() clock.tick(60) pygame.quit()
可选优化:无敌帧视觉反馈
如果要让玩家直观感知无敌状态,可以在无敌期间让角色闪烁:
# 替换原绘制角色的代码 if current_time - last_hit_time < invincibility_duration: # 每隔100毫秒切换一次可见性,实现闪烁效果 if (current_time // 100) % 2 == 0: pygame.draw.rect(screen, (0, 255, 0), player_rect) else: pygame.draw.rect(screen, (0, 255, 0), player_rect)
这种方法完全在主线程的游戏循环内处理,不会出现阻塞或线程同步问题,是Pygame中实现无敌帧的标准做法。
内容的提问来源于stack exchange,提问作者redninja
相关产品推荐
相关产品推荐

