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 :)
Page «Previous 1 2 3 4 Last »
#1
05/13/2002 (4:17 pm)
Very nice. Thanks for that, Daniel !
#2
05/18/2002 (1:57 am)
I get an error:

c:\torque\engine\game\player.cc(1443) : error C2065: 'tempSprintSpeedMult' : undeclared identifier
#3
05/18/2002 (12:52 pm)
Check your spelling mate
#4
05/18/2002 (9:43 pm)
I re did it on a new engine source and it has the same error...I just copyed and pasted it in...did anyone have to change any thing in putting the code in?
#5
05/18/2002 (10:44 pm)
you have this part in? This is the declaration..

//Check if sprinting
F32 tempSprintSpeedMult;
F32 tempSprintForceMult;
tempSprintSpeedMult = 1;
tempSprintForceMult = 1;
#6
05/19/2002 (2:05 am)
Yeah I have that just after:
if(!inLiquid && mWaterCoverage >= 1.0f) {

inLiquid = true;
}
else if(inLiquid && mWaterCoverage < 0.8f) {
if(getVelocity().len() >= mDataBlock->exitSplashSoundVel && !isMounted())
alxPlay(mDataBlock->sound[PlayerData::ExitWater], &getTransform());
inLiquid = false;
}

//then the check if sprinting code
//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;
}
}
#7
05/19/2002 (3:59 am)
It should be just before this

// Desired move direction & speed
VectorF moveVec;
F32 moveSpeed;
#8
05/19/2002 (4:23 am)
ah complied ok thanks mate ;-)

but when I go to run in the game it goes back and then forward?

I got a feeling more code is where it shouldn't be...

Could you tell where all the part 2 code goes?
Like the things before them...
#9
05/25/2002 (4:48 am)
I was thinking is anyone else having problems with this code?
#10
05/28/2002 (9:46 am)
Daniel,
There seems to be something not working quite right with this (maybe me). When I tried adding the code, I didn't get any errors or anything, but all it seemed to do was remap my freelook to the "q" key.

I think it has to do with these two sections of code:
curMove.freeLook = MoveManager::mFreeLook;
curMove.freeLook = MoveManager::mSprint;

and...

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);

It doesn't ever seem to go into the If (move->sprint...) section. If I change the curMove.freeLook = MoveManager::mSprint;
to
curMove.sprint = MoveManager::mSprint;
I get a similar thing going on that Edward was seeing. My player tries to Sprint but I can't control the direction he's sprinting.

Any ideas?
Maybe I have part of it in the wrong section. Some of the line numbers you refer to didn't seem to match what I see on a "fresh" 1.1.1 engine.
#11
05/29/2002 (2:47 am)
I just changed the curMove.freelook to curMove.Sprint...and now I can choose were I go but I'm always sprinting. ???
#12
06/01/2002 (4:36 am)
Sabrecyd get anywhere?
#13
06/01/2002 (7:53 pm)
Does this code not work? I was about to try it.
#14
06/01/2002 (8:15 pm)
I think Step 2 needs updating; instead of just saying Line such and such, could you also show the example like you did in step 1? I'm looking at the code and wondering if I'm adding it in the right place.

What I mean is, when you say add at line (for example) 450, is that line 450 before the previous steps were followed and code added, or is that line 450 afer the previous steps were followed?

For example you say to add some code at line 761 in player.cc, but line 761 is:

F32 Player::mGravity = -20;

which has nothing to do with this resource.
#15
06/02/2002 (12:46 am)
Although a lot of people were able to use this resource with no problems, obviously some people can not so I have tried to clarify some things.

When using a resource, imho, you should attempt to understand what it is doing and not just blindly copy the snippets into place.

If you have any problems with this, just comment here.
#16
06/02/2002 (12:18 pm)
That's all well and good Daniel, but I try to learn as I add each block of code in. I find it difficult to learn when the instructions tell me add code at line xxx when that line is the wrong one.
#17
06/03/2002 (2:57 am)
I argee with Mike...just about to try the code.mmm...everything is in the right place :-/ I'll have to look some more....
#18
06/04/2002 (5:28 am)
@Edward,
Sorry for not replying. I was out of town on business. I'll take a look at this some more tonight or at least this week. I probably have something in the wrong spot. If I see what my mistake is, I'll post it here.
#19
06/05/2002 (5:00 am)
Guys, I found the problem.
There is a line missing in the code.
Here is the full section:

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

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

Mine is working fine now that that line is added. Hope that's what the problem was for others.

@Daniel, Thanks for the code post. It's pretty cool and like you said it could be used for other move types too.

-Sabrecyd
#20
06/06/2002 (3:07 am)
mmm thx that makes sense lol... I'm having a problem still :-/ its not toggleing or can't...not sure
Page «Previous 1 2 3 4 Last »