魔兽地图编辑器吧 关注:65,046贴子:3,836,470

【JASS】分享一个简单跳跃函数,方便复制(含方法)

只看楼主收藏回复


一楼防吞


IP属地:山西1楼2018-12-04 21:33回复
    函数简单,方便复制粘贴,只需要用到一个哈希表就行了
    先说原理:
    当单位释放跳跃技能时,创建一个每0.01秒运行一次的循环计时器
    设置speed为速度,即计时器每运行一次,单位所移动的距离
    设置distance为距离,实际作用是计时器每次运行 distance = distance - speed ,当 distance <= 1 时,停止计时器
    利用极坐标位移,在单位前方创建一个点,然后判断这个点是否可通行,计时器每次运行将单位移动到这个点上
    至于单位的高度,则是利用二次函数延伸出来的,我是百度搜索“跳跃函数”,借鉴的他人成果
    高度公式:h = -1x * x * (最高点高度/(跳跃总距离/2)^2) + 最高点高度


    IP属地:山西2楼2018-12-04 21:34
    回复(2)
      1.将代码复制到触发器内该位置

      2.创建一个名为HT的哈希表变量

      3.设置HT = (新建哈希表)
      /* 如果是使用自定义代码的话,就是 set udg_HT = InitHashtable() */

      4.设置一个指向性技能,比如用通魔做模板,我们给它起名叫“跳跃”

      5.新建一个触发器,如果所示
      事件:任意单位发动技能效果
      条件:施放技能等于跳跃
      动作:自定义代码 call HeroSkill_Jump()

      然后就可以测试效果了!


      IP属地:山西3楼2018-12-04 21:41
      回复
        /*最后,贴上代码,本楼内容全部复制*/
        //计时器步骤
        function HeroSkill_Jump_Time takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local integer int = GetHandleId(t)
        local unit u = LoadUnitHandle(udg_HT,int,0)
        local real jiaodu = LoadReal(udg_HT, int, 1)
        // distance 实际作用是用来判断计时器何时终止
        local real distance = LoadReal(udg_HT, int, 2)
        local real w = LoadReal(udg_HT, int, 3)
        local real x = LoadReal(udg_HT, int, 4)
        // speed 为单位的速度,可以自行修改
        local real speed = 10
        local location d1 = GetUnitLoc(u)
        local location d2 = PolarProjectionBJ(d1, speed, jiaodu)
        // h1 为单位跳跃的最高高度,这里设置为跳跃距离的三分之一。h2 是指当前高度,计时器每次运行都会计算,下面会讲
        local real h1 = w / 3
        local real h2
        // 如果 distance <= 1 的时候,将终止跳跃,并清理计时器
        if (distance <= 1) then
        call SetUnitFlyHeight(u, 0, 0)
        call EXSetUnitMoveType(u, 0x02 )//JAPI 设置单位移动类型为步行
        call PauseTimer(t)//暂停计时器
        call DestroyTimer(t)//删除计时器
        call FlushChildHashtable(udg_HT,int)//清空计时器的哈希表
        else
        // 设置 distance = distance - speed 并保存,而 x 则是二次函数的关键
        set distance = distance - speed
        call SaveReal(udg_HT,int,2,distance)
        set x = x + speed
        call SaveReal(udg_HT, int, 4, x)
        // h2 是计时器每运行一次的当前高度,高度计算公式 h2 = -1x * x * (h1/(w/2)^2) + h1
        set h2 = (-1 * x) * x * (h1 / Pow((w / 2), 2)) + h1
        // 判断 d2 在地图可用范围内,并且是地面单位可通行的区域。防止技能超出地图边界造成崩溃。
        // 如果 d2 超出可用范围,将强行停止跳跃技能
        // 想让跳跃技能跨越地形的话,需要删掉 and (IsTerrainPathableBJ(d2, PATHING_TYPE_WALKABILITY) == false) 这部分
        if (RectContainsLoc(GetPlayableMapRect(), d2) == true) and (IsTerrainPathableBJ(d2, PATHING_TYPE_WALKABILITY) == false) then
        call SetUnitPositionLoc(u, d2)
        call SetUnitFlyHeight(u, h2, 0)
        else
        set distance = 0
        call SaveReal(udg_HT,int,2,distance)
        endif
        endif
        //排泄
        call RemoveLocation(d1)
        call RemoveLocation(d2)
        set t = null
        set u = null
        set d1 = null
        set d2 = null
        endfunction
        //跳跃函数 HeroSkill_Jump
        function HeroSkill_Jump takes nothing returns nothing
        local timer t = CreateTimer()
        local integer int = GetHandleId(t)
        local unit u = GetTriggerUnit()
        local location d1 = GetUnitLoc(u)
        local location d2 = GetSpellTargetLoc()
        local real jiaodu = AngleBetweenPoints(d1, d2)
        local real w = DistanceBetweenPoints(d1, d2)
        local real x = 0 - (w / 2)
        //为单位添加并删除(风暴之鸦)技能,必要操作
        call UnitAddAbility(u,'Arav')
        call UnitRemoveAbility(u,'Arav')
        call EXSetUnitMoveType(u, 0x04 )//JAPI 设置单位移动类型为飞行
        //保存关键数据到哈希表,供计时器调取
        call SaveUnitHandle(udg_HT,int,0,u)
        call SaveReal(udg_HT, int, 1, jiaodu)
        call SaveReal(udg_HT, int, 2, w)
        call SaveReal(udg_HT, int, 3, w)
        call SaveReal(udg_HT, int, 4, x)
        //开始计时器
        call TimerStart(t, 0.01, true, function HeroSkill_Jump_Time)
        //排泄
        call RemoveLocation(d1)
        call RemoveLocation(d2)
        set t = null
        set u = null
        set d1 = null
        set d2 = null
        endfunction


        IP属地:山西4楼2018-12-04 21:42
        回复
          代码排版对照图



          IP属地:山西5楼2018-12-04 21:43
          回复
            啊,原来不是坐标


            来自Android客户端6楼2018-12-04 22:14
            回复
              虽然看不懂J,但还是谢谢分享


              IP属地:湖南7楼2018-12-04 22:16
              回复
                用j不用t,用点不用坐标,我都可以理解,可你还用japi就过分了,跳跃哪那么复杂


                IP属地:山西来自Android客户端8楼2018-12-04 22:58
                收起回复
                  楼主真牛逼,楼上的都是渣渣,不用管他们


                  IP属地:广东来自Android客户端9楼2018-12-04 23:10
                  收起回复
                    ydwe好像有一个跳跃函数...


                    IP属地:福建来自iPhone客户端10楼2018-12-05 00:35
                    收起回复
                      优秀


                      IP属地:广东来自Android客户端13楼2018-12-05 08:35
                      回复
                        还不如indexer冲锋


                        14楼2018-12-05 09:11
                        回复
                          连个参数都没有,你让别人每个跳跃都要重新复制修改么 还有这个公式怎么看着这么想ydwe的那个,或许我看错了


                          来自Android客户端15楼2018-12-05 11:10
                          回复(1)
                            /*增加了一个速度参数,删除了JAPI内容,本楼内容全部复制*/
                            //计时器步骤
                            function HeroSkill_Jump_Time takes nothing returns nothing
                            local timer t = GetExpiredTimer()
                            local integer int = GetHandleId(t)
                            local unit u = LoadUnitHandle(udg_HT,int,0)
                            local real jiaodu = LoadReal(udg_HT, int, 1)
                            // distance 实际作用是用来判断计时器何时终止
                            local real distance = LoadReal(udg_HT, int, 2)
                            local real w = LoadReal(udg_HT, int, 3)
                            local real x = LoadReal(udg_HT, int, 4)
                            local real speed = LoadReal(udg_HT, int, 5)
                            local location d1 = GetUnitLoc(u)
                            local location d2 = PolarProjectionBJ(d1, speed, jiaodu)
                            // h 为单位跳跃的最高高度,这里设置为跳跃距离的三分之一。z 是指单位的Z轴高度,计时器每次运行都会计算,下面会讲
                            local real h = w / 3
                            local real z
                            // 如果 distance <= 1 的时候,将终止跳跃,并清理计时器
                            if (distance <= 1) then
                            call SetUnitFlyHeight(u, 0, 0)
                            call PauseTimer(t)//暂停计时器
                            call DestroyTimer(t)//删除计时器
                            call FlushChildHashtable(udg_HT,int)//清空计时器的哈希表
                            else
                            // 设置 distance = distance - speed 并保存,而 x 则是二次函数的关键
                            set distance = distance - speed
                            call SaveReal(udg_HT,int,2,distance)
                            set x = x + speed
                            call SaveReal(udg_HT, int, 4, x)
                            // z 是计时器每运行一次的单位的Z轴高度,高度计算公式 z = -1x * x * (h/(w/2)^2) + h
                            set z = (-1 * x) * x * (h / Pow((w / 2), 2)) + h
                            // 判断 d2 在地图可用范围内,并且是地面单位可通行的区域。防止技能超出地图边界造成崩溃。
                            // 如果 d2 超出可用范围,将强行停止跳跃技能
                            // 想让跳跃技能跨越地形的话,需要删掉 and (IsTerrainPathableBJ(d2, PATHING_TYPE_WALKABILITY) == false) 这部分
                            if (RectContainsLoc(GetPlayableMapRect(), d2) == true) and (IsTerrainPathableBJ(d2, PATHING_TYPE_WALKABILITY) == false) then
                            call SetUnitPositionLoc(u, d2)
                            call SetUnitFlyHeight(u, z, 0)
                            else
                            set distance = 0
                            call SaveReal(udg_HT,int,2,distance)
                            endif
                            endif
                            call RemoveLocation(d1)
                            call RemoveLocation(d2)
                            set t = null
                            set u = null
                            set d1 = null
                            set d2 = null
                            endfunction
                            //跳跃函数 HeroSkill_Jump
                            function HeroSkill_Jump takes real speed returns nothing
                            local timer t = CreateTimer()
                            local integer int = GetHandleId(t)
                            local unit u = GetTriggerUnit()
                            local location d1 = GetUnitLoc(u)
                            local location d2 = GetSpellTargetLoc()
                            local real jiaodu = AngleBetweenPoints(d1, d2)
                            local real w = DistanceBetweenPoints(d1, d2)
                            local real x = 0 - (w / 2)
                            //为单位添加并删除(风暴之鸦)技能,必要操作
                            call UnitAddAbility(u,'Arav')
                            call UnitRemoveAbility(u,'Arav')
                            //保存关键数据到哈希表,供计时器调取
                            call SaveUnitHandle(udg_HT,int,0,u)
                            call SaveReal(udg_HT, int, 1, jiaodu)
                            call SaveReal(udg_HT, int, 2, w)
                            call SaveReal(udg_HT, int, 3, w)
                            call SaveReal(udg_HT, int, 4, x)
                            call SaveReal(udg_HT, int, 5, speed)
                            //开始计时器
                            call TimerStart(t, 0.01, true, function HeroSkill_Jump_Time)
                            call RemoveLocation(d1)
                            call RemoveLocation(d2)
                            set t = null
                            set u = null
                            set d1 = null
                            set d2 = null
                            endfunction


                            IP属地:山西18楼2018-12-05 13:45
                            收起回复
                              我寻思要不要判断u是否存活


                              IP属地:云南19楼2018-12-08 00:21
                              回复