13lade619
is now a game developer :)
- Reaction score
- 399
This tutorial will show you how to make ‘close-to-real’ jumps, using a physics equation.
First off, the vertical jump. (forward jump will be added later.)
Ok.. let’s start with a simple lesson in physics/calculus.
THE PHYSICS OF JUMPING : VERTICAL
Acceleration : the change of velocity over time.
*Calculating for velocity.*
And because the object is falling, it has constant acceleration due to gravity.
And it is also negative because it is pulling downwards.
Now if we take the formula and isolate dV,
now integrate to solve for V,
That gives us a new variable c, which is the initial velocity.
Let’s denote that by vi.
This is now our equation for velocity based on a
given acceleration due to gravity in a given timeframe T,
plus an initial velocity vi going upwards (of course you need to push the object upward).
Velocity : the change of displacement over time.
*Calculating for z-height.*
Now to keep track of the displacement of our unit, we need to see the height of the object,
Its displacement, denote by Z.
Same as before, we isolate then integrate.
dZ = V *dT, but because we have an equation for V...
dZ = (-A*T + vi)dT, then
Z = (-A/2)*T^2 + vi*T + c
The c another constant for the initial displacement, so we dont need that for now since we are jumping in a level plane.
Now we have a formula to track the displacement Z of a unit through time T as it jumps
Given that we have a constant acceleration due to gravity A
And an initial velocity vi that pushes it upward.
And because A and vi are constants, we can solve for T.
In this, we solve for when Z reaches 0 again,
showing that the unit has reached ground.
*Calculating for hangtime formula.*
And we have the ‘hangtime’ formula needed in the next chapter of the lesson later.
We can also calculate for the maximum height reached by the object of anyone is interested..
Maximum height is attained when velocity is zero,
which is when the object is at the topmost point,
when it makes the transition from upward to downward motion.
*Calculating for V=0.*
We got the T for which V = 0.
Now use that T value in the Z equation to obtain maximum Z.
Z = (-A/2)*T^2 + vi*T
//============================================================
TRIGGERING A VERTICAL JUMP
//============================================================
FORWARD JUMPING
>> In this method we will be 'assigning' a forward speed (wc3 units / time) to travel from point a to point b.
Then we will have formulas to take care of the jumping.
Reviewing some ideas:
Basically we want to precisely time the jump and move so that the unit will reach its target point and at the same time fall from the jump. And we will only be using a given forward speed that you will assign, then the formula will calculate for vertical speed so that times will match.
So now we want to equate the time of the 2 events :
(FDistance/FSpeed) = (VVelocity/(VGravity/2))
^Now to isolate VVelocity, we multiply by VGravity/2 both sides; which cancels the left side.
so we have this equation for VVelocity:
((VGravity/2)*FDistance)/FSpeed = VVelocity
And that's *basically* all what we need to make a forward jump.
B U T . . .
By thoroughly testing some triggers i made, the jump is sometimes unnoticeable due to the fast speeds of the forward jump..
So, I've come up with a solution :
multiplying the gravity and upward velocity by a factor of the speed so that the caster will jump higher.
Like this : (by a factor of 300)
vi = vi * (fs/300)
A = A * (fs/300)
So now, to the triggers:
//============================================================
TRIGGERING A FORWARD JUMP
//============================================================
Thanks for reading and i hope you learned something today.
First off, the vertical jump. (forward jump will be added later.)
Ok.. let’s start with a simple lesson in physics/calculus.
THE PHYSICS OF JUMPING : VERTICAL
Acceleration : the change of velocity over time.
*Calculating for velocity.*
A = dV/dT
And because the object is falling, it has constant acceleration due to gravity.
And it is also negative because it is pulling downwards.
-A = constant
Now if we take the formula and isolate dV,
dV = (-A)dT
now integrate to solve for V,
V = -A*T + c
That gives us a new variable c, which is the initial velocity.
Let’s denote that by vi.
This is now our equation for velocity based on a
given acceleration due to gravity in a given timeframe T,
plus an initial velocity vi going upwards (of course you need to push the object upward).
V = -A*T + vi
Velocity : the change of displacement over time.
*Calculating for z-height.*
V = dZ/dT
V = -A*T + vi
Now to keep track of the displacement of our unit, we need to see the height of the object,
Its displacement, denote by Z.
Same as before, we isolate then integrate.
dZ = V *dT, but because we have an equation for V...
dZ = (-A*T + vi)dT, then
Z = (-A/2)*T^2 + vi*T + c
The c another constant for the initial displacement, so we dont need that for now since we are jumping in a level plane.
Now we have a formula to track the displacement Z of a unit through time T as it jumps
Given that we have a constant acceleration due to gravity A
And an initial velocity vi that pushes it upward.
Z = (-A/2)*T^2 + vi*T
And because A and vi are constants, we can solve for T.
In this, we solve for when Z reaches 0 again,
showing that the unit has reached ground.
*Calculating for hangtime formula.*
Set Z to 0
0 = (-A/2)*T^2 + vi*T
Move the negative half to the other side, nullifying negative sign.(A/2)*T^2 = vi*T
Divide by T to eliminate it from the right side and we have:(A/2)*T = vi
Now we divide by the acceleration/2 to isolate T.T = vi / (A/2)
And we have the ‘hangtime’ formula needed in the next chapter of the lesson later.
T = vi / (A/2)
We can also calculate for the maximum height reached by the object of anyone is interested..
Maximum height is attained when velocity is zero,
which is when the object is at the topmost point,
when it makes the transition from upward to downward motion.
*Calculating for V=0.*
From the V formula,
V = -A*T + vi
Set V to 0,0 = -A*T + vi
Then to the other side again,A*T = vi
DivisionT = vi/A
We got the T for which V = 0.
Now use that T value in the Z equation to obtain maximum Z.
Z = (-A/2)*T^2 + vi*T
//============================================================
TRIGGERING A VERTICAL JUMP
These sample actions will make a unit jump vertically when it casts an ability.
And now we test vertical jump in a trigger:
Use a simple ‘starts the effect of ability’ event, and ability comparison condition.
And a struct:
and also, a struct to timer attachment system.
In this tutorial, we will be using Timer Ticker from Cohadar
Here’s the actions, with comments of course.
Now the JumpFunc
And now we test vertical jump in a trigger:
Use a simple ‘starts the effect of ability’ event, and ability comparison condition.
And a struct:
JASS:
and also, a struct to timer attachment system.
In this tutorial, we will be using Timer Ticker from Cohadar
Here’s the actions, with comments of course.
JASS:
function Jump_Actions takes nothing returns nothing
//caster and struct only, since we're just dealing with flyheight.
local jump j = jump.create()
//set the struct values.
set j.caster = GetTriggerUnit() // Caster
//just play around with the constants..
//i have these for the example.
set j.A = 3200 //from the real 32 ft/sec^2.
set j.vi = 1000 //pushed up at a speed of 1000.
//Crow Form for flying.
call UnitAddAbility(j.caster,039;Amrf039;)
call UnitRemoveAbility(j.caster,039;Amrf039;)
//i'm using Cohadar's TT by the way, you can search it on the site.
call TT_Start(function JumpFunc, j)
endfunction
Now the JumpFunc
JASS:
function JumpFunc takes nothing returns boolean
//get the struct from the timer.
local jump j = TT_GetData()
//increment the time value with the periodic timeout of the expiring timer.
set j.T = j.T + .035
//now using our formula for displacement : Z = (-A/2)*T^2 + vi*T
set j.Z = ((-j.A/2)*(j.T*j.T)) + (j.vi*j.T)
//set the flying height of the caster.
call SetUnitFlyHeight(j.caster,j.Z,0)
// if object fell to the ground already, then stop the trigger.
if j.Z <= 0 then
//take care of the leaks and finish off.
set j.caster = null
call j.destroy()
return true
else
return false
endif
endfunction
FORWARD JUMPING
>> In this method we will be 'assigning' a forward speed (wc3 units / time) to travel from point a to point b.
Then we will have formulas to take care of the jumping.
Reviewing some ideas:
Forward Movement
Forward Speed = ( Travel Distance / Travel Time )
Time = Distance / Speed
Vertical Jump
Hangtime = T = ( Initial Velocity / ( Gravity / 2 ) )
Basically we want to precisely time the jump and move so that the unit will reach its target point and at the same time fall from the jump. And we will only be using a given forward speed that you will assign, then the formula will calculate for vertical speed so that times will match.
So now we want to equate the time of the 2 events :
(FDistance/FSpeed) = (VVelocity/(VGravity/2))
^Now to isolate VVelocity, we multiply by VGravity/2 both sides; which cancels the left side.
so we have this equation for VVelocity:
((VGravity/2)*FDistance)/FSpeed = VVelocity
And that's *basically* all what we need to make a forward jump.
B U T . . .
By thoroughly testing some triggers i made, the jump is sometimes unnoticeable due to the fast speeds of the forward jump..
So, I've come up with a solution :
multiplying the gravity and upward velocity by a factor of the speed so that the caster will jump higher.
Like this : (by a factor of 300)
vi = vi * (fs/300)
A = A * (fs/300)
So now, to the triggers:
//============================================================
TRIGGERING A FORWARD JUMP
Use a simple ‘starts the effect of ability’ event, and ability comparison condition.
And a struct.
and also, a struct to timer attachment system.
In this tutorial, we will be using Timer Ticker from Cohadar
Here's a sample trigger w/ Comments.
And a struct.
and also, a struct to timer attachment system.
In this tutorial, we will be using Timer Ticker from Cohadar
Here's a sample trigger w/ Comments.
JASS:
struct jump
unit caster
real A //Gravity set later
real vi //Vi calculated later
real fs //forward speed you set.
real angle
//counters Z and T, incremented later so add a starting value 0 for simplicity
real Z = 0
real T = 0
endstruct
function JumpFuncFly takes nothing returns boolean
//get the struct from the timer.
local jump j = TT_GetData()
// we divide j.fs by 28.57 because you need j.fs units/second.
// but the interval is .035 and 1/.035 = 28.57
local real NX = GetUnitX(j.caster) + (j.fs/28.57) * Cos(j.angle * bj_DEGTORAD)
local real NY = GetUnitY(j.caster) + (j.fs/28.57) * Sin(j.angle * bj_DEGTORAD)
//increment the time value with the periodic timeout of the expiring timer.
set j.T = j.T + .035
//now using our formula for displacement : Z = (-A/2)*T^2 + vi*T
set j.Z = ((-j.A/2)*(j.T*j.T)) + (j.vi*j.T)
//move the caster..
call SetUnitX(j.caster,NX)
call SetUnitY(j.caster,NY)
call BJDebugMsg(R2S(j.Z))
//set the flying height of the caster.
call SetUnitFlyHeight(j.caster,j.Z,0)
// if object fell to the ground already, then stop the trigger.
if j.Z <= 0 then
//take care of the leaks and finish off.
set j.caster = null
call j.destroy()
return true
else
return false
endif
endfunction
function Trig_JumpFunc_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 039;AOwk039; //Using Wind Walk.
endfunction
function Trig_JumpFunc_Actions takes nothing returns nothing
local unit caster = GetTriggerUnit()
local location cp = GetUnitLoc(caster)
//Since i'm using Wind Walk, it's instant so i need to set the target point manually.
local location tp = PolarProjectionBJ(cp, 500, GetUnitFacing(caster))
//You should use this if you have a point target ability:
//local location tp = GetSpellTargetLoc()
//You should use this if you have a unit target ability:
//local location tp = GetUnitLoc(target)
local jump j = jump.create()
//set the struct values.
set j.caster = caster
//Now set the gravity constant, vi will be set later.
set j.A = 3200
set j.angle = AngleBetweenPoints(cp,tp)
set j.fs = 2000 //depends upon you.
//(FDistance/FSpeed) = (VVelocity/(VGravity/2))
//^Now to isolate VVelocity, we multiply by VGravity/2 both sides; which cancels the left side.
//so we have this equation for VVelocity:
//((VGravity/2)*FDistance)/FSpeed = VVelocity
set j.vi = (DistanceBetweenPoints(cp,tp)*( j.A/2 )) / (j.fs)
//through hi-speeds, the normal jump may be unnoticeable.
//we multiply the values by j.fs/300 to overcome that.
set j.vi = j.vi * (j.fs/300)
set j.A = j.A * (j.fs/300)
call BJDebugMsg(R2S(j.vi))
call AddSpecialEffectLoc("Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl",tp)
//Crow Form for flying.
call UnitAddAbility(j.caster,039;Amrf039;)
call UnitRemoveAbility(j.caster,039;Amrf039;)
//Start the Timer.
call TT_Start(function JumpFuncFly, j)
call RemoveLocation(cp)
call RemoveLocation(tp)
set cp = null
set tp = null
endfunction
//===========================================================================
function InitTrig_JumpFunc takes nothing returns nothing
set gg_trg_JumpFunc = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_JumpFunc, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_JumpFunc, Condition( function Trig_JumpFunc_Conditions ) )
call TriggerAddAction( gg_trg_JumpFunc, function Trig_JumpFunc_Actions )
endfunction
Thanks for reading and i hope you learned something today.