You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 04:06:25