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

单位-开始/停止移动事件

[复制链接]
发表于 2007-5-8 18:05:50 | 显示全部楼层 |阅读模式
//#####START#####
[codes=jass]library COMMON initializer InitCOMMON
globals
    gamecache HGGC = null
    timer HTMR = null
endglobals
function InitCOMMON takes nothing returns nothing
    set HGGC = InitGameCache("GLOBALGAMECACHE")
    set HTMR = CreateTimer()
endfunction
function H2I takes handle h returns integer
    return h
    return 0
endfunction
function I2U takes integer i returns unit
    return i
    return null
endfunction
function C2I takes code c returns integer
    return c
    return 0
endfunction
function I2C takes integer i returns code
    return i
    return null
endfunction
function I2T takes integer i returns trigger
    return i
    return null
endfunction
function Execute takes code c returns nothing
    call TimerStart(HTMR,0,false,c)
endfunction
endlibrary
//added two event: movestart,moveend.
library UNITMOVEEVENT requires COMMON
//! define MOVE_CHECK_TIME 0.04
function MoveEventCore takes nothing returns nothing
    local trigger t = GetTriggeringTrigger()
    local unit u = I2U(GetStoredInteger(HGGC,"UNITMOVEEVENT",I2S(H2I(t))))
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local code c = I2C(GetStoredInteger(HGGC,"UNITMOVEEVENT_START_MOVING_HANDLER",I2S(H2I(u))))
    local code d = I2C(GetStoredInteger(HGGC,"UNITMOVEEVENT_END_MOVING_HANDLER",I2S(H2I(u))))
    if (x==GetStoredReal(HGGC,"UNITMOVEEVENT_UNIT_X",I2S(H2I(u)))) and (y==GetStoredReal(HGGC,"UNITMOVEEVENT_UNIT_Y",I2S(H2I(u)))) then
      if GetStoredBoolean(HGGC,"UNITMOVEEVENT_UNIT_MOVING",I2S(H2I(u))) and (d!=null) then
          call Execute(d)
      endif
      call StoreBoolean(HGGC,"UNITMOVEEVENT_UNIT_MOVING",I2S(H2I(u)),false)
    elseif (x!=GetStoredReal(HGGC,"UNITMOVEEVENT_UNIT_X",I2S(H2I(u)))) or (y!=GetStoredReal(HGGC,"UNITMOVEEVENT_UNIT_Y",I2S(H2I(u)))) then
      if (GetStoredBoolean(HGGC,"UNITMOVEEVENT_UNIT_MOVING",I2S(H2I(u)))==false) and (c!=null) then
          call Execute(c)
      endif
      call StoreBoolean(HGGC,"UNITMOVEEVENT_UNIT_MOVING",I2S(H2I(u)),true)
    endif
    call StoreReal(HGGC,"UNITMOVEEVENT_UNIT_X",I2S(H2I(u)),x)
    call StoreReal(HGGC,"UNITMOVEEVENT_UNIT_Y",I2S(H2I(u)),y)
endfunction
function RegMoveEvent takes unit u,boolean b returns nothing
  local trigger t = I2T(GetStoredInteger(HGGC,"UNITMOVEEVENT",I2S(H2I(u))))
    if (b==false)and (t!=null) then
      call DisableTrigger(t)
      call DestroyTrigger(t)
      call FlushStoredInteger(HGGC,"UNITMOVEEVENT",I2S(H2I(u)))
    elseif b and(t==null) then
      set t = CreateTrigger()
      call StoreInteger(HGGC,"UNITMOVEEVENT",I2S(H2I(u)),H2I(t))
      call StoreInteger(HGGC,"UNITMOVEEVENT",I2S(H2I(t)),H2I(u))
      call TriggerAddAction(t,function MoveEventCore)
      call TriggerRegisterTimerEvent(t,MOVE_CHECK_TIME,true)
    endif
endfunction
function IsUnitMoving takes unit u returns boolean
    return GetStoredBoolean(HGGC,"UNITMOVEEVENT_UNIT_MOVING",I2S(H2I(u)))
endfunction
function UnitMoveStart takes unit u,code c returns nothing
    call StoreInteger(HGGC,"UNITMOVEEVENT_START_MOVING_HANDLER",I2S(H2I(u)),C2I(c))
endfunction
function UnitMoveEnd takes unit u,code c returns nothing
    call StoreInteger(HGGC,"UNITMOVEEVENT_END_MOVING_HANDLER",I2S(H2I(u)),C2I(c))
endfunction
endlibrary[/codes]
//#####END#####
RegMoveEvent :注册/取消注册移动事件
UnitMoveStart :注册单位开始移动事件,必须先注册移动事件
UnitMoveEnd :注册单位停止移动事件,必须先注册移动事件
IsUnitMoving :判断单位是否移动中

由于要判断单位是原地转向还是移动中转向比较麻烦,所以我没有把移动转向停留作为移动中来看。
如果被监视的单位转向太急以至于原地小停,将先后触发停止移动事件和开始移动事件。

你可以设置MOVE_CHECK_TIME的值来设置检测周期,值越小则越敏感。
没有使用无限循环,如果没有注册移动事件的单位,则不占资源。

另外,如果你有兴趣你可以添加到UI里面
发表于 2007-5-8 18:12:24 | 显示全部楼层

Re:[vjass]单位-开始/停止移动事件

用时间来检查的花费比较高。
回复

使用道具 举报

发表于 2007-5-8 18:56:57 | 显示全部楼层
kaixiaodaakaixiaoda~

louzhuqiangalouzhuqiang~
回复

使用道具 举报

DeadFish 该用户已被删除
发表于 2007-5-8 18:57:30 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

 楼主| 发表于 2007-5-8 20:41:14 | 显示全部楼层
本来原来是用命令事件来检测移动的,不过存在好多问题,所以换成这个了。
开销虽然比较大,不过对于地图来说能够运行起来不卡就行。资源也要合理利用嘛。
回复

使用道具 举报

发表于 2007-5-9 00:04:10 | 显示全部楼层
其实有更简单的办法。
回复

使用道具 举报

发表于 2007-5-9 09:01:14 | 显示全部楼层
LS告诉我啊!
回复

使用道具 举报

发表于 2007-5-9 10:30:18 | 显示全部楼层
呃。停止事件米有。
移动事件很好做啊。
麦德大人告诉偶的。
动态建一个只在单位脚下的区域。
然后注册单位离开事件。
或者做个全地图区域。把单位脚下的扣出来。用单位进入区域事件。
555。当然。这个区域不素WE里的区域(rect)啦。
是region。
呃。单位脚下的区域其实不是模型大小。只要1。呃。距离的单位是什么。5555。
回复

使用道具 举报

 楼主| 发表于 2007-5-9 12:22:20 | 显示全部楼层
LS很强,不过貌似对已经开始移动的单位无法注册,注册一次只能用一次。呵呵(因为我最开始就打算用这个来做的)。
回复

使用道具 举报

发表于 2007-5-9 13:59:43 | 显示全部楼层
已经开始移动的单位无法注册是什么意思呢?
你的意思是说,如果单位已经开始移动。然后再注册单位移动事件的话。
并不是开始移动的事件。因为单位是正在移动中的。发出命令的时间已经过了。
但是呢。其实一般像“开始”、“停止”移动。这样的表达很模糊呢。
因为如何算开始移动呢?比如按A。攻击移动到某个区域。
单位开始去了,中间遇到敌人,停下来了。然后打完再继续。
那么如果是发出命令之前算起。那也许会有发出命令的“开始”和中间战斗的“开始”。
但是,如果在命令发出以后再注册的事件。不管怎么样,都很难知道前面的那次开始是怎么样的呢。
只能从注册事件的那个时间算“开始”了。

嗯嗯。其实打这么字偶也不知道是啥米意思。
简单的说就是偶说的只是移动事件,并没有“开始”和“结束”一说。
“开始”和“结束”很难算清楚。
回复

使用道具 举报

 楼主| 发表于 2007-5-9 16:37:52 | 显示全部楼层
如果是移动事件的话,什么时候抛出动作线程?
还是说处于移动中就不停地触发移动事件?
我不想争论了,我这个系统是经过了我的很多思考的,如果认为做得不够好,那就拿出比它好的来。
我会虚心接受的。
回复

使用道具 举报

发表于 2007-5-10 00:17:52 | 显示全部楼层
NO NO。我并没有说不好。只是提出另一种思路。
关于我说用时间间隔来判断花费比较高。仅仅只是个人看法。嗯嗯。
回复

使用道具 举报

发表于 2007-5-10 02:59:03 | 显示全部楼层
你们很强大
回复

使用道具 举报

发表于 2007-5-10 07:33:55 | 显示全部楼层
用timer代替trigger会好很多
回复

使用道具 举报

 楼主| 发表于 2007-5-10 18:21:27 | 显示全部楼层
恩,的确是这样。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-22 03:59 , Processed in 0.031577 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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