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«First 1 2 Next»
#21
06/02/2009 (6:50 pm)
nevermind, i'm dumb haha, i never recompiled the engine after i made the changes. classic forgetful me :P
#22
10/13/2009 (3:33 pm)
i followed the coding perfectly and have been messing with the numbers. no compilers errors have occurred at all but it will still only do a single jump. are there any issues with 1.5.2?
#23
10/22/2009 (5:28 pm)
found a much easier way of doing this without using code just scripting in the defaultbinds.cs
$jumpForce = "0 0 1500";
$jump2 = true;

function jump(%val)
{
if( %val )
{
if( !$jump1 )
{
$player.applyImpulse( 0, $jumpForce );
$jump1 = true;
schedule( 2000, 0, enableJumpOne );
schedule( 350, 0, enableJumpTwo );
schedule( 800, 0, disableJumpTwo );

} //end jump
if( $jump1 && !$jump2 )
{
$player.applyImpulse( 0, $jumpForce );
$jump2 = true;
} //end dbl jump
}
}
function enableJumpOne()
{
$jump1= false;
}
function enableJumpTwo()
{
$jump2= false;
}
function disableJumpTwo()
{
$jump2= true;
}
Page«First 1 2 Next»