Game Development Community

dev|Pro Game Development Curriculum

Double/Air Jump

by Jeremy Alessi · 02/15/2005 (9:56 am) · 23 comments

Here I am very happy to post my first resource which is a modification to the C++ core of the Torque ;)

To begin open the player.h file of the Torque SDK. Find this line:

S32 splashEmitterIDList[NUM_SPLASH_EMITTERS];

Afterward add this:

bool doubleJumpEnabled;
   F32 doubleJumpDelay;
   F32 doubleJumpForce;
   F32 doubleJumpMinHeight;
   F32 doubleJumpMaxHeight;


Now find this line:

S32  mContactTimer;              ///< Ticks since last contact

After add this:

bool mDoubleJumped;

OK, that's all for the player.h file. Now open the player.cc file.

Find these 3 lines:

mActionAnimation.atEnd = false;
   mState = MoveState;
   mFalling = false;

Under those add:

mDoubleJumped = false;

Then find:

else
      mContactTimer++;

After that decision structure and before this:

else
      if (jumpSurface) {
         if (mJumpDelay > 0)
            mJumpDelay--;
         mJumpSurfaceLastContact = 0;
      }

Replace the existing code between those above items with:

if (jumpSurface)
   { 
	  mDoubleJumped = false;
   }
   Point3F pos;
   getTransform().getColumn(3,&pos);
   // Acceleration from Jumping
   if ( ( move->trigger[2] && !isMounted() && canJump() ) || ( (mDataBlock->doubleJumpEnabled == true) && (move->trigger[2]) && (mDoubleJumped == false) && (mContactTimer > mDataBlock->doubleJumpDelay) && (pos.z > mDataBlock->doubleJumpMinHeight) && (pos.z < mDataBlock->doubleJumpMaxHeight)) )    
   {
      
	  // Scale the jump impulse base on maxJumpSpeed
      F32 zSpeedScale = mVelocity.z;
      if (zSpeedScale <= mDataBlock->maxJumpSpeed) 
      {
         zSpeedScale = (zSpeedScale <= mDataBlock->minJumpSpeed)? 1:
            1 - (zSpeedScale - mDataBlock->minJumpSpeed) /
            (mDataBlock->maxJumpSpeed - mDataBlock->minJumpSpeed);

         // Desired jump direction
         VectorF pv = moveVec;
         F32 len = pv.len();
         if (len > 0)
            pv *= 1 / len;

         // We want to scale the jump size by the player size, somewhat
         // in reduced ratio so a smaller player can jump higher in
         // proportion to his size, than a larger player.
         F32 scaleZ = (getScale().z * 0.25) + 0.75;

         // If we are facing into the surface jump up, otherwise
         // jump away from surface.
         F32 dot = mDot(pv,mJumpSurfaceNormal);
         F32 impulse = mDataBlock->jumpForce / mMass;
		 F32 doubleJumpImpulse = mDataBlock->doubleJumpForce;
         if (dot <= 0)
         {
		    if (jumpSurface)
			{
			   acc.z += mJumpSurfaceNormal.z * scaleZ * impulse * zSpeedScale;
            }
			else
			{
			   acc.z += scaleZ * doubleJumpImpulse;
			   mDoubleJumped = true;
			}			
		 }
		 else 
         {
            acc.x += pv.x * impulse * dot;
            acc.y += pv.y * impulse * dot;
            if (jumpSurface)
			{
			  acc.z += mJumpSurfaceNormal.z * scaleZ * impulse * zSpeedScale;
            }
			else 
			{
			   acc.z += scaleZ * doubleJumpImpulse;
			   mDoubleJumped = true;
			}            
         }

         mJumpDelay = mDataBlock->jumpDelay;
         mEnergy -= mDataBlock->jumpEnergyDrain;
         
         setActionThread((mVelocity.len() < 0.5)?
            PlayerData::StandJumpAnim: PlayerData::JumpAnim, true, false, true);
         mJumpSurfaceLastContact = JumpSkipContactsMax;
      }
   }

Afterward find this bit:

if (stream->writeFlag(mask & MoveMask)) 
   {
      stream->writeFlag(mFalling);

Add this below:

stream->writeFlag(mDoubleJumped);

Then find:

if (stream->readFlag()) {
      mPredictionCount = sMaxPredictionTicks;
      mFalling = stream->readFlag();

Add:

mDoubleJumped = stream->readFlag();

Find:

groundImpactShakeFalloff = 10.0;

Add:

doubleJumpEnabled = false;
   doubleJumpDelay = 0.0f;
   doubleJumpForce = 0.0f;
   doubleJumpMinHeight = 0.0f;
   doubleJumpMaxHeight = 0.0f;

Find:

addField("groundImpactShakeFalloff",   TypeF32, Offset(groundImpactShakeFalloff,    PlayerData));

Add:

addField("doubleJumpEnabled", TypeBool, Offset(doubleJumpEnabled, PlayerData));
   addField("doubleJumpDelay", TypeF32, Offset(doubleJumpDelay, PlayerData));   	
   addField("doubleJumpForce", TypeF32, Offset(doubleJumpForce, PlayerData));
   addField("doubleJumpMinHeight", TypeF32, Offset(doubleJumpMinHeight, PlayerData));
   addField("doubleJumpMaxHeight", TypeF32, Offset(doubleJumpMaxHeight, PlayerData));


Find:

stream->write(groundImpactShakeFalloff);

Add:

stream->write(doubleJumpEnabled);
   stream->write(doubleJumpDelay);
   stream->write(doubleJumpForce);
   stream->write(doubleJumpMinHeight);
   stream->write(doubleJumpMaxHeight);

Find:

stream->read(&groundImpactShakeFalloff);

Add:

stream->read(&doubleJumpEnabled);
   stream->read(&doubleJumpDelay);
   stream->read(&doubleJumpForce);
   stream->read(&doubleJumpMinHeight);
   stream->read(&doubleJumpMaxHeight);

Then under the player.cs TorqueScript file find:

datablock PlayerData(PlayerBody)
{

Add:

doubleJumpEnabled = true;
   doubleJumpDelay = 50;
   doubleJumpForce = 100;
   doubleJumpMinHeight = 150;
   doubleJumpMaxHeight = 300;

This means that the player can double jump, the player must wait 50 ticks after leaving a surface from which it can jump before double jumping, the impulse the player jumps with is 100, player must be above 150 units to double jump, the player must be below 300 units to double jump.

OK, so there it is ... I think that's all of it anyway. Of course this code could be improved upon in many ways but the basic gist is there so do with it what you'd like and have fun!
Page «Previous 1 2
#1
02/15/2005 (11:43 am)
Excellent, I was looking into something like this for my platformer. Sweet.
#2
02/15/2005 (3:17 pm)
thanks!! this could work as a jetpack pretty much
#3
02/15/2005 (7:56 pm)
Ahh, the first step towards Torque Excessive :)
#4
02/15/2005 (8:25 pm)
Yeah, I was thinking that as well and figured maybe Aerial Antics 2 could be a Torque game with some hot multiplayer ;)
#5
04/20/2005 (8:46 am)
Great thanks a lot, this will be great for my game, A* resource.
#6
05/06/2005 (4:40 am)
I did everything as instructed but my character just jumped higher. Btw I already repeated this 3 times. Is there something I missed?
#7
08/12/2005 (10:53 am)
...i ahd the same problem. I had my delay set to 0 since 50 is really long in my tickrate. Since it was zeo, it'd instantly double jump. Also, if ur in starter.fps, 100 is a huge double jump, while 10 is about right.
#8
07/12/2007 (1:14 pm)
Great resource. It worked like a dream.
#9
12/16/2007 (5:37 pm)
does anyone know if this works with 1.5.2?
#10
02/10/2008 (7:11 am)
I thought its time for me to contribute something to this great community.
Here's how you can play a different animation while double jumping (for example a flip)

in player.cc search for this line:
{ "land" }, // LandAnim

and add this below it:
{ "flip" }, // FlipAnim

now search for these lines:

setActionThread((mVelocity.len() < 0.5)?:
PlayerData::StandJumpAnim: PlayerData::JumpAnim, true, false, true);

and replace them with:

if (mDoubleJumped) {
setActionThread((mVelocity.len() < 0.5)?
PlayerData::FlipAnim: PlayerData::FlipAnim, true, false, true);
} else {
setActionThread((mVelocity.len() < 0.5)?
PlayerData::StandJumpAnim: PlayerData::JumpAnim, true, false, true);
}

in player.h search for this line:

LandAnim,

and add this below it:

FlipAnim,

now replace this line:
NumTableActionAnims = LandAnim + 1,

with this line:
NumTableActionAnims = FlipAnim + 1,

replace this line (your number could be different):
NumExtraActionAnims = 512,

with this line:
NumExtraActionAnims = 511, // was 512

replace this line (your number could be different):
ActionAnimBits = 9,

with this line:
ActionAnimBits = 10, // was 9

Don't forget to add your animation "flip" to your player animation script!

and now (if i didn't forget anything) you should see your flip animation played when you double jump :-)

@ Jermaine M.
It works with 1.5.2
#11
02/15/2008 (2:22 pm)
Thanks for this excellent resource! It was just what I needed (both as a way to implement multiple jumps and more importantly a great introduction to modifying player movement through source modifications). Thanks.

I do have a question though: I modified this to allow an arbitrary number of air jumps, however, I noticed that the you can just hold down the space bar to achieve this. How can I modify this to make it so the player has to press the space bar for each jump?

Thanks!
#12
02/16/2008 (3:10 am)
@Mike Treanor

here's one way to do that:

edit your default.bind.cs (found in client/scripts)

and replace this line:
$mvTriggerCount2++;

with this line:
if (%val) {
$mvTriggerCount2++; // Trigger Jump
$mvTriggerCount2++; // Stop Jumping
}

That should do it :-)
#13
02/24/2008 (4:56 pm)
Seems to work well in 1.5.2.

I have this combined with the Air Control resource. had to modify a few datablock values for it to work

doubleJumpEnabled = true;
doubleJumpDelay = 10;
doubleJumpForce = 10;
doubleJumpMinHeight = 150;
doubleJumpMaxHeight = 300;

these are the settings i'm using to get the player to double jump.
#14
06/15/2008 (7:25 pm)
This is an awesome resource, but I noticed something weird. If you jump off something really high and do a double jump, when you land, you will be unable to do another double jump until you try jumping while going up an upward incline. It seems that the gravity is somehow overpowering the double jump, but I haven't figured out exactly what's going on yet...
#15
07/21/2008 (1:48 pm)
How to disable/enable doublejump in game ?
#16
12/04/2008 (8:52 pm)
I can't get this to work, no errors or anything. The character jumps normal.
can anyone help?
#17
12/24/2008 (8:10 am)
maria, you could add a flag and have it like if datablock has doublejump=1 then then double jump is active, else normal jumping,

all u really need is encase it in an if statement. make sure u also add this then to the bit stream else the engine never see it


jsut a quick question, has anyone played around with a costum 2nd jump animation?

so that normal jump plays normal animation, and the 2nd jump plays jump2 animation? any ideas before i dive into this problem?
#18
12/24/2008 (10:07 am)
@ Tom
Exacly. Each Jump has its own animation.
#19
12/24/2008 (10:10 am)
oh, so its already included?
...

woops its right above in your post.. must have missed that one.

thank you:)
#20
05/28/2009 (11:43 am)
is anyone else having trouble getting this to work? i have tgea 1.8.1 and i followed all the steps (went back 5 times now to make completely sure i did everything and did it right) and i enabled it on my PlayerData and put the settings in and nothing happens.

the character jumps like normal. i even set the delay to zero and the double jump force to something ridiculous like 10000 just to see if it was jumping too fast, but it never double jumps.

if it makes any difference, i used the new project generator to test it and modified their SpaceOrc playerdata to try it out
Page «Previous 1 2