永恒的灌水帝吧 关注:590贴子:1,695

简单的移动类函数...

只看楼主收藏回复

首先是timerdatasystem... 下面每个函数都需要的
library TDS initializer TDS_init
globals
    integer udg_Max = 0
    integer array udg_Flu
    integer udg_TDSid
    timer array udg_Timer
    boolean array udg_DS_Used //占用判定
    real MOVETIMER_TIMEOUT=0.02 //移动函数循环时间
    //_____________________可用数据______________________________
    real array udg_DS_angle
    real array udg_DS_speed
    real array udg_DS_distance
    real array udg_DS_x
    real array udg_DS_y
    real array udg_DS_speed_x
    real array udg_DS_speed_y
    integer array udg_DS_times
    boolean array udg_DS_hastarget
    player array udg_DS_player
    effect array udg_DS_effect
    string array udg_DS_effectPath
    unit array udg_DS_whichUnit
    //___________________________________________________________
endglobals
function CreateTimerId takes nothing returns integer
    set udg_Max = udg_Max + 1
    if udg_Flu[udg_Max] == 0 then
        set udg_DS_Used[udg_Max] = true
        return udg_Max
    endif
    set udg_DS_Used[udg_Flu[udg_Max]] = true
    return udg_Flu[udg_Max]
endfunction
function GetTimerId takes nothing returns integer
    return GetHandleId(GetExpiredTimer()) - udg_TDSid
endfunction
function DestroyTimerId takes integer tid returns nothing
    if udg_DS_Used[tid] then //只对占用的id操作
        call PauseTimer(udg_Timer[tid])
        set udg_Flu[udg_Max] = tid
        set udg_DS_Used[tid] = false
        set udg_Max = udg_Max - 1
        debug call BJDebugMsg("TimerIdMax="+I2S(udg_Max))
    endif
endfunction
function TDS_init takes nothing returns nothing
    local integer c = 1
    local location l = Location(0,0)
    set udg_TDSid = GetHandleId(l)
    call RemoveLocation(l)
    set l = null
    loop
        exitwhen c >= 8000
        set udg_Timer[c] = CreateTimer()
        set c = c + 1
    endloop
endfunction
endlibrary


1楼2011-03-09 10:05回复
    只是个普通的移动函数
    function Move_Action takes nothing returns nothing
        local integer id=GetTimerId()
        if udg_DS_effectPath[id]!=null then   //特效在经过的位置创建
            call DestroyEffect(AddSpecialEffect(udg_DS_effectPath[id],udg_DS_x[id],udg_DS_y[id]))
        endif
        set udg_DS_x[id]=udg_DS_x[id]+udg_DS_speed_x[id]
        set udg_DS_y[id]=udg_DS_y[id]+udg_DS_speed_y[id]
        if udg_DS_hastarget[id] then //拥有蝗虫技能
            if IsTerrainPathable(udg_DS_x[id], udg_DS_y[id], PATHING_TYPE_FLYABILITY) then
                //不可通行停止移动
                call DestroyTimerId(id)
            else
               
                //可通行直接移动
                call SetUnitX(udg_DS_whichUnit[id],udg_DS_x[id])
                call SetUnitY(udg_DS_whichUnit[id],udg_DS_y[id])
                set udg_DS_distance[id]=udg_DS_distance[id]-udg_DS_speed[id]
                if udg_DS_distance[id]<=0 then
                    call DestroyTimerId(id)
                endif
            endif
        else
            if IsTerrainPathable(udg_DS_x[id], udg_DS_y[id], PATHING_TYPE_WALKABILITY) then
                //不可通行停止移动
                call DestroyTimerId(id)
            else
               
                //可通行直接移动
                call SetUnitX(udg_DS_whichUnit[id],udg_DS_x[id])
                call SetUnitY(udg_DS_whichUnit[id],udg_DS_y[id])
                set udg_DS_distance[id]=udg_DS_distance[id]-udg_DS_speed[id]
                if udg_DS_distance[id]<=0 then
                    call DestroyTimerId(id)
                endif
            endif
        endif
    endfunction
    function Move takes unit u,real x,real y,real angle,real speed,real distance,string effpath returns nothing
        //call Move(u,x,y,angle,speed,distance,effpath)
        local integer id=CreateTimerId()
        set udg_DS_speed[id]=speed*MOVETIMER_TIMEOUT //速度具体化
        set udg_DS_whichUnit[id]=u
        set udg_DS_x[id]=x
        set udg_DS_y[id]=y
        set udg_DS_angle[id]=angle
        set udg_DS_distance[id]=distance
        set udg_DS_speed_x[id]=udg_DS_speed[id]*Cos(angle) //x,y速度分量
        set udg_DS_speed_y[id]=udg_DS_speed[id]*Sin(angle)
        set udg_DS_effectPath[id]=effpath
        set udg_DS_hastarget[id]=(GetUnitAbilityLevel(u,'Aloc')>0) //拥有蝗虫技能
        call SetUnitX(u,x)
        call SetUnitY(u,y)
        call TimerStart(udg_Timer[id],MOVETIMER_TIMEOUT,true,function Move_Action)
    endfunction


    2楼2011-03-09 10:06
    收起回复
      击退函数, 路径特效是花岗石怪的攻击投射物不可更改
      function Back_Action takes nothing returns nothing
          local integer id=GetTimerId()
          call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl",udg_DS_x[id],udg_DS_y[id]))
          //特效在经过的位置创建
          set udg_DS_x[id]=udg_DS_x[id]+udg_DS_speed_x[id]
          set udg_DS_y[id]=udg_DS_y[id]+udg_DS_speed_y[id]
          if not IsTerrainPathable(udg_DS_x[id], udg_DS_y[id], PATHING_TYPE_WALKABILITY) then
              //可通行直接移动
              call SetUnitX(udg_DS_whichUnit[id],udg_DS_x[id])
              call SetUnitY(udg_DS_whichUnit[id],udg_DS_y[id])
              set udg_DS_distance[id]=udg_DS_distance[id]-udg_DS_speed[id]
              if udg_DS_distance[id]<=0 then
                  call DestroyTimerId(id)
              endif
          else
              //不可通行停止移动
              call DestroyTimerId(id)
          endif
      endfunction
      function Back takes unit u,real angle,real speed,real distance returns nothing
          //call Back(u,angle,speed,distance)
          local integer id
          if not IsUnitType(u, UNIT_TYPE_ANCIENT) then //无法击退古树类单位
          set id=CreateTimerId()
          set udg_DS_speed[id]=speed*MOVETIMER_TIMEOUT //速度具体化
          set udg_DS_whichUnit[id]=u
          set udg_DS_x[id]=GetUnitX(u)
          set udg_DS_y[id]=GetUnitY(u)
          set udg_DS_angle[id]=angle
          set udg_DS_distance[id]=distance
          set udg_DS_speed_x[id]=udg_DS_speed[id]*Cos(angle) //x,y速度分量
          set udg_DS_speed_y[id]=udg_DS_speed[id]*Sin(angle)
          call SetUnitFacing(u,180+angle*bj_RADTODEG)
          call TimerStart(udg_Timer[id],MOVETIMER_TIMEOUT,true,function Back_Action)
          endif
      endfunction


      3楼2011-03-09 10:07
      回复
        另一个击退, 自己指定特效. 输入null则不创建特效
        function BackEff_Action takes nothing returns nothing
            local integer id=GetTimerId()
            if udg_DS_effectPath[id]!=null then
                call DestroyEffect(AddSpecialEffectTarget(udg_DS_effectPath[id],udg_DS_whichUnit[id],"origin"))
            endif
            //特效在单位身上创建
            set udg_DS_x[id]=udg_DS_x[id]+udg_DS_speed_x[id]
            set udg_DS_y[id]=udg_DS_y[id]+udg_DS_speed_y[id]
            if not IsTerrainPathable(udg_DS_x[id], udg_DS_y[id], PATHING_TYPE_WALKABILITY) then
                //可通行直接移动
                call SetUnitX(udg_DS_whichUnit[id],udg_DS_x[id])
                call SetUnitY(udg_DS_whichUnit[id],udg_DS_y[id])
                set udg_DS_distance[id]=udg_DS_distance[id]-udg_DS_speed[id]
                if udg_DS_distance[id]<=0 then
                    call DestroyTimerId(id)
                endif
            else
                //不可通行停止移动
                call DestroyTimerId(id)
            endif
        endfunction
        function BackEff takes unit u,real angle,real speed,real distance,string effpath returns nothing
            //call Back(u,angle,speed,distance)
            local integer id
            if not IsUnitType(u, UNIT_TYPE_ANCIENT) then //无法击退古树类单位
            set id=CreateTimerId()
            set udg_DS_speed[id]=speed*MOVETIMER_TIMEOUT //速度具体化
            set udg_DS_whichUnit[id]=u
            set udg_DS_x[id]=GetUnitX(u)
            set udg_DS_y[id]=GetUnitY(u)
            set udg_DS_angle[id]=angle
            set udg_DS_distance[id]=distance
            set udg_DS_speed_x[id]=udg_DS_speed[id]*Cos(angle) //x,y速度分量
            set udg_DS_speed_y[id]=udg_DS_speed[id]*Sin(angle)
            set udg_DS_effectPath[id]=effpath
            call SetUnitFacing(u,180+angle*bj_RADTODEG)
            call TimerStart(udg_Timer[id],MOVETIMER_TIMEOUT,true,function BackEff_Action)
            endif
        endfunction


        4楼2011-03-09 10:07
        回复
          跳跃函数,从地面往高处跳,然后落下, 仅仅是跳跃, 没有改变位置的跳跃,
          配合移动函数可以做向某方向的跳跃
          function Jump_Action takes nothing returns nothing
              local integer id=GetTimerId()
              set udg_DS_distance[id]=udg_DS_distance[id]+udg_DS_speed[id] //速度改变高度
              set udg_DS_speed[id]=udg_DS_speed[id]+udg_DS_angle[id]       //加速度改变速度
              call SetUnitFlyHeight(udg_DS_whichUnit[id],udg_DS_distance[id],0)
              set udg_DS_times[id]=udg_DS_times[id]-1 //次数减1
              if udg_DS_times[id]<=0 or GetUnitState(udg_DS_whichUnit[id],UNIT_STATE_LIFE)<=0 then
                  call SetUnitFlyHeight(udg_DS_whichUnit[id],GetUnitDefaultFlyHeight(udg_DS_whichUnit[id]),0)
                  call DestroyTimerId(id)
              endif
          endfunction
          function Jump takes unit u,real height,real time returns nothing
              //call Jump(u,height,time)
              local integer id=CreateTimerId()
              set udg_DS_whichUnit[id]=u
              set udg_DS_times[id]=R2I(time/MOVETIMER_TIMEOUT)
              set udg_DS_angle[id]=-height*8/time/time*MOVETIMER_TIMEOUT*MOVETIMER_TIMEOUT //设置加速度(运动过程中为常量) 向下为负
              set udg_DS_speed[id]=height*4/time*MOVETIMER_TIMEOUT //设置当前速度(向上为正方向,不断变化)
              set udg_DS_distance[id]=GetUnitDefaultFlyHeight(u) //设置初始高度(不断变化)
              if UnitAddAbility(u,'Amrf') then
                  call UnitRemoveAbility(u,'Amrf')
              endif
              call TimerStart(udg_Timer[id],MOVETIMER_TIMEOUT,true,function Jump_Action)
          endfunction


          5楼2011-03-09 10:08
          回复
            function JumpDown_Action takes nothing returns nothing
                local integer id=GetTimerId()
                set udg_DS_distance[id]=udg_DS_distance[id]+udg_DS_speed[id] //速度改变高度
                set udg_DS_speed[id]=udg_DS_speed[id]+udg_DS_angle[id]       //加速度改变速度
                call SetUnitFlyHeight(udg_DS_whichUnit[id],udg_DS_distance[id],0)
                set udg_DS_times[id]=udg_DS_times[id]-1 //次数减1
                if udg_DS_times[id]<=0 or GetUnitState(udg_DS_whichUnit[id],UNIT_STATE_LIFE)<=0 then
                    call SetUnitFlyHeight(udg_DS_whichUnit[id],GetUnitDefaultFlyHeight(udg_DS_whichUnit[id]),0)
                    call DestroyTimerId(id)
                endif
            endfunction
            从最高点往下跳.. 自由落体, 配合移动函数就是平抛运动
            function JumpDown takes unit u,real height,real time returns nothing
                //call JumpDown(u,height,time)
                local integer id=CreateTimerId()
                set udg_DS_whichUnit[id]=u
                set udg_DS_times[id]=R2I(time/MOVETIMER_TIMEOUT)
                set udg_DS_angle[id]=-height*2/time/time*MOVETIMER_TIMEOUT*MOVETIMER_TIMEOUT //设置加速度(运动过程中为常量) 向下为负
                set udg_DS_speed[id]=0 //设置当前速度(向上为正方向,不断变化)
                set udg_DS_distance[id]=height //设置初始高度(不断变化)
                call TimerStart(udg_Timer[id],MOVETIMER_TIMEOUT,true,function JumpDown_Action)
            endfunction


            6楼2011-03-09 10:09
            回复
              //普通的移动类函数
              //call Move(u,x,y,angle,speed,distance,effpath) //普通移动函数(可带轨迹特效)
              //call Back(u,angle,speed,distance) //普通击退函数(自带轨迹特效)
              //call BackEff(u,angle,speed,distance,effpath) //普通击退函数(指定特效)
              //call Jump(u,height,time) //普通跳跃函数
              //call JumpDown(u,height,time) //从高处跳下
              // u单位   x,y坐标   angle方向(弧度制)   speed速度(距离/秒)   distance距离
              // effpath轨迹特效 height高度    time所需时间 


              7楼2011-03-09 10:09
              回复
                顶了,不过为什么一堆全局


                IP属地:广东8楼2011-03-09 15:52
                回复
                  timer data system 就是用全局数组变量储存数据的
                  可以同时支持8192个timer同时运行.所以不用担心多人使用的问题... 而且效率很高


                  9楼2011-03-09 16:58
                  回复
                    全局数组效率的确高,但是发函数的全局还是globals新建吧否则看得不太直观


                    IP属地:广东10楼2011-03-10 07:40
                    回复
                      额搞错…应该说为什么都加了一堆udg_,没有替换功能就是麻烦。


                      IP属地:广东11楼2011-03-10 07:44
                      回复
                        判断可通行方面还是用布尔建造方法比较理想,直接判定通行卡装饰物卡单位。
                        接下来是击退一直以来存在的难点,即判定不可击退地区,比如悬崖、树木、水域、单位等等,无视这些的话会导致被击退单位卡住无法动弹。以 前的方法是设置一个“探路者”的角色先行移动,并匹配“探路者”的实际坐标与所要移动的坐标是否一致,不一致的话就停止击退,这个方法虽然能解决判定问 题,但是效率的话仍稍有欠缺。因此在这里感谢<大师与天才>前不久发明的布尔值建造法,能更高效且巧妙地完成这个判断。原理:1、发布命令给单位会返回一个成功与否的布尔值。2、建造单位(不是建筑)需要所建造区域符合单位的移动类型与触碰。3、拥有“幽灵”的单位不会阻碍单位的建造。


                        IP属地:广东12楼2011-03-10 07:49
                        回复
                          udg是以前的习惯嘛,


                          13楼2011-03-10 08:45
                          回复


                            IP属地:广东14楼2011-03-10 09:06
                            回复
                              国外不是有个拿维特之脚物品法判断通行的么。。。


                              IP属地:安徽来自掌上百度15楼2012-01-02 18:29
                              回复