找回密码
 点一下
查看: 2808|回复: 6

继续Hash方法可用性的探讨

[复制链接]
发表于 2008-11-3 22:15:44 | 显示全部楼层 |阅读模式
继续Hash方法...
上篇帖子初步显示了Hash方法的一些功能,兔子也指出了Hash方法的应用采用了
类似缓存的思路。我认为,Hash在一定的范围内,是可以模拟缓存的。接下来演
示动态函数的注册和销毁。

本演示参考了Red_wolf的显示伤害值的演示,使用了Hash方法,如下:

[codes=全局变量jass]globals
constant integer Ha=16381
constant integer Hb=3999
constant integer Hc=8191
//以上为Hash算法需要的数值,不需变动。
integer I
unit U
//以上为Union Bug应用的前提,Hash函数调用时用到了它们。
integer array H1
integer array H2
//用于Hash法数值的记录和读取。
boolean array show
//用于玩家控制伤害数值是否显示。(默认为不显示)
trigger array T1
trigger array T2
triggercondition array Tc1
triggercondition array Tc2
//用于记录注册的函数和其条件
endglobals[/codes]

[codes=单位收到伤害后漂浮字体显示jass]function ShowDamage_Func takes nothing returns nothing
local texttag tt
local unit u
if GetEventDamage()>0 then
//有很多指向性魔法或一些效果会使得单位收到0伤害,在此排除。
set tt=CreateTextTag()
set u=GetTriggerUnit()
if show[GetPlayerId(GetLocalPlayer())] and IsUnitVisible(u,GetLocalPlayer()) then
//上一行判断本地玩家是否允许显示漂浮字体和受到伤害单位是否为本地玩家所见。
call SetTextTagText(tt,I2S(R2I(GetEventDamage())),.023)
call SetTextTagPos(tt,GetUnitX(u),GetUnitY(u),50)
call SetTextTagColor(tt,255,202,149,255)
call SetTextTagVelocity(tt,0,.03)
call SetTextTagFadepoint(tt,.2)
endif
call SetTextTagPermanent(tt,false)
call SetTextTagLifespan(tt,1)
endif
set u=null
set tt=null
endfunction[/codes]

[codes=函数主体集成了动态函数的注册和删除功能jass]function Hash takes integer I,unit U,boolean b returns nothing
//integer I与Unit U请顺序调用!boolean b为true时,记录并创建动态函数,为false时,消除记录并销毁动态函数。
local integer ha=I-I/Ha*Ha
local integer hb=(I/Hb+1)*Hb-I
local integer n
if b then
set n=0
else
set n=I
endif
loop
if ha>=Hc then
set ha=ha-Ha
endif
exitwhen (ha>=0 and H1[ha]==n)or(ha<0 and H2[-ha]==n)
set ha=ha+hb
endloop
//改变了一些数值的大小,使得可以记录的单位的数量的上限增长为16381,但理想的记录数量应为上限的半数左右。
if b then
if ha>=0 then
set T1[ha]=CreateTrigger()
call TriggerRegisterUnitEvent(T1[ha],U,EVENT_UNIT_DAMAGED)
set Tc1[ha]=TriggerAddCondition(T1[ha],Condition(function ShowDamage_Func))
set H1[ha]=I
else
set T2[-ha]=CreateTrigger()
call TriggerRegisterUnitEvent(T2[-ha],U,EVENT_UNIT_DAMAGED)
set Tc2[-ha]=TriggerAddCondition(T2[-ha],Condition(function ShowDamage_Func))
set H2[-ha]=I
endif
//以上为b==true时,记录并生成了动态函数。
else
if ha>=0 then
call TriggerRemoveCondition(T1[ha],Tc1[ha])
call DestroyTrigger(T1[ha])
set H1[ha]=0
else
call TriggerRemoveCondition(T2[-ha],Tc2[-ha])
call DestroyTrigger(T2[-ha])
set H2[-ha]=0
endif
//以上为b==false时,清楚了Hash中的记录并销毁了动态函数。
endif
endfunction[/codes]

[codes=函数的调用方法jass]call Hash(0,CreateUnit(p,'hfoo',GetRandomReal(-1000,1000),GetRandomReal(-1000,1000),0),true)
//Hash新创建的单位
call Hash(0,GetDyingUnit(),false)
//单位死亡后调用[/codes]

综上,此方法可以在一定范围内取代缓存并有效的提升触发的运行速度。
需要补充的是,收到伤害后显示伤害数值在我看来并不适用于地图当中,它会使得大家的游戏画面变的
很繁杂从而影响游戏体验,此演示只是用于探讨地图中动态函数的创建与删除的不同于缓存方法的可行
性。
Hash.伤害显示V0.1.w3x (25 KB, 下载次数: 19)
发表于 2008-11-4 11:55:19 | 显示全部楼层
值得研究。
回复

使用道具 举报

发表于 2008-11-4 19:37:51 | 显示全部楼层
:吸收hash精华中........
回复

使用道具 举报

发表于 2008-11-5 11:16:52 | 显示全部楼层
数组下标在超过8192时,用游戏的保存功能后载入游戏会直接使war3崩溃哦
回复

使用道具 举报

 楼主| 发表于 2008-11-6 15:36:02 | 显示全部楼层
嗯,此楼我自己占了,搞点莫名其妙的事。
回复

使用道具 举报

发表于 2008-11-6 18:54:02 | 显示全部楼层
研究中
回复

使用道具 举报

发表于 2008-11-7 16:43:19 | 显示全部楼层
参数传递在Jass里已经有很成熟的方案,不如把精力多往变量的分类上研究,如 vJass这样的。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-24 07:14 , Processed in 0.083341 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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