找回密码
 点一下
查看: 1357|回复: 14

关于创建异步技能的问题,感谢zhuzeitou。

[复制链接]
发表于 2008-2-22 11:57:22 | 显示全部楼层 |阅读模式
想用触发或者JASS创建一个技能,该技能具有如下特点:

该技能的关键在于:可以让多个单位同时的使用该技能。而互不影像各自释放区域中的效果。

我一开始的做法是:

触发器1(当单位开始释放一个魔法
       事件:当一个单位开始释放魔法
       条件:所释放的魔法是指定的魔法
       动作:保存释放魔法的目标区域到一个全局变量
                   打开一个用于创建效果的定时触发器(触发器2)。
触发器2(每隔n毫秒)(默认关闭的)
       事件:每隔n毫秒
       条件:(无)
       动作:获取保存在全局变量中的区域
                   在这个区域中创建一个指定的特效
                   延时x秒
                   销毁这个特效
触发器3(当单位停止释放一个魔法)
         事件:当一个单位停止释放魔法
         条件:所释放的魔法是指定的魔法
         动作:停止触发器2

如果某一时刻这个游戏中只有一个单位释放魔法,而且再释放过程中不会有其他单位释放同样的魔法,这样做的确可以很好的工作,但是,一旦一个单位释放了魔法,还没有释放完成的时候,另一个单位又释放了该魔法,那么,全局变量中的区域就会改变,那么第一个释放魔法的目标区域将不再有效果。。。而且,一旦第一个释放魔法的单位停止了魔法的释放,那么第二个单位的魔法效果也会停止,因为触发器2被关闭了。

后来,我又更换了做法。
思路是,将创建魔法效果的动作放到一个函数中。如下:

函数1:
          function 创建魔法效果的函数 takes rect rtTeget returns nothing
                  // .............Some Other Code...............
                 //创建一系列的效果并且延时

          endfunction
触发器1(当单位开始释放一个魔法)
       事件:当一个单位开始释放魔法
       条件:所释放的魔法是指定的魔法
       动作:保存释放魔法的目标区域到一个局部变量
                  call 创建魔法效果的函数(目标区域的局部变量

这样做,的确可以让多个单位同时释放魔法而不会相互影像了!!!!!!
但是,新的问题又来了:

魔法如何停止呢???
触发器3(当单位停止释放一个魔法)
         事件:当一个单位停止释放魔法
         条件:所释放的魔法是指定的魔法
         动作:这里我该怎么写呢????????

希望高手能予以解答,谢谢!!!!!!!!!
 楼主| 发表于 2008-2-22 12:07:46 | 显示全部楼层
接着来。

有朋友可能会说,在创建魔法效果的函数里面做上恰当的延时,使得魔法效果得生命周期和技能得释放周期差不多不就行了???

但是,假如说是玩家人为的移动了魔法释放单位,而停止了魔法的释放呢??例如,我刚控制大法师释放了暴风雪,发现有一群敌人K我,我逃!!暴风雪技能随之被打断。
这时,魔法虽然停止了,那个效果却还在继续。。。。
回复

使用道具 举报

发表于 2008-2-22 12:10:20 | 显示全部楼层
如果是我的话,我会用缓存+计时器来做
回复

使用道具 举报

发表于 2008-2-22 12:15:30 | 显示全部楼层
你看~~最简单的方案是~~把每隔XXX时间创建特效这个触发动态处理~~

每释放一个法术就生成一个对应的这种触发~~每停止一个法术就销毁其相应的触发就行了嘛~~
回复

使用道具 举报

 楼主| 发表于 2008-2-22 12:17:06 | 显示全部楼层
楼上的意思是,还得需要一个全局变量数组用来保存动态创建的触发器的句柄??
而且,魔法目标区域如何才能传到动态创建的触发器里面???
回复

使用道具 举报

发表于 2008-2-22 12:18:45 | 显示全部楼层
用单个触发的话也可以~~那就把触发事件的计时器动态注册化~~

然后获取触发计时器的对应区域创建特效也可以~~
回复

使用道具 举报

发表于 2008-2-22 12:18:59 | 显示全部楼层
这样可以么?

触发器1(当单位开始释放一个魔法)
      事件:当一个单位开始释放魔法
      条件:所释放的魔法是指定的魔法
      动作:保存释放魔法的目标区域到一个全局变量
                  打开一个用于创建效果的定时触发器(触发器2)。
触发器2(每隔n毫秒)(默认关闭的)
      事件:每隔n毫秒
      条件:(无)
      动作:local  类型 局部变量 = 全局变量(触发1的)
            call 创建魔法效果的函数(目标区域的局部变量)
触发器3(当单位停止释放一个魔法)
        事件:当一个单位停止释放魔法
        条件:所释放的魔法是指定的魔法
        动作:停止触发器2
回复

使用道具 举报

发表于 2008-2-22 12:19:52 | 显示全部楼层
引用第4楼sdhexu于2008-02-22 12:17发表的  :
楼上的意思是,还得需要一个全局变量数组用来保存动态创建的触发器的句柄??
而且,魔法目标区域如何才能传到动态创建的触发器里面???

你看~~你可以用缓存来建立触发器和区域的一一对应关系~~通过将触发器的H2I将触发器和区域的handle保存到缓存中~~
回复

使用道具 举报

 楼主| 发表于 2008-2-22 12:20:35 | 显示全部楼层
谢谢楼上的朋友!!!

在下原本酷爱VC++Windows下编程并从事编程方面的工作,最近迷上魔兽地图制作。真心希望与各位高手交朋友!!!
QQ:703252627  

哪位高手可否帮我该一下,在下感激不禁。。。
我的图: WorldEditTestMap.w3x (15 KB, 下载次数: 10)
回复

使用道具 举报

 楼主| 发表于 2008-2-22 12:23:03 | 显示全部楼层
再问一下高手:

触发器可以传递参数么???
回复

使用道具 举报

 楼主| 发表于 2008-2-22 12:25:41 | 显示全部楼层
引用第6楼buu_peng于2008-02-22 12:18发表的  :
这样可以么?

触发器1(当单位开始释放一个魔法)
      事件:当一个单位开始释放魔法
      条件:所释放的魔法是指定的魔法
.......
回答6楼的朋友。这样,仍然不行的。因为第一个单位如果停止了魔法释放,就会关闭触发器2,那么第二个正在释放该魔法的单位就不会有效果了。
回复

使用道具 举报

发表于 2008-2-22 12:46:56 | 显示全部楼层
lz看看这样效果可以吗?

test2.w3x (16 KB, 下载次数: 17)
回复

使用道具 举报

 楼主| 发表于 2008-2-22 12:48:04 | 显示全部楼层
先谢谢楼上的朋友,下载试试。。
谢谢。

哇!!!!!
楼上的朋友!!!
谢谢!!完全是我预期的。。再次谢谢!!!

如何才能给您加分啊。
回复

使用道具 举报

 楼主| 发表于 2008-2-22 16:19:54 | 显示全部楼层
zhuzeitou师父,可不可以把您的代码加上点注释,给我解释一下啊:

function BaoFengXueStop takes nothing returns nothing
    local trigger trg = GetTriggeringTrigger()
    local timer tm = I2T(GetStoredInteger(GameCache(), I2S(H2I(trg)), "timer"))
    local integer index = GetStoredInteger(GameCache(), I2S(H2I(tm)), "index")
    set index = 20
    call StoreInteger(GameCache(), I2S(H2I(tm)), "index", index)
    set tm = null
    set trg = null
endfunction

function BaoFengXueTeXiao takes nothing returns nothing
    local timer tm = GetExpiredTimer()
    local integer index = GetStoredInteger(GameCache(), I2S(H2I(tm)), "index")
    local rect rtA = I2RC(GetStoredInteger(GameCache(), I2S(H2I(tm)), "rect"))
    local location rdm = GetRandomLocInRect(rtA)
    local effect eff
    local trigger trg = I2TG(GetStoredInteger(GameCache(), I2S(H2I(tm)), "trigger"))
    if index > 19 then
        call PauseTimer(tm)
        call DestroyTimer(tm)
        call DestroyTriggerAll(trg)
        call RemoveRect(rtA)
    else
        set index = index + 1
        call StoreInteger(GameCache(), I2S(H2I(tm)), "index", index)
        set eff = AddSpecialEffectLoc("Objects\\\\Spawnmodels\\\\Naga\\\\NagaDeath\\\\NagaDeath.mdl", rdm)
        call DestroyEffect(eff)
    endif
    set tm = null
    set rtA = null
    call RemoveLocation(rdm)
    set rdm = null
    set eff = null
    set trg = null
endfunction

function Trig_BaoFengXue_______u_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A000' ) ) then
        return false
    endif
    return true
endfunction

function Trig_BaoFengXue_______u_Actions takes nothing returns nothing
    local rect rtA = RectFromCenterSizeBJ(GetSpellTargetLoc(), 500.00, 500.00)
    local unit u = GetTriggerUnit()
    local timer tm = CreateTimer()
    local trigger trg = CreateTrigger()
    local triggeraction ta
    local integer index = 0
    call TriggerRegisterUnitEvent(trg, u, EVENT_UNIT_SPELL_ENDCAST)
    set ta = TriggerAddAction(trg, function BaoFengXueStop)
    call StoreInteger(GameCache(), I2S(H2I(trg)), "TriggerAction", H2I(ta))
    call StoreInteger(GameCache(), I2S(H2I(trg)), "timer", H2I(tm))
    call StoreInteger(GameCache(), I2S(H2I(tm)), "trigger", H2I(trg))
    call StoreInteger(GameCache(), I2S(H2I(tm)), "index", index)
    call StoreInteger(GameCache(), I2S(H2I(tm)), "rect", H2I(rtA))
    call TimerStart(tm, 0.2, true, function BaoFengXueTeXiao)
    set rtA = null
    set u = null
    set tm = null
    set trg = null
    set ta = null
endfunction

//===========================================================================
function InitTrig_BaoFengXue takes nothing returns nothing
    set gg_trg_BaoFengXue = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_BaoFengXue, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_BaoFengXue, Condition( function Trig_BaoFengXue_______u_Conditions ) )
    call TriggerAddAction( gg_trg_BaoFengXue, function Trig_BaoFengXue_______u_Actions )
endfunction
回复

使用道具 举报

发表于 2008-2-22 17:03:23 | 显示全部楼层
55555555不要叫人家师傅,很显老的………………大家共同学习呀~~

[codes=jass]function BaoFengXueStop takes nothing returns nothing
    local trigger trg = GetTriggeringTrigger()//获取正在执行的触发器trg
    local timer tm = I2T(GetStoredInteger(GameCache(), I2S(H2I(trg)), "timer"))
    local integer index = GetStoredInteger(GameCache(), I2S(H2I(tm)), "index")//从缓存读取数据
    set index = 20//设置index为20
    call StoreInteger(GameCache(), I2S(H2I(tm)), "index", index)//缓存记录index
    set tm = null
    set trg = null//清空handle类变量
endfunction

function BaoFengXueTeXiao takes nothing returns nothing
    local timer tm = GetExpiredTimer()//获取到期的计时器tm
    local integer index = GetStoredInteger(GameCache(), I2S(H2I(tm)), "index")
    local rect rtA = I2RC(GetStoredInteger(GameCache(), I2S(H2I(tm)), "rect"))//从缓存中读取数据
    local location rdm = GetRandomLocInRect(rtA)//设置点rdm为rtA内随机点
    local effect eff
    local trigger trg = I2TG(GetStoredInteger(GameCache(), I2S(H2I(tm)), "trigger"))//从缓存读取触发器trg
    if index > 19 then//如果index>19,这也就是之前为什么要设为20的原因
        call PauseTimer(tm)//暂停tm
        call DestroyTimer(tm)//销毁tm
        call DestroyTriggerAll(trg)//完整的销毁触发器trg,此函数在自定义脚本中声明,还有一些与return bug和缓存相关的函数也在
        call RemoveRect(rtA)//删除rtA
    else//不满足index>19的条件下执行以下
        set index = index + 1//设置index自增
        call StoreInteger(GameCache(), I2S(H2I(tm)), "index", index)//缓存记录index
        set eff = AddSpecialEffectLoc("Objects\\\\Spawnmodels\\\\Naga\\\\NagaDeath\\\\NagaDeath.mdl", rdm)//创建特效
        call DestroyEffect(eff)//销毁特效,虽然是即时销毁,但仍然会完整的播放一遍
    endif
    set tm = null
    set rtA = null
    call RemoveLocation(rdm)//rdm不再被用到了,清除掉
    set rdm = null
    set eff = null
    set trg = null//清空handle类变量
endfunction

function Trig_BaoFengXue_______u_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A000' ) ) then
        return false
    endif
    return true
endfunction

function Trig_BaoFengXue_______u_Actions takes nothing returns nothing
    local rect rtA = RectFromCenterSizeBJ(GetSpellTargetLoc(), 500.00, 500.00)
    local unit u = GetTriggerUnit()
    local timer tm = CreateTimer()
    local trigger trg = CreateTrigger()
    local triggeraction ta
    local integer index = 0
    call TriggerRegisterUnitEvent(trg, u, EVENT_UNIT_SPELL_ENDCAST)
    set ta = TriggerAddAction(trg, function BaoFengXueStop)//创建一个临时的触发,事件为单位停止释放技能,动作为BaoFengXueStop
    call StoreInteger(GameCache(), I2S(H2I(trg)), "TriggerAction", H2I(ta))
    call StoreInteger(GameCache(), I2S(H2I(trg)), "timer", H2I(tm))
    call StoreInteger(GameCache(), I2S(H2I(tm)), "trigger", H2I(trg))
    call StoreInteger(GameCache(), I2S(H2I(tm)), "index", index)
    call StoreInteger(GameCache(), I2S(H2I(tm)), "rect", H2I(rtA))//缓存记录数据
    call TimerStart(tm, 0.2, true, function BaoFengXueTeXiao)//开启0.2秒间隔的循环计时器tm
    set rtA = null
    set u = null
    set tm = null
    set trg = null
    set ta = null//清空变量
endfunction[/codes]

大概就是这样,可以去看一些教程,恩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-11-23 17:14 , Processed in 0.097188 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表