如何在Pygame中实现invincibility timer?含优化方案咨询
星星无敌道具的Pygame实现方案
更优实现思路
直接全局关闭所有碰撞检测不是最佳选择——这会导致玩家与道具、场景边界的必要碰撞也失效,破坏游戏逻辑。更合理的做法是:
- 给玩家添加
invincible状态标记,仅在无敌期间跳过玩家与危险对象(敌人、陷阱等)的碰撞判定,保留其他必要碰撞(比如捡道具、边界限制) - 加入视觉反馈(比如玩家闪烁),让玩家清晰感知无敌状态
代码实现
基础版(全局关闭碰撞,不推荐)
如果确实需要全局关闭碰撞,可以通过状态标记控制所有碰撞检测的执行:
import pygame pygame.init() screen = pygame.display.set_mode((800, 600)) player = pygame.Rect(100, 100, 50, 50) star = pygame.Rect(300, 300, 30, 30) enemies = [pygame.Rect(500, 200, 40, 40), pygame.Rect(200, 400, 40, 40)] invincible = False invincibility_end_time = 0 clock = pygame.time.Clock() running = True while running: dt = clock.tick(60) / 1000 current_time = pygame.time.get_ticks() / 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 -= 300 * dt if keys[pygame.K_RIGHT]: player.x += 300 * dt if keys[pygame.K_UP]: player.y -= 300 * dt if keys[pygame.K_DOWN]: player.y += 300 * dt # 检测星星碰撞,触发无敌 if player.colliderect(star): invincible = True invincibility_end_time = current_time + 5 star.x = -100 # 隐藏已拾取的星星 # 到期关闭无敌状态 if invincible and current_time >= invincibility_end_time: invincible = False # 仅非无敌时执行所有碰撞检测 if not invincible: for enemy in enemies: if player.colliderect(enemy): print("玩家受到伤害") # 此处添加受伤逻辑(如减血、死亡判定) # 绘制元素 screen.fill((0, 0, 0)) pygame.draw.rect(screen, (255, 255, 0), star) pygame.draw.rect(screen, (0, 255, 0), player) for enemy in enemies: pygame.draw.rect(screen, (255, 0, 0), enemy) pygame.display.flip() pygame.quit()
优化版(选择性碰撞+视觉反馈)
这是更推荐的实现方式,保留必要碰撞的同时,通过状态控制危险碰撞:
import pygame pygame.init() screen = pygame.display.set_mode((800, 600)) player = pygame.Rect(100, 100, 50, 50) star = pygame.Rect(300, 300, 30, 30) enemies = [pygame.Rect(500, 200, 40, 40), pygame.Rect(200, 400, 40, 40)] invincible = False invincibility_end_time = 0 clock = pygame.time.Clock() blink_timer = 0 blink_visible = True running = True while running: dt = clock.tick(60) / 1000 current_time = pygame.time.get_ticks() / 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 -= 300 * dt if keys[pygame.K_RIGHT]: player.x += 300 * dt if keys[pygame.K_UP]: player.y -= 300 * dt if keys[pygame.K_DOWN]: player.y += 300 * dt # 保留边界碰撞,防止玩家出界 player.clamp_ip(screen.get_rect()) # 始终保留道具碰撞检测,不影响拾取其他道具 if player.colliderect(star): invincible = True invincibility_end_time = current_time + 5 star.x = -100 # 更新无敌状态与闪烁效果 if invincible: if current_time >= invincibility_end_time: invincible = False # 每0.2秒切换玩家可见性,实现闪烁 blink_timer += dt if blink_timer >= 0.2: blink_visible = not blink_visible blink_timer = 0 else: blink_visible = True # 仅非无敌时检测玩家与敌人的碰撞 if not invincible: for enemy in enemies: if player.colliderect(enemy): print("玩家受伤") # 添加受伤逻辑 # 绘制 screen.fill((0, 0, 0)) pygame.draw.rect(screen, (255, 255, 0), star) # 无敌时闪烁显示玩家 if blink_visible: pygame.draw.rect(screen, (0, 255, 0), player) for enemy in enemies: pygame.draw.rect(screen, (255, 0, 0), enemy) pygame.display.flip() pygame.quit()
内容的提问来源于stack exchange,提问作者Rohit Sangishetty
相关产品推荐
相关产品推荐

