找回密码
 点一下
查看: 6901|回复: 15

[转贴][教程][初级]如何异步执行代码

[复制链接]
发表于 2006-3-29 19:19:45 | 显示全部楼层 |阅读模式
在制作技能时,经常需要一些异步操作,可是直接函数调用是同步执行的。
解决办法是很简单的,但是很多人不知道。
所以我冒昧的转贴了过来,并转成了简体汉字(当初就是因为给出了Danny网站的链接,被无数看不懂繁体字的人骂死)。

以下资料来自Danny的WE自学手册。

http://www.infor.org/~n1048/WESelfStudy/GoodArticles/JASSManual/attach11.htm
<附件11>:分割执行程序代码
分割执行程序代码(可在函数中放Wait而不会有执行上的延迟)
[jass]function RunCode takes code whichcode returns nothing
    local trigger trg = CreateTrigger()
    local triggeraction act = TriggerAddAction(trg, whichcode)
    call TriggerExecute(trg)
    call TriggerRemoveAction(trg,act)
    call DestroyTrigger(trg)
endfunction [/jass]

上面那个等级还不够高,高手都是用这个函数写的:
[jass]    call ExecuteFunc("函数名") [/jass]
这个函数会自动搜寻指定的函数名称并执行它,一样是用分割的方式进行的。

而且它可向前参照原则,执行写在后面的函数,例如:
[jass]function Test takes nothing returns nothing
    call MyFunc()
endfunction

function MyFunc takes nothing returns nothing
    call BJDebugMsg("MyFunc is called")
endfunction [/jass]
由于你不能呼叫此函数以后的函数,这样写会造成出错。

然而,这样写就没有问题了:
[jass]function Test takes nothing returns nothing
    call ExecuteFunc("MyFunc")
endfunction

function MyFunc takes nothing returns nothing
    call BJDebugMsg("MyFunc is executed")
endfunction[/jass]

这个函数的最大缺点是,被执行的函数必须是takes nothing returns nothing,因此不能传递自变量。不过JASS高手自有妙计,看下去就知道了:)

http://www.infor.org/~n1048/WESelfStudy/GoodArticles/JASSManual/attach12.htm
<附件12>:十秒特效
[quote]
做法一:
[jass]function AddTimeredEffectTargetUnit_Child takes nothing returns nothing
    local effect timeredeffect = bj_lastCreatedEffect
    local real duration = bj_enumDestructableRadius
    call PolledWait( duration )
    call DestroyEffect( timeredeffect )
endfunction

function AddTimeredEffectTargetUnit takes string modelName, unit whichUnit, string whichAttach, real duration returns nothing
    local real Bj_enumDestructableRadius = bj_enumDestructableRadius
    set bj_lastCreatedEffect = AddSpecialEffectTarget(modelName, whichUnit, whichAttach )
    set bj_enumDestructableRadius = duration
    call RunCode(function AddTimeredEffectTargetUnit_Child)
    set bj_enumDestructableRadius = Bj_enumDestructableRadius
endfunction[/jass]

做法二:
[jass]function AddTimeredEffectTargetUnit takes string modelName, unit whichUnit, string whichAttach, real duration returns nothing
    local effect timeredeffect = AddSpecialEffectTargetUnitBJ(whichAttach, whichUnit, modelName )
    call PolledWait(duration)
    call DestroyEffect( timeredeffect )
endfunction[/jass]

以上两种写法,有什么不同?哪一个好?
乍看之下,第二种写法似乎比较简单,但是真的是这样吗?
读者可以试试看,连续对2个不同单位执行这个函数。你会发现,使用第一种做法,2个单位身上同时冒出特效,10秒后同时消失;使用第二种做法时,只有一个单位身上冒出特效,等它消失后,第二个单位身上才冒出特效。

这就是所谓的分割程序代码,当你在一个函数里直接放wait时,必须等函数执行完,才能执行下一个函数。为了免去时间延迟,我们必须先建立一个触发器,让它独立执行,但是code不能传送参数,因此,我们就借用blizzard.j里的变量充当参数传送,当然借完了要把值还回去,不然到时候莫名奇妙出了bug别找我:-(。
看过<附件11>了吗?如果有看过,你就应该知道这样的写法还不够完美,大部分的JASSer会这样写:
[jass]function AddTimeredEffectTargetUnit_Child takes nothing returns nothing
    local effect timeredeffect = bj_lastCreatedEffect
    local real duration = bj_enumDestructableRadius
    call PolledWait( duration )
    call DestroyEffect( timeredeffect )
endfunction

function AddTimeredEffectTargetUnit takes string modelName, unit whichUnit, string whichAttach, real duration returns nothing
    local real Bj_enumDestructableRadius = bj_enumDestructableRadius
    set bj_lastCreatedEffect = AddSpecialEffectTarget(modelName, whichUnit, whichAttach )
    set bj_enumDestructableRadius = duration
    call ExecuteFunc("AddTimeredEffectTargetUnit_Child")
    set bj_enumDestructableRadius = Bj_enumDestructableRadius
endfunction[/code]
[/jass]
发表于 2006-3-29 20:32:20 | 显示全部楼层
这些方法都不稳妥,稳妥地方法是利用GameCache。
回复

使用道具 举报

发表于 2006-3-29 20:35:54 | 显示全部楼层
这样直接看起JASS极其不方便
看来得想办法改善一下论坛对JASS的识别恩
回复

使用道具 举报

发表于 2006-3-29 20:41:35 | 显示全部楼层
精确的说,不是不稳妥,而是比较ugly,而且功能太有限。
利用Timer的handle来传递参数是我比较喜欢的方法,具体使用在我的很多文章里都有,比如Dummy System,还有复活Creep的那个Jass。
回复

使用道具 举报

发表于 2006-3-29 20:45:43 | 显示全部楼层
我比较用VI写或者看Jass,VI可以把当前语法高亮输出成html,不过没有JASS的语法高亮文件,而且VI用的人太少我也懒得专门弄了-__-
其实可以联系JSP或者JassCraft的作者建议他们增加输出成html的功能.
回复

使用道具 举报

发表于 2006-3-29 20:57:05 | 显示全部楼层
那LARS帮忙联系下WC3C的吧 很想要他们坛子的T和JASS粘贴功能
但写信我写不来
回复

使用道具 举报

 楼主| 发表于 2006-3-30 09:46:04 | 显示全部楼层
我转这篇帖子的主要目的是介绍异步执行代码的方法
至于参数传递,自然有更好的办法
但那不是Jass初学者能迅速接受的


以后再有人问如何异步执行代码时
我可以直接粘贴该帖子的URL
不必再费舌了:lol
(我乃懒人一个)
回复

使用道具 举报

发表于 2006-3-30 10:27:25 | 显示全部楼层
wc3c上关于trigger tag和jass tag的文章是Vexorian发的,我给他写信了,这是给我回的:

Well if eGust is a member he could ask zoxc directly, he is the author of the trigger tags, I made my own trigger tags but afterall zoxc is the author.

JASS tag shouldn\'t be a problem, will get the highlighter code soon

eGust我们一个同学,Jass Shop Pro的作者,我问问他看看,或者你们直接问他:)
回复

使用道具 举报

发表于 2006-3-30 11:19:19 | 显示全部楼层
那就麻烦LARS了啊 JASS就是想要这个HIGHLIGHT效果 T的那个功能MS是识别并转换 因为除了识别是用JS写的外 主要在贴内有判断 这个着实有点麻烦 所以希望WC3C的朋友们愿意分享了啊
英文不好 还是得麻烦LARS
TY~~~
回复

使用道具 举报

发表于 2006-4-1 18:59:27 | 显示全部楼层
原帖由 lars 于 2006-3-29 20:32 发表
这些方法都不稳妥,稳妥地方法是利用GameCache。



哦,那是如何做的呢?
回复

使用道具 举报

发表于 2006-4-1 22:44:41 | 显示全部楼层
你看我在Frozen Orb演示里面怎么传递临时变量的:)
回复

使用道具 举报

wawawawa 该用户已被删除
发表于 2006-4-16 15:50:43 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

wawawawa 该用户已被删除
发表于 2006-4-16 15:50:49 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

wawawawa 该用户已被删除
发表于 2006-4-16 15:50:58 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

发表于 2011-7-26 12:06:56 | 显示全部楼层
BBBBBBBBBBBBBBBBBBBbS
回复

使用道具 举报

发表于 2011-8-23 00:08:15 | 显示全部楼层
嘿嘿~奸笑中!
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-22 15:02 , Processed in 0.040878 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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