HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Maths Enquires

06-17-2009, 11:12 AM#1
wraithseeker
Collapse JASS:
library VerticalJump uses AutoIndex


//=================================================================
//                  HOW TO USE ?
//=================================================================
//
//  function ThrowUnitToAir takes unit u, real velocity returns nothing
//
//     -This is used to throw unit in to the air
//
//
//  function SetUnitGravity takes unit u, real gravity, returns nothing
//
//    - this can be used to change untis gravity
//    - use it only after you have called ThrowUnitToAir
//
//
//=================================================================
//                 SYSTEM CODE:
//=================================================================

globals
    private constant real TIMEOUT = 0.03
    private constant real DEFAULT_GRAVITY = 1. // notice this as gravity
    private constant integer FLY_ID = 'Amrf'
    private timer Timer = CreateTimer()
    private integer Count = 0
    private group HitGroup = CreateGroup()
    private integer array FlyZ
endglobals

struct VelocityJump   
    unit target
    real positionZ 
    real velocityZ 
    real gravity 
    
    static method create takes unit u, real velocity returns VelocityJump
        local VelocityJump d = VelocityJump.allocate()
        set d.target = u
        set d.velocityZ = velocity
        set d.gravity = -(DEFAULT_GRAVITY/2.)
        call UnitAddAbility(u,FLY_ID)
        call UnitRemoveAbility(u,FLY_ID)
        return d
    endmethod
    
    method onDestroy takes nothing returns nothing
        call GroupRemoveUnit(HitGroup,.target)
    endmethod
    implement AutoData
endstruct

private function Periodic takes nothing returns nothing
        local integer i = 0
        local VelocityJump d
        loop
            exitwhen i >= Count
            set d = FlyZ[i]
            set d.velocityZ= d.velocityZ+ d.gravity
            set d.positionZ= d.positionZ+ d.velocityZ
            set d.velocityZ= d.velocityZ+ d.gravity
            call SetUnitFlyHeight(d.target,d.positionZ,0.0)
            if d.positionZ <= 0.0 then
                call d.destroy()
                set Count = Count - 1
                if Count > 0 then
                    set FlyZ[i] = FlyZ[Count]
                    set i = i - 1
                else
                    call PauseTimer(Timer)
                endif
            endif
            set i = i + 1
        endloop
    endfunction
    
function ThrowUnitToAir takes unit u, real velocity returns nothing
        local VelocityJump d
        if IsUnitInGroup(u,HitGroup) then
            set d = VelocityJump[u]
            set d.velocityZ = d.velocityZ+velocity
        else
            if Count == 0 then
                call TimerStart(Timer,TIMEOUT,true,function Periodic)
            endif
            set d = VelocityJump.create(u,velocity)
            set VelocityJump[u] = d
            set FlyZ[Count] = d
            set Count = Count + 1
            call GroupAddUnit(HitGroup,u)
        endif
endfunction

function SetUnitGravity takes unit u, real gravity returns nothing
     local VelocityJump d = VelocityJump[u]
     if IsUnitInGroup(u,HitGroup) then
        set d.gravity= -(gravity/2.)
    endif
endfunction

function IsUnitFlying takes unit u returns boolean
    return IsUnitInGroup(u,HitGroup)
endfunction

endlibrary

Am I doing the maths right for this system? I use this system for vertical jumps only.
06-17-2009, 11:27 AM#2
Opossum
Why are you adding gravity twice in the periodic loop?
Collapse JASS:
            set d.velocityZ= d.velocityZ+ d.gravity
            set d.positionZ= d.positionZ+ d.velocityZ
            set d.velocityZ= d.velocityZ+ d.gravity
Also you should add the timer timeout to these calculations
Collapse JASS:
            set d.velocityZ= d.velocityZ+ d.gravity*TIMEOUT
            set d.positionZ= d.positionZ+ d.velocityZ*TIMEOUT
This ensures that higher timeouts don't screw up the calculations.
Physic formulas: v = v0 + a * t
and: x = x0 + v * t
which is practically what you have there so yes, physics (and maths) are right.

But why are you dividing gravity by 2 in the gravity function?
Collapse JASS:
function SetUnitGravity takes unit u, real gravity returns nothing
     local VelocityJump d = VelocityJump[u]
     if IsUnitInGroup(u,HitGroup) then
        set d.gravity= -(gravity/2.)
    endif
endfunction
Maybe because you're adding gravity twice in the loop?
06-17-2009, 12:00 PM#3
moyack
Do you remember the parabolic movement test map?

if you set an elevation angle of 90º, you'll get this effect.