找回密码
 点一下
查看: 1963|回复: 8

这个函数还有问题吗?

[复制链接]
发表于 2010-8-21 13:35:57 | 显示全部楼层 |阅读模式
用3-5个Debug文本信息检错的时候一旦同时运行多次会很卡。

第一次用Jass自己写函数。
以前都是改改Dota虐虐AI而已。
对函数隐藏的错误个人已经检查不出来了,希望有经验丰富的前辈指点指点。


引用的内容是我对函数的理解。
Jass高亮的内容是实际函数。

顺带问一下,Timerstart和新建触发器并给予事件和动作有什么差别么。
Timerstart看起来简单一些,可是我听说函数的运行是串联的,触发器是并联的。
函数名HealHP

声明局部变量*4
……
……
……
设置局部变量*4
……
……
……
显示Debug信息
判断循环次数(本来是用了个局部变量从缓存里读,然后看Dota里的方法更省事,果断无耻的抄袭了。)
是则:
恢复生命值
否则:
清空局部变量*3(根据教材,只有句柄型变量需要清空,但是习惯性的全部清零吧。)
……
……
……
删除缓存类别
关闭触发器
删除触发器
清空trigger变量(担心清空变量导致无法使用变量做事,所以最后清除。)

函数名HealHP_Start

声明局部变量*5
设置局部变量*4
清空起到传递参数用的全局变量(不会用传递参数……每次JassshopPRO总是提示Except“.”or“return” )
设置局部变量(这个局部变量是用计算得来的,所以位置稍后了一些。)
简单的判断
是则XXX
否则无视
对变量进行最后的计算*2
使用Trigger变量,创建一个新触发器
使用return Bug保存需要保存的数据到触发器身上
为新建的触发器添加事件和动作
清空变量

[jass]function HealHP takes nothing returns nothing
local trigger Temp_Trigger
local unit Temp_Unit
local integer Temp_Integer
local real Temp_RHP
set Temp_Trigger = GetTriggeringTrigger()
set Temp_Unit = I2U(GetStoredInteger(udg_GC, I2S(H2I(Temp_Trigger)),"Temp_Unit"))
set Temp_Integer = GetStoredInteger(udg_GC, I2S(H2I(Temp_Trigger)),"Temp_Integer")
set Temp_RHP = GetStoredReal(udg_GC, I2S(H2I(Temp_Trigger)),"Temp_RHP")
call BJDebugMsg( "当前循环次数"+I2S(GetTriggerEvalCount(Temp_Trigger)))
if GetTriggerEvalCount(Temp_Trigger) <= Temp_Integer then
call SetUnitState( Temp_Unit, UNIT_STATE_LIFE,(GetUnitState(Temp_Unit,UNIT_STATE_LIFE)+(Temp_RHP)))
else
set Temp_Unit = null
set Temp_Integer = 0
set Temp_RHP = 0
call FlushStoredMission(udg_GC, I2S(H2I(Temp_Trigger)) )
call DisableTrigger( Temp_Trigger )
call DestroyTrigger( Temp_Trigger )
set Temp_Trigger = null
endif
endfunction

function HealHP_Start takes nothing returns nothing
local integer Temp_Integer
local trigger Temp_Trigger
local unit Temp_Unit
local real Temp_PPT
local real Temp_RHPMax
local real Temp_RHP
set Temp_Unit = udg_Unit
set Temp_Integer = udg_Integer
set Temp_PPT = udg_PPT
set Temp_RHPMax = udg_RHPMax
set udg_Unit = null
set udg_Integer = 0
set udg_PPT = 0
set udg_RHPMax = 0
set Temp_RHP = ((GetUnitState(Temp_Unit, UNIT_STATE_MAX_LIFE) - GetUnitState(Temp_Unit, UNIT_STATE_LIFE))* Temp_PPT)
if&#160;&#160;( Temp_RHP > Temp_RHPMax )&#160;&#160;then
set Temp_RHP=Temp_RHPMax
endif
set Temp_Integer = Temp_Integer*100
set Temp_RHP = Temp_RHP/Temp_Integer
set Temp_Trigger = CreateTrigger()
call StoreInteger( udg_GC, (I2S(H2I(Temp_Trigger))), "Temp_Unit",&#160;&#160;H2I(Temp_Unit) )
call StoreInteger( udg_GC, (I2S(H2I(Temp_Trigger))), "Temp_Integer",&#160;&#160;Temp_Integer )
call StoreReal( udg_GC, (I2S(H2I(Temp_Trigger))), "Temp_RHP", Temp_RHP )
call TriggerRegisterTimerEvent(Temp_Trigger,0.01,true)
//一般情况下时间间隔小于多少会导致机器卡?刚开始我5个Debug,每0.001运行一次,直接卡飞了。
call TriggerAddCondition(Temp_Trigger,Condition(function HealHP))
set Temp_Trigger = null
set Temp_Unit = null
set Temp_Integer = 0
set Temp_PPT = 0
set Temp_RHPMax = 0
set Temp_RHP = 0
endfunction[/jass]
发表于 2010-8-21 23:47:00 | 显示全部楼层
和我上回给你那个演示的思路如出一辙,只是回复量可能不同...
[jass]function a2 takes nothing returns nothing
local integer i=udg_i
local real r
loop
exitwhen udg_tmr==GetExpiredTimer()
set i=i-1
if i<1 then
set i=8000
endif
endloop
if udg_tms<=0 then
call DestroyTimer(udg_tmr)
endif
set udg_tms=udg_tms-1
set r=GetUnitState(udg_u,UNIT_STATE_LIFE)
set r=RMinBJ(r+udg_hp*udg_hp[0]/I2R(udg_tms[0]),GetUnitState(udg_u,UNIT_STATE_MAX_LIFE))
call BJDebugMsg(R2S(r))
call SetUnitState(udg_u,UNIT_STATE_LIFE,r)
endfunction

function a1 takes nothing returns nothing
local integer i=udg_i
set i=i+1
if i>8000 then
set i=1
endif
set udg_i=i
set udg_u=GetTriggerUnit()
set udg_hp=GetUnitState(udg_u,UNIT_STATE_MAX_LIFE)-GetUnitState(udg_u,UNIT_STATE_LIFE)
set udg_hp=RMinBJ(udg_hp,1000/udg_hp[0])
set udg_tmr=CreateTimer()
set udg_tms=udg_tms[0]
call TimerStart(udg_tmr,3/I2R(udg_tms),true,function a2)
endfunction[/jass]
回复

使用道具 举报

发表于 2010-8-21 23:57:03 | 显示全部楼层
已经打扫得很干净了,时间间隔没必要那么小吧... 上回的0.02我觉得都很短了 0.2还差不多...

如果非挑错的话... 这个触发器条件最后也应该干掉
TriggerAddCondition(Temp_Trigger,Condition(function HealHP))

//native TriggerAddCondition takes trigger whichTrigger, boolexpr condition returns triggercondition
回复

使用道具 举报

发表于 2010-8-22 00:21:25 | 显示全部楼层
至于传递参数... 你可以这么修改下
[jass]function HealHP_Start takes integer Temp_Integer, unit Temp_Unit, real Temp_PPT, real Temp_RHPMax returns nothing
local trigger Temp_Trigger
local real Temp_RHP
set Temp_RHP = ((GetUnitState(Temp_Unit, UNIT_STATE_MAX_LIFE) - GetUnitState(Temp_Unit, UNIT_STATE_LIFE))* Temp_PPT)
if  ( Temp_RHP > Temp_RHPMax )  then
set Temp_RHP=Temp_RHPMax
endif
set Temp_Integer = Temp_Integer*100
set Temp_RHP = Temp_RHP/Temp_Integer
set Temp_Trigger = CreateTrigger()
call StoreInteger( udg_GC, (I2S(H2I(Temp_Trigger))), "Temp_Unit",  H2I(Temp_Unit) )
call StoreInteger( udg_GC, (I2S(H2I(Temp_Trigger))), "Temp_Integer",  Temp_Integer )
call StoreReal( udg_GC, (I2S(H2I(Temp_Trigger))), "Temp_RHP", Temp_RHP )
call TriggerRegisterTimerEvent(Temp_Trigger,0.01,true)
call TriggerAddCondition(Temp_Trigger,Condition(function HealHP))
set Temp_Trigger = null
set Temp_Unit = null
endfunction[/jass]
然后在触发器动作里这么调用... 实际上这几个全局变量可以省掉,直接把他们的值写进去
call HealHP_Start(udg_Integer, udg_Unit, udg_PPT, udg_RHPMax)
//我的理解,不知道对不... HealHP_Start(几秒,嗑药单位,回复占损失百分比,最大回复量)
回复

使用道具 举报

发表于 2010-8-22 11:53:04 | 显示全部楼层
timerstart的效率比TriggerRegisterTimerEvent要高很多,而且timerstart也不存在什么“串联”的问题。
http://bbs.islga.org/read-htm-tid-33531-keyword-timerstart.html

另外,我只知道“TriggerAction”必须要排泄,不然会很卡;TriggerCondition貌似不需要排泄吧。

最后面,我发现最好的“算法”不是我的那两种,而是用一个实数储存回复的生命,然后在计算“损失生命”的时候加上这个实数。
回复

使用道具 举报

 楼主| 发表于 2010-8-22 12:45:23 | 显示全部楼层
第一次写函数,虽然自认为应该没有致命缺陷了,但是还是想请教一下权威呀。
谢谢了,我会好好拜读的。
回复

使用道具 举报

 楼主| 发表于 2010-8-22 12:57:05 | 显示全部楼层
引用第2楼Conflux于2010-08-21 23:57发表的  :
已经打扫得很干净了,时间间隔没必要那么小吧... 上回的0.02我觉得都很短了 0.2还差不多...

如果非挑错的话... 这个触发器条件最后也应该干掉
TriggerAddCondition(Temp_Trigger,Condition(function HealHP))

.......
话说大菠萝里面的生命恢复我非常喜欢,因为更平滑,安全更有保障。
话说我完全不知道Condition竟然也要清空……太嫩了……
引用第3楼Conflux于2010-08-22 00:21发表的  :
至于传递参数... 你可以这么修改下
[jass]function HealHP_Start takes integer Temp_Integer, unit Temp_Unit, real Temp_PPT, real Temp_RHPMax returns nothing
………………
.......
呼哇,我传递参数的时候Jassshoppro一直报错。
引用第4楼希瓦于2010-08-22 11:53发表的  :
timerstart的效率比TriggerRegisterTimerEvent要高很多,而且timerstart也不存在什么“串联”的问题。
http://bbs.islga.org/read-htm-tid-33531-keyword-timerstart.html

另外,我只知道“TriggerAction”必须要排泄,不然会很卡;TriggerCondition貌似不需要排泄吧。

.......
既然Timerstar是触发器的话,就不会存在什么问题了。
只是Dota竟然用TriggerRegisterTimerEvent……本着“看和学”的理念还是用了TriggerRegisterTimerEvent……………………

谢谢大家帮忙。
解决了~
回复

使用道具 举报

发表于 2010-8-22 13:38:50 | 显示全部楼层
平滑...
那就换下思路,计算每回复1点需要多少时间...
回复

使用道具 举报

 楼主| 发表于 2010-8-22 16:35:24 | 显示全部楼层
不可能不可能……
10秒回复四千万,每秒恢复400万……
于是0.01-0.04好了。

曾经花了一个上午检错,最后发现没有初始化游戏缓存。
曾经花了一个下午检查传递参数,今天发现没加逗号。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-21 16:58 , Processed in 0.031399 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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