简单的移动类函数...
永恒的灌水帝吧
全部回复
仅看楼主
level 1
秋瀞葉 楼主
首先是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
2011年03月09日 02点03分 1
level 1
秋瀞葉 楼主
只是个普通的移动函数
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
2011年03月09日 02点03分 2
为什么用destroytimer啊,那一开始新建的计时器不就被删掉了,以后不能用了么?
2014年03月11日 15点03分
回复 landvin :[委屈]哎哟,眼拙了,DestroyTimerId那是之前的函数
2014年03月11日 15点03分
level 1
秋瀞葉 楼主
击退函数, 路径特效是花岗石怪的攻击投射物不可更改
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
2011年03月09日 02点03分 3
level 1
秋瀞葉 楼主
另一个击退, 自己指定特效. 输入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
2011年03月09日 02点03分 4
level 1
秋瀞葉 楼主
跳跃函数,从地面往高处跳,然后落下, 仅仅是跳跃, 没有改变位置的跳跃,
配合移动函数可以做向某方向的跳跃
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
2011年03月09日 02点03分 5
level 1
秋瀞葉 楼主
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
2011年03月09日 02点03分 6
level 1
秋瀞葉 楼主
//普通的移动类函数
//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所需时间 
2011年03月09日 02点03分 7
level 15
顶了,不过为什么一堆全局
2011年03月09日 07点03分 8
level 1
秋瀞葉 楼主
timer data system 就是用全局数组变量储存数据的
可以同时支持8192个timer同时运行.所以不用担心多人使用的问题... 而且效率很高
2011年03月09日 08点03分 9
level 15
全局数组效率的确高,但是发函数的全局还是globals新建吧否则看得不太直观
2011年03月09日 23点03分 10
level 15
额搞错…应该说为什么都加了一堆udg_,没有替换功能就是麻烦。
2011年03月09日 23点03分 11
level 15
判断可通行方面还是用布尔建造方法比较理想,直接判定通行卡装饰物卡单位。
接下来是击退一直以来存在的难点,即判定不可击退地区,比如悬崖、树木、水域、单位等等,无视这些的话会导致被击退单位卡住无法动弹。以 前的方法是设置一个“探路者”的角色先行移动,并匹配“探路者”的实际坐标与所要移动的坐标是否一致,不一致的话就停止击退,这个方法虽然能解决判定问 题,但是效率的话仍稍有欠缺。因此在这里感谢<大师与天才>前不久发明的布尔值建造法,能更高效且巧妙地完成这个判断。原理:1、发布命令给单位会返回一个成功与否的布尔值。2、建造单位(不是建筑)需要所建造区域符合单位的移动类型与触碰。3、拥有“幽灵”的单位不会阻碍单位的建造。
2011年03月09日 23点03分 12
level 1
秋瀞葉 楼主
udg是以前的习惯嘛,
2011年03月10日 00点03分 13
level 15

2011年03月10日 01点03分 14
level 4
国外不是有个拿维特之脚物品法判断通行的么。。。
2012年01月02日 10点01分 15
level 12
因为习惯所以加udg前缀吗
2016年12月20日 14点12分 16
1