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

如何让PumpBomb_Exp重复3-5次或持续10-15秒?while循环失效求助

手雷爆炸特效重复触发问题与解决

问题说明

需要在游戏环境中实现PumpBomb_Exp(手雷爆炸效果方法)重复执行3-5次,或让特效持续显示10-15秒。尝试用while循环实现,但游戏测试中特效未重复触发,无预期效果。

原代码核心问题

你写的while循环存在两个致命问题:

  1. 变量名冲突:外层while循环的计数器i,被内部for循环的new i = 0覆盖(Pawn语言中new会创建局部变量),导致外层i永远保持初始值1,循环逻辑完全失效。
  2. 同步循环阻塞帧:游戏是单线程运行,同步while循环会一次性执行所有特效代码,玩家视觉上只会看到一次效果,还会阻塞游戏线程导致卡顿。

解决方案:使用异步定时器

游戏开发中重复触发特效必须用异步定时器,避免阻塞主线程,同时实现间隔触发。以下是修改思路和代码示例:

1. 拆分逻辑,避免重复伤害

把爆炸伤害计算放在第一次触发时执行,后续仅重复显示特效,防止多次攻击玩家。

2. 用set_task创建定时任务

通过AMX Mod X的set_task函数,每隔指定时间(比如2秒)触发一次特效,重复3-5次即可覆盖10-15秒的持续时间。

修改后代码示例

// 主爆炸函数:执行伤害+首次特效,启动定时任务
public PumpBomb_Exp(Ent, Float:Origin[3], Owner, Team)
{
    // 仅执行一次伤害计算
    static Float:PlayerOrigin[3]
    for(new idx = 0; idx < g_MaxPlayers; idx++)
    {
        if(!is_user_alive(idx))
            continue
        if(get_player_team(idx) == Team)
            continue
        pev(idx, pev_origin, PlayerOrigin)
        if(get_distance_f(Origin, PlayerOrigin) > PUMPKIN_RADIUS)
            continue
            
        if(!is_user_connected(Owner)) Owner = idx
        ExecuteHamB(Ham_TakeDamage, idx, "grenade", Owner, PUMPKIN_DAMAGE, DMG_CRUSH)
    }

    // 首次音效与特效
    emit_sound(Ent, CHAN_BODY, WeaponSounds[0], 1.0, ATTN_NORM, 0, PITCH_NORM)
    static Float:flOrigin[3]
    pev(Ent, pev_origin, flOrigin)
    engfunc(EngFunc_EmitSound, Ent, CHAN_WEAPON, g_soundexpl, 1.0, ATTN_NORM, 0, PITCH_NORM)
    DrawExplosionEffects(flOrigin)

    // 启动定时任务:每隔2秒触发一次,重复4次(总共5次),持续10秒
    new params[12];
    params[0] = Ent;
    memcpy(params[1], Origin, sizeof(Origin));
    set_task(2.0, "Task_RepeatExplosion", _, params, sizeof(params), "a", 4);
}

// 定时触发的特效函数
public Task_RepeatExplosion(params[])
{
    new Ent = params[0];
    Float:Origin[3];
    memcpy(Origin, params[1], sizeof(Origin));

    // 重复音效
    emit_sound(Ent, CHAN_BODY, WeaponSounds[0], 1.0, ATTN_NORM, 0, PITCH_NORM)
    static Float:flOrigin[3]
    pev(Ent, pev_origin, flOrigin)
    engfunc(EngFunc_EmitSound, Ent, CHAN_WEAPON, g_soundexpl, 1.0, ATTN_NORM, 0, PITCH_NORM)

    // 绘制爆炸特效
    DrawExplosionEffects(flOrigin)
}

// 抽离的特效绘制函数,复用代码
stock DrawExplosionEffects(Float:flOrigin[3])
{
    // 爆炸特效1
    message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
    write_byte(TE_EXPLOSION)
    engfunc(EngFunc_WriteCoord, flOrigin[0])
    engfunc(EngFunc_WriteCoord, flOrigin[1])
    engfunc(EngFunc_WriteCoord, flOrigin[2] + 16.0)
    write_short(g_Exp_SprId)
    write_byte(50)  // 缩放比例(单位0.1)
    write_byte(30)  // 帧率
    write_byte(4)   // 标志位
    message_end()

    // 爆炸特效2
    engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flOrigin, 0)
    write_byte(TE_EXPLOSION)
    engfunc(EngFunc_WriteCoord, flOrigin[0])
    engfunc(EngFunc_WriteCoord, flOrigin[1])
    engfunc(EngFunc_WriteCoord, flOrigin[2]+50.0)
    write_short(spriteexpl)
    write_byte(30)
    write_byte(10)
    write_byte(0)
    message_end()

    // 灯光特效
    message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
    write_byte(TE_DLIGHT)
    engfunc(EngFunc_WriteCoord, flOrigin[0])
    engfunc(EngFunc_WriteCoord, flOrigin[1])
    engfunc(EngFunc_WriteCoord, flOrigin[2])
    write_byte(45)//半径
    write_byte(250) // 红
    write_byte(150) // 绿
    write_byte(50)  // 蓝
    write_byte(15)  // 生命周期
    write_byte(10)
    message_end()

    // 贴花特效
    engfunc(EngFunc_MessageBegin, MSG_PAS, SVC_TEMPENTITY, flOrigin, 0)
    write_byte(TE_WORLDDECAL)
    engfunc(EngFunc_WriteCoord, flOrigin[0])
    engfunc(EngFunc_WriteCoord, flOrigin[1])
    engfunc(EngFunc_WriteCoord, flOrigin[2])
    write_byte(engfunc(EngFunc_DecalIndex,"{scorch3"))
    message_end()

    // 环形特效1
    engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flOrigin, 0)
    write_byte(TE_BEAMCYLINDER) // TE标识
    engfunc(EngFunc_WriteCoord, flOrigin[0])    // x坐标
    engfunc(EngFunc_WriteCoord, flOrigin[1])    // y坐标
    engfunc(EngFunc_WriteCoord, flOrigin[2])    // z坐标
    engfunc(EngFunc_WriteCoord, flOrigin[0])    // x轴
    engfunc(EngFunc_WriteCoord, flOrigin[1])    // y轴
    engfunc(EngFunc_WriteCoord, flOrigin[2] + 35)   // z轴
    write_short(g_sprRing)  // 精灵
    write_byte(0)   // 起始帧
    write_byte(0)   // 帧率
    write_byte(10)  // 生命周期
    write_byte(65)  // 宽度
    write_byte(0)   // 噪点
    write_byte(255)     // 红
    write_byte(155)     // 绿
    write_byte(55)  // 蓝
    write_byte(200)     // 亮度
    write_byte(0)   // 速度
    message_end()

    // 环形特效2
    engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flOrigin, 0)
    write_byte(TE_BEAMCYLINDER)         // TE标识
    engfunc(EngFunc_WriteCoord, flOrigin[0])        // x坐标
    engfunc(EngFunc_WriteCoord, flOrigin[1])        // y坐标
    engfunc(EngFunc_WriteCoord, flOrigin[2])        // z坐标
    engfunc(EngFunc_WriteCoord, flOrigin[0])        // x轴
    engfunc(EngFunc_WriteCoord, flOrigin[1])        // y轴
    engfunc(EngFunc_WriteCoord, flOrigin[2] + 65)   // z轴
    write_short(g_sprRing)  // 精灵
    write_byte(0)       // 起始帧
    write_byte(0)       // 帧率
    write_byte(10)      // 生命周期
    write_byte(35)      // 宽度
    write_byte(0)       // 噪点
    write_byte(255)     // 红
    write_byte(155)     // 绿
    write_byte(55)      // 蓝
    write_byte(200)     // 亮度
    write_byte(0)       // 速度
    message_end()

    // 环形特效3
    engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flOrigin, 0)
    write_byte(TE_BEAMCYLINDER)         // TE标识
    engfunc(EngFunc_WriteCoord, flOrigin[0])        // x坐标
    engfunc(EngFunc_WriteCoord, flOrigin[1])        // y坐标
    engfunc(EngFunc_WriteCoord, flOrigin[2])        // z坐标
    engfunc(EngFunc_WriteCoord, flOrigin[0])        // x轴
    engfunc(EngFunc_WriteCoord, flOrigin[1])        // y轴
    engfunc(EngFunc_WriteCoord, flOrigin[2] + 95)   // z轴
    write_short(g_sprRing)  // 精灵
    write_byte(0)       // 起始帧
    write_byte(0)       // 帧率
    write_byte(10)      // 生命周期
    write_byte(15)      // 宽度
    write_byte(0)       // 噪点
    write_byte(255)         // 红
    write_byte(155)         // 绿
    write_byte(55)      // 蓝
    write_byte(200)         // 亮度
    write_byte(0)       // 速度
    message_end()
}

关键修改点

  • 抽离DrawExplosionEffects函数,复用特效代码,减少冗余。
  • 使用set_task异步触发特效,参数"a", 4表示重复4次(加上首次共5次),间隔2秒,总时长10秒。
  • 伤害计算仅执行一次,避免重复攻击玩家。
  • 修复变量名冲突问题,将内部循环计数器改为idx,避免覆盖外层变量。

内容的提问来源于stack exchange,提问作者Tech2cool

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 09:50:24