Jump to content
  • Advertisement
Sign in to follow this  
Muzzy A

Applying Acceleration to a player

This topic is 2441 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Im working on a project to basically help myself get better with game physics.

I'm having a problem with adding acceleration to velocity.

I want to move my character around using W A S D keys, but i cant figure out how to get the player to slow down to a stop after i release the key.

I know the code ive written is most likely FAR more than what you need to do this but this is what i've got



// For each key i do something like this
if(KeyDown(keyW))
{
if(Length(player.Acceleration) == 0)
{
// Set acceleration to the direction of the camera
Vector3 camDir = GetCameraDirection();

player.Acceleration.x = camDir.x * playerSpeed;
player.Acceleration.z = camDir.z * playerSpeed;
}
}
else
{
if(player.Acceleration.x > 0)
{
player.Acceleration.x -= playerSpeed;

if(player.Acceleration.x < 0)
player.Acceleration.x = 0;
}
if(player.Acceleration.z > 0)
{
player.Acceleration.z -= playerSpeed*time.GetDeltaTime();

if(player.Acceleration.z < 0)
player.Acceleration.z = 0;
}
}

// Then i update the players position
player.Velocity += player.Acceleration;
player.Position += player.Velocity;



This code works for speeding up and maintaining a constant speed, but when i release the button the player doesn't stop

Share this post


Link to post
Share on other sites
Advertisement
Why don't you just set acceleration to 0 when a key isn't pressed, rather than subtracting playerSpeed from it and then setting it to 0 if it becomes negative?

Share this post


Link to post
Share on other sites

Why don't you just set acceleration to 0 when a key isn't pressed, rather than subtracting playerSpeed from it and then setting it to 0 if it becomes negative?

Acceleration of 0 means a constant speed, not a slowdown.

@Muzzy :
First, I don't really understand how you get your current results. From the code I see, when the key is pressed, you set a constant acceleration. Yet you're reporting that you observe a "constant speed", which imho is quite puzzling to begin with (a constant acceleration would mean exactly that : you'd keep accelerating forever).

Second, I fail to see why you would need a different method for handling x and z in the part of your code trying to handle deceleration.


I see two paths here, depending on the kind of "reality" you want to simulate :

First Method : you consider that "pressing the 'W' key" means pressing the gas pedal on a car, and "not pressing the 'W' key" means not pressing the gas pedal of a car.

1) When user presses 'W', set a constant acceleration just as you do now (but either double check your result - or interpretation of the result - or fix the issue that you currently experience a "constant speed" as a result). Ah, and rename that "playerSpeed" constant to something more appropriate, like "playerAcceleration", if you insist on using it as the length of this constant acceleration vector. And also remove that test on Acceleration length, it's not really worth it as things are, and will prevent you from turning around once you work on the other keys tongue.png
2) When not pressing 'W', set acceleration to zero.
3) Whatever the user does with his keys, set a constant friction force opposing your current velocity.
=> When deceleration resulting from force outweights the acceleration from the engine, you will eventually experience a "constant" maximum speed.
=> When not pressing the gas pedal, you will eventually come to an halt.

Second Method : you see "pressing the 'W' key" as actively moving your feets in some kind of I-want-to-go-there fashion (or, once again, pressing the gas pedal on a car), and "not pressing the 'W' key" as actively slowing down those feets (or pressing the brakes on a car).

1) When user presses 'W', set a constant acceleration just as you do now, but also impose a limit on the maximum speed.
2) When user does not press 'W', set a constant deceleration, and clamp your speed to zero when it would try to go backwards.


//
// First method
//
Vector3 camDir = GetCameraDirection();
if (keyDown(keyW)) {
player.Acceleration.x = camDir.x * playerAcceleration;
player.Acceleration.z = camDir.z * playerAcceleration;
} else {
player.Acceleration = nullVector;
if (currentSpeed < minSpeed) {
// when speed becomes too tiny, we can safely assume we have come to an halt.
player.Velocity= nullVector;
}
}
// friction (with the road, against the air, from the engine internals, whatever.) is a force opposing movement.
Vector3 friction = ( - player.Velocity ) * someFrictionFactor;

// a force typically sets an acceleration on an object, in inverse proportion with the object's mass (or weight, if you prefer).
player.Acceleration += friction / playerMass;

player.Velocity += player.Acceleration;
player.Position += player.Velocity;

// *********************

//
// Second method
//
Vector3 camDir = GetCameraDirection();
float currentSpeed = Length(player.Velocity);
if (keyDown(keyW)) {
// restricts the throttle if the player comes close to max speed so that your player cannot go too fast.
float possibleAcceleration = playerAcceleration;
if (currentSpeed + possibleAcceleration > maxSpeed) {
// This part will get tricky once you start messing with the real timing, but let's keep it simple for now.
possibleAcceleration = maxSpeed - currentAcceleration;
}
player.Acceleration.x = camDir.x * possibleAcceleration;
player.Acceleration.z = camDir.z * possibleAcceleration;
} else {
if (currentSpeed > minSpeed) {
player.Acceleration = ( - player.Velocity ) * playerAcceleration;
} else {
// when speed becomes too tiny, we can safely assume we have come to an halt.
player.Acceleration = nullVector;
player.Velocity= nullVector;
}
}
player.Velocity += player.Acceleration;
player.Position += player.Velocity;


As a side note, well... that depends on what you are doing of course, but I would assume you only need position and velocity to be properties of a "player", as you'll need those each frames along with their previous values (note the usage of '+=' in the related operations), but this is not the case for acceleration which could be a local variable of the method.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!