# Help with acceleration! :(

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

## Recommended Posts

I'm trying to get my spaceship has acceleration and braking but I can not :S

This is the code I have:

// Accelerationif(key[SDLK_w]) {    ship.AddY(-vel);    vel += INC_ACCEL;    dir[0] = true;}else if(key[SDLK_a]) {    ship.AddX(-vel);    vel += INC_ACCEL;    dir[12] = true;}else if(key[SDLK_s]) {    ship.AddY(vel);    vel += INC_ACCEL;    dir[8] = true;}else if(key[SDLK_d]) {    ship.AddX(vel);    vel += INC_ACCEL;    dir[4] = true;}// Brakingelse {    if(dir[0]) {        vel -= vel*0.1;	ship.AddY(-vel);	if(vel < 0) {	    vel = 0;	    dir[0] = false;	}    }    else if(dir[4]) {	vel -= vel*0.1;	ship.AddX(vel);	if(vel < 0) {	    vel = 0;            dir[4] = false;	}   }   else if(dir[8]) {	vel -= vel*0.1;	ship.AddY(vel);	if(vel < 0) {	    vel = 0;	    dir[8] = false;	}   }   else if(dir[12]) {	vel -= vel*0.1;	ship.AddX(-vel);	if(vel < 0) {	    vel = 0;	    dir[12] = false;	}    }}if(vel > MAX_ACCEL) {    vel = MAX_ACCEL;}

0 -> Up
4 -> Right
8 -> Down
12 -> Left

It works more or less as it actually moves to where he wants...

Let's see if anyone can help
Regards!

##### Share on other sites
You don't seem to actually be using the newtonian motion equations which is probably making your life a lot harder.

newtonian motion:
s = 1/2*a*t^2 + v0*t + s0

s: position now
a: acceleration
t: time passed
v0: original velocity
s0: original position

you can track velocity separately:
newVelocity = acceleration*t + lastVelocity;newPosition = 1/2*acceleration*t*t + lastVelocity*t + lastPosition

where:
t is time since last frame
acceleration is a vector in the direction the ship is currently facing.
<anything>Velocity is a vector
<anything>Position is a 3D point
however:
you can treat x,y,z acceleration/velocity/position separately. In that case the above are just the values per direction so you'd do that calculation 3 times, one for each axis in which you're interested.

Braking:
Need more info about how you want braking to behave. Is it active braking (user presses a button to bleed speed) or is it passive "braking" (the ship will slow down to a stop when you let go of all buttons?

-me

##### Share on other sites
Or you can skip the 1/2*acceleration*t*t by using newVelocity when calculating
position.

newVelocity = oldVelocity + acceleration*dt
newPosition = oldPosition + newVelocity*dt

in either case you need a class that encapsulates a 2D or 3D vector (2D in your case i guess) with the proper operator overloads, there are a lot of these available.

I recommend making your ship class something like this:

class Ship {
private:
vector2D speed;
vector2D acceleration;
vector2D postition
public:
void move(float dt)
{
speed+=acceleration*dt;
position+=speed*dt;
}
void setAcceleration(vector2D acc)
{
acceleration=acc;
}
};

all you now need is a appropriate vector2D class as i mentioned before.

Braking in space is nothing else but accelerating in the opposite direction, so for braking you just send -acc when using setAcceleration. If you want a natural breaking (slowing down over time) you need to add a always active negative acceleration (this simulates wind drag), this will also disable your ship to accelerate infinitely.

dragAcceleration = -speed*k;
where k is a constant which indicates how fast will your ship come to a stop.
now you speed eq looks like:
speed+=acceleration*dt + dragAcceleration*dt;

If you dont know how to calculate dt(time between frames) you can just send a small float instead(0.01 for example), this will only work if your frame rate if fairly constant, you will need to manage you frames sooner or later.

Hope this helped.

##### Share on other sites
1)

Quote:
 0 -> Up4 -> Right8 -> Down12 -> Left

OK; what do all the other elements of 'dir' represent?

2) Don't change the velocity when you process the key. Do it in separate physics-update logic.

3) When you call something "velocity", that means it has an amount and a direction. If you are only storing "how fast", that is called "speed", not "velocity".

4) Think about what happens when you are going in one direction and then you want to brake, by hitting the key for the other direction. Right now, every key INC_ACCEL, which never changes. So you can only ever accelerate. Also, you add vel or -vel depending on the direction key, so you change direction immediately and keep going even faster.

The mistake here is that you have not considered that velocity and acceleration do not have to be in the same direction.

What you have right now is a mess. Please don't try to fix it in steps; instead, understand how it is supposed to work and try again.

Represent acceleration as an X-acceleration and a Y-acceleration. When the user presses a direction key, set the X-acceleration and Y-acceleration immediately, and do not change velocity or position.

Represent velocity with X and Y components, too. Store all of these values - position, velocity and acceleration - within the Ship.

Give the ship two functions: "set_acceleration" (so you can tell it what keys were pressed) and "update". Get rid of AddY and whatever else. That is misunderstanding how objects are supposed to work. The ship is a thing; you don't drag it along and tell it where it should be - you push it (apply acceleration), and it moves (and keeps moving, because there is no friction in space).

In update(), you multiply each component of the acceleration by the elapsed time, and add to the velocity components. Then you do the same with the velocity components and the position components.

That gives you a very simple model. It's still not very realistic, because a spaceship does not really have any reference to X or Y directions - your acceleration should instead be forward, backward or turning. But understanding how to make turning work realistically is a little more complicated, so just try making this much work first.

##### Share on other sites
Quote:
 Original post by PalidineYou don't seem to actually be using the newtonian motion equations which is probably making your life a lot harder.newtonian motion:s = 1/2*a*t^2 + v0*t + s0s: position nowa: accelerationt: time passedv0: original velocitys0: original positionyou can track velocity separately:*** Source Snippet Removed ***where:t is time since last frameacceleration is a vector in the direction the ship is currently facing.Velocity is a vectorPosition is a 3D pointhowever:you can treat x,y,z acceleration/velocity/position separately. In that case the above are just the values per direction so you'd do that calculation 3 times, one for each axis in which you're interested.Braking:Need more info about how you want braking to behave. Is it active braking (user presses a button to bleed speed) or is it passive "braking" (the ship will slow down to a stop when you let go of all buttons?-me

Well, about breaking I want to stop pressing the button, the ship starts to slow down so that it moved a few pixels before stopping completely; passive braking like you say.

I'm using SDL and a 2D engine, so I only have X and Y, so what time should I put? SDL_GetTicks()? I control the fps and is constant to 62.5.

@Zahlman tomorrow I answer you; here is very late xD

[Edited by - Puyover on July 7, 2010 8:55:11 PM]

##### Share on other sites
this is simple but it's linear deceleration which may "feel" weird. Normally deceleration from air resistance is proportional to the square of the velocity (so rate of slowing is much steeper when you're moving fast).

if ( not accelerating )    velocity -= BREAKING_AMOUNT;

The time is literally the time since the last frame has been run, in seconds for convenience. So however you are calculating time passed since last frame to cap your framerate, use that. If your Frames Per Second is 62.5 you should be able to convert that into seconds per frame pretty easily [smile]

In answer to your other questions, I think you should probably learn some basic linear algebra and basic physics if what I and Zahlman have posted doesn't make much sense.

-me

##### Share on other sites
Well, at finish I solved without apply the uniform rectilinear motion equations; I only have to create a new variable (accelX, accelY) which I use to multiply by a constant (1.115) ...

This I have get and work very fine:

if(key[SDLK_w] && key[SDLK_d]) {    	accelX *= ACELERACION; accelY *= ACELERACION;    	ship.SetVel(accelX, -accelY);    }    else if(key[SDLK_a] && key[SDLK_w]) {    	accelX *= ACELERACION; accelY *= ACELERACION;    	ship.SetVel(-accelX, -accelY);    }    else if(key[SDLK_d] && key[SDLK_s]) {    	accelX *= ACELERACION; accelY *= ACELERACION;    	ship.SetVel(accelX, accelY);    }    else if(key[SDLK_s] && key[SDLK_a]) {    	accelX *= ACELERACION; accelY *= ACELERACION;    	ship.SetVel(-accelX, accelY);    }    else if(key[SDLK_w]) {    	accelY *= ACELERACION;    	ship.SetVelY(-accelY);    }	else if(key[SDLK_a]) {		accelX *= ACELERACION;		ship.SetVelX(-accelX);	}    else if(key[SDLK_s]) {    	accelY *= ACELERACION;    	ship.SetVelY(accelY);    }    else if(key[SDLK_d]) {    	accelX *= ACELERACION;    	ship.SetVelX(accelX);    }    else {    	accelX /= ACELERACION; accelY /= ACELERACION;    	ship.SetVel(ship.GetVelX()*DECELERACION, ship.GetVelY()*DECELERACION);    }    if(accelX < 1) accelX = 1;    if(accelY < 1) accelY = 1;    if(accelX > 5) accelX = 5;    if(accelY > 5) accelY = 5;    ship.AddPos(ship.GetVelX(), ship.GetVelY());

DECELERACION -> 0.99, I use this to decrease the speed of the ship very slowly (braking).

Thank you all!

1. 1
2. 2
Rutin
16
3. 3
4. 4
5. 5

• 26
• 11
• 9
• 9
• 11
• ### Forum Statistics

• Total Topics
633704
• Total Posts
3013457
×