Game Development Community

dev|Pro Game Development Curriculum

Sprint Button

by Daniel Neilsen · 05/13/2002 (10:56 am) · 79 comments

Download Code File

Adding a Player Sprint Key


by Daniel "Wizard_TPG" Neilsen
wizardsworld@bigpond.com


This is quite a simple thing to do but requires the editing of
several files in the torque engine. I have based this on the
latest HEAD version as at 13/5/02 but, I originally coded this
for the original release of torque so it should be compatible
with all torque versions to date.

Before we go too much further I should say this
DISCLAIMER - I am certainly not the best at C++ in the world but
this worked for me so it should work for you too.
- The line numbers are taken from my edit version of
the engine so should be considered approximate only.



STEP 1 - Adding a sprint toggle into the engine

Open MoveManager.h and add this line to line 29
bool sprint;

result should look like this
bool freeLook;
bool sprint;
bool trigger[MaxTriggerKeys];


Add this to line 50
static bool mSprint;

result should look like this
static bool mFreeLook;
static bool mSprint;
static F32 mPitch;
static F32 mYaw;
static F32 mRoll;


Open GameConnectionMoves.cc and add this line to line 29
bool MoveManager::mSprint = false;

result should look like this
bool MoveManager::mFreeLook = false;
bool MoveManager::mSprint = false;
F32 MoveManager::mPitch = 0;
F32 MoveManager::mYaw = 0;
F32 MoveManager::mRoll = 0;


Add this to line 64
Con::addVariable("mvSprint", TypeBool, &mSprint);

result should look like this
Con::addVariable("mvFreeLook", TypeBool, &mFreeLook);
Con::addVariable("mvSprint", TypeBool, &mSprint);
Con::addVariable("mvPitch", TypeF32, &mPitch);
Con::addVariable("mvYaw", TypeF32, &mYaw);
Con::addVariable("mvRoll", TypeF32, &mRoll);


Add this to line 148
stream->writeFlag(sprint);

result should look like this
stream->writeFlag(freeLook);
stream->writeFlag(sprint);


Add this to line 172
sprint = stream->readFlag();

result should look like this
freeLook = stream->readFlag();
sprint = stream->readFlag();


Add this to line 199
curMove.sprint = MoveManager::mSprint;

result should look like this
curMove.freeLook = MoveManager::mFreeLook;
curMove.sprint = MoveManager::mSprint;


Open default.bind.cs and add the following
function toggleSprint( %val )
{
if ( %val )
$mvSprint = true;
else
$mvSprint = false;
}
moveMap.bind( keyboard, q, toggleSprint );


ok, cool, we got a sprint button....but it dosnt do didly squat...doh!
hmmm better make it do something then eh?

Just a quick offside... For those that didnt notice, we literally copied the freelook
all the way. This method can be used for any toggle button you wish to add.



STEP 2 - THE SPRINT DATABLOCK SETTINGS

The next step is to add new properties into the playerdata datablock
for the sprint speed, force, energy drain and min energy


Open player.h and add the following at line 57
F32 SprintSpeedMult; // Player max speed increase when sprinting eg. 1.2 = 20% increase
F32 SprintForceMult; // Player run force increase when sprinting eg. 1.2 = 20% increase
F32 sprintEnergyDrain; // Energy drain/tick
F32 minSprintEnergy; // Energy required to sprint

Result should look like this:
F32 SprintSpeedMult;
F32 SprintForceMult;
F32 sprintEnergyDrain; // Energy drain/tick
F32 minSprintEnergy;
F32 maxStepHeight;
F32 runSurfaceAngle; // Angle from vertical in degrees



Open player.cc and add the following at line 170
SprintSpeedMult = 1.2;
SprintForceMult = 1.2;
sprintEnergyDrain = 2;
minSprintEnergy = 2;

Result should look like this:
SprintSpeedMult = 1.2;
SprintForceMult = 1.2;
sprintEnergyDrain = 2;
minSprintEnergy = 2;
maxStepHeight = 1;
runSurfaceAngle = 80;



add the following at line 450
addField("SprintSpeedMult", TypeF32, Offset(SprintSpeedMult, PlayerData));
addField("SprintForceMult", TypeF32, Offset(SprintForceMult, PlayerData));
addField("sprintEnergyDrain", TypeF32, Offset(sprintEnergyDrain, PlayerData));
addField("minSprintEnergy", TypeF32, Offset(minSprintEnergy, PlayerData));

Result should look like this:
addField("SprintSpeedMult", TypeF32, Offset(SprintSpeedMult, PlayerData));
addField("SprintForceMult", TypeF32, Offset(SprintForceMult, PlayerData));
addField("sprintEnergyDrain", TypeF32, Offset(sprintEnergyDrain, PlayerData));
addField("minSprintEnergy", TypeF32, Offset(minSprintEnergy, PlayerData));
addField("runSurfaceAngle", TypeF32, Offset(runSurfaceAngle, PlayerData));
addField("recoverDelay", TypeS32, Offset(recoverDelay, PlayerData));
addField("recoverRunForceScale", TypeF32, Offset(recoverRunForceScale, PlayerData));



add the following at line 643
stream->write(SprintSpeedMult);
stream->write(SprintForceMult);
stream->write(sprintEnergyDrain);
stream->write(minSprintEnergy);

Result should look like this:
stream->write(SprintSpeedMult);
stream->write(SprintForceMult);
stream->write(sprintEnergyDrain);
stream->write(minSprintEnergy);
stream->write(recoverDelay);
stream->write(recoverRunForceScale);



add the following at line 761
stream->read(&SprintSpeedMult);
stream->read(&SprintForceMult);
stream->read(&sprintEnergyDrain);
stream->read(&minSprintEnergy);

Result should look like this:
stream->read(&runSurfaceAngle);
stream->read(&SprintSpeedMult);
stream->read(&SprintForceMult);
stream->read(&sprintEnergyDrain);
stream->read(&minSprintEnergy);
stream->read(&recoverDelay);
stream->read(&recoverRunForceScale);




STEP 3 - THE MOVEMENT

Now we have the button working, and we have the sprint settings in the engine
Time to make it all work. The basics of sprinting is we are "amplifying" the
players speed.


Before these three lines at approx line 1660

// Desired move direction & speed
VectorF moveVec;
F32 moveSpeed;

add the following:

//Check if sprinting
F32 tempSprintSpeedMult;
F32 tempSprintForceMult;
tempSprintSpeedMult = 1;
tempSprintForceMult = 1;

if (move->sprint)
{
tempSprintSpeedMult = mDataBlock->SprintSpeedMult;
tempSprintForceMult = mDataBlock->SprintForceMult;
if (mEnergy < mDataBlock->minSprintEnergy)
{
tempSprintSpeedMult = 1;
tempSprintForceMult = 1;
}
}



Change the following lines at approx line 1422 like so..

if (move->y > 0)
{
if( mWaterCoverage >= 0.9 )
moveSpeed = getMax(mDataBlock->maxUnderwaterForwardSpeed * tempSprintSpeedMult * move->y,
mDataBlock->maxUnderwaterSideSpeed * tempSprintSpeedMult * mFabs(move->x));
else
moveSpeed = getMax(mDataBlock->maxForwardSpeed * tempSprintSpeedMult * move->y,
mDataBlock->maxSideSpeed * tempSprintSpeedMult * mFabs(move->x));
}
else
{
if( mWaterCoverage >= 0.9 )
moveSpeed = getMax(mDataBlock->maxUnderwaterBackwardSpeed * tempSprintSpeedMult * mFabs(move->y),
mDataBlock->maxUnderwaterSideSpeed * tempSprintSpeedMult * mFabs(move->x));
else
moveSpeed = getMax(mDataBlock->maxBackwardSpeed * tempSprintSpeedMult * mFabs(move->y),
mDataBlock->maxSideSpeed * tempSprintSpeedMult * mFabs(move->x));
}




Change the following lines at approx line 1482 like so..

VectorF pv;
if(moveSpeed > 0)
{
if (move->sprint && mEnergy >= mDataBlock->minSprintEnergy)
{
mEnergy -= mDataBlock->sprintEnergyDrain;
}
else if (mEnergy >= mDataBlock->minRunEnergy)
{
mEnergy -= mDataBlock->runEnergyDrain;
pv = moveVec;
}
}
else
pv.set(0,0,0);



Change the following lines at approx line 1513 like so..

// Clamp acceleratin, player also accelerates faster when
// in his hard landing recover state.
F32 maxAcc = (mDataBlock->runForce / mMass) * TickSec;
if (move->sprint)
maxAcc *= mDataBlock->SprintForceMult;
if (mState == RecoverState)
maxAcc *= mDataBlock->recoverRunForceScale;
if (runSpeed > maxAcc)
runAcc *= maxAcc / runSpeed;
acc += runAcc;


And there you have it. A working sprint key.

Enjoy :)
#41
07/30/2002 (9:14 am)
I might try and implement the walk feature as I mentioned, but don't hold your breath!
#43
12/12/2002 (9:04 pm)
Ok, well at last I got round to putting this in my game and its a cool feature... however it seems to disable strafing and backwards movement. Have I done something wrong or is this a sideffect of it? if so has anyone fixed it so strafing etc does work? if not i guess i'll have to fix it myself :P
#44
12/13/2002 (12:59 am)
mmm Has I remember that shouldn't be a problem.

So maybe you should go ove rthe code and make sure everything thing is in place.
#45
12/18/2002 (6:04 pm)
hmmm
I cant see a problem with it, it looks like it should work... but it just wont strafe or walk backwards.
Has anyone else had this problem?
It might be that it only works with the older versions of the engine but i cant work out why that would be...
#46
12/18/2002 (6:51 pm)
I have never had that problem Thorgrim
It might help if you echo out some values to the console to see what is happening
#47
12/22/2002 (1:29 am)
Ahh... my bad, accidently messed up one of the functions.
Sorry for the bother, it works great now, thanks :)
#48
01/02/2003 (2:08 pm)
Has anybody tested this in HEAD? Doesn't seem to work at all there... I didn't get any compile errors, but the player just went nuts after I've added the code...
it wouldn't react on any movement key, simply slide down with highspeed to the lowest point in the map, falling through the terrain, etc.
And if a new AIPlayer was placed in a map, the engine would hang up and crash...
anybody else tried this?
I'm sure I did everything that was mentioned in this whole tread...
#49
02/14/2003 (2:01 pm)
Hey Beffy,

It works quite well with head, which I checked out I think 28 of Jan. The line numbers of reference were pretty useless by this time, HEAD having changed obviously, the but the author was as wise as he was kind, and indicated where it should be by showing which line of code to look for. Based on that I had no problems installing this, it compiled fine, and worked the first try.

And excellent resource which has supplied me with the knowledge to add other methods of movement to my character! I love the resources!
#50
12/13/2003 (5:08 pm)
Got exactly same problem as Beffy in 1.2 HEAD.

Have absolutley no control over player while its moving, and the only time its moving is because its sliding down a hill (only walks on perfectly flat terrain).

Has anybody got a clue why this is happening?
#51
02/03/2005 (6:56 am)
I've implemented this in 1.3.0 with the fixes suggested in the comments, and it appears to work fine.
#52
03/10/2005 (1:44 am)
Hi
I have included this into my 1.3.0 Project and its working very fine. having full control of Player's movements. Thanx for this lovely resource.

I want to implement this into my Tank. I will be appriciate if somebody could suggest me. Thanx.

Ali Shikla
#53
11/29/2005 (6:07 pm)
PlayerData:: Recover delay exceeds range (0-127)
Woah, I think I'm getting some overwrite here.
Is it possible to run out of stream->writeFlag(somthing);?
I know that TGE has 32bits for it's network, would this be a symptom of running out?

*Edit: Nevermind, I was just newbin' out.

Egon (referencing the Proton Pack): "Don't cross the streams!"
Peter: "Why?"
Egon: "It will be bad."
Peter: "I'm fuzzy of this whole good/bad thing, what do you mean "bad?"
Egon: "Try to imagine all life as you know it stopping instantaneously and every molecule in your body exploding at the speed of light."
Ray (gasping): "Total Protonic Reversal!"
#54
11/29/2005 (6:38 pm)
This resource works great with TGE 1.3!

Ari
#55
11/29/2005 (7:32 pm)
I copied this from player.cc and added it into player.cs in datablock PlayerData(PlayerBody) to make for easy editing.
SprintSpeedMult = 1.2;
		SprintForceMult = 1.2;
		sprintEnergyDrain = 2;
		minSprintEnergy = 2;

Also, I tested this resource on multiplayer with a dedicated server and it worked fine.

Ari
#56
02/22/2006 (6:51 am)
compiled fine, but when i press "q" and W / A / S / D i will sprint (more like being pushed) into one direction. im using 1.4, what should i do to fix this?
#57
03/05/2006 (8:35 pm)
Has anyone gotten this to work with 1.4 yet? I am getting the same results as vincent (player slides to lowest point when sprinting).
#58
03/07/2006 (9:20 am)
Well, I got it working fine in TGE 1.4 with TLK. And I think to get it to work I just added "Sabrecyd" fix and it worked.
#59
03/21/2006 (7:01 am)
Great ressource, thx ;)

Work with no problem (TGA 1.4 + LP 1.4) only add sabrecyd bugfix

@Vincent&Johnatan: simply set sprintEnergyDrain in player.cc from 2 to 0.
#60
04/02/2006 (3:38 pm)
Thanks for the heads up stalker works fine now.

Jonathan