Help with simple 2D car physics

Started by
10 comments, last by djhworld 16 years, 1 month ago
Hello there, I'm currently a little confused how to implement simple 2D car physics, now I'd like to emphasize simple here. I've already managed to implement acceleration (I think!) but my car just does this when you accelerate: - acceleration Now I'm presuming this is just demonstrating the linear nature of acceleration over time. My question is, how do I implement turning/steering? A lot of guides (there's one on this website) talk about implementing 4 wheels, I don't wish to do that just yet, that's perhaps a little....too realistic for my needs. I just want something that can accelerate and steer... Any help would be appreciated!
Advertisement
Assuming you have a fully defined vector class. What you would do is at some interval, update the car's postion based on it's velocity. Just make sure to adjust the car's velocity beforehand by its current acceleration vector.

struct Vectory2D {    int x;    int y;// Define your operators here};class Car {public:    Vector2D m_acceleration;    Vector2D m_velocity;    Vector2D m_position;        float m_facing;    void Turn(float degrees);};void Turn(float degrees) {    m_facing += degrees;    Matrix transform;    transform.Identity();    transform.Rotate(DEG_TO_RAD(m_facing));    m_velocity *= transform;}void Car::UpdatePosition(DWORD elapsed) {    m_velocity += (m_accelaration * elapsed);    m_position += (m_velocity * elapsed);}


To make it change direction, apply a rotation to the velocity vector.

int main(int argc, char** argv){    Car racer;    racer.m_position = Vector(ScreenWidth / 2, ScreenHeight / 2); // Its inital    // postion is in the middle of the screen. Assuming a screen size of    // 640x480 its current position is:    // {320, 240}    racer.m_velocity = Vector(1,-1); // Car will initially head to the upper right    racer.UpdatePosition(1); // Car will now move from its initial position of {320,240} to {321,239}    // which puts it one pixel closer to the upper right corner as you've depicted    racer.Turn(90); // Turns the car 90 degrees to the left    //m_velocity should now be {-1, -1}    racer.UpdatePosition(1);    // m_postion should now be {320, 238} and if allowed to continue is now     // heading to the upper left.    racer.Turn(90); // this will turn the car another 90 degreens to the left    // for a total of 180 degrees from its inital velocity direction    // m_velocity should now be {-1, 1};    racer.UpdatePosition(1);    // m_position should now be {319, 239} and if allowed to continue is now     // heading to the lower left.}


There are plenty of optimizations you can make but I've omitted them for clarity. Basically, you car travels in the direction of its velocity. To change direction, just keep modifying it's velocity vector.

[Edited by - Tenbatsu on February 13, 2008 8:36:41 PM]
your velocity needs to be broken down into component vectors
when you turn at angle A and your curent velocity = V then

XVelocity = V * cos(A)
YVelocity = V * sin(A)
-games4thefuture-
A Car physics resources download is available on my website.

It includes the famous Marco Monster car physics tutorial as well as alot of other car physics papers, demo's and source code.

http://www.kjmsoftware.co.uk/

KJM

Quote:Original post by K_J_M
A Car physics resources download is available on my website.

It includes the famous Marco Monster car physics tutorial as well as alot of other car physics papers, demo's and source code.

http://www.kjmsoftware.co.uk/

KJM


Some very good reading, thanks KJM!
Thankyou for the help people, but I'm still a little confused as to what you are getting at (sorry)

Tenbatsu I implemented your code, but got stuck when it came to using matrices to transform the vector, I haven't got a matrix class and when attempting to implement a quick one, this line of code threw me off

m_velocity *= transform;


What does that do?

Games4TheFuture thankyou for the reply, but could you be kind to elaborate on what you mean? How do I put those values so it alters the position of my car?

K_J_M - Thankyou for the reply, I've had a quick glance at the downloads and there's a whole breadth of information there! Thankyou!

Forgive me, I'm a little poor when it comes to maths at times so any help would be appreciated.
Few more resources:
http://physics.hardwire.cz/index.php?action=show&sortby=order&parent_id=42
Quote:Original post by djhworld
m_velocity *= transform;

What does that do?

I think that's equivalent to m_velocity = m_velocity * transform; which is taking the product of a vector and a matrix, and assigning it to m_velocity. That matrix is a rotation matrix, used to rotate the vector by a certain number of degrees (specified in code above) around its origin.

I might be wrong about the order of multiplication... Shouldn't it be matrix by vector instead? Or does it not matter? I can't really remember this, maybe someone else can answer.

Hope that helps. You can find some useful info here.
shurcool

Thank you for the reply, I think I've implemented a rotation matrix, but does this mean I have to rotate all three axis?

How would I go about doing this? At the moment it just rotates along the x-axis, which I believe is incorrect

void Matrix::rotate(float rads) {	m[1][1] = cos(rads);	m[1][2] = -sin(rads);	m[2][1] = sin(rads);	m[2][2] = cos(rads);}
Here goes.

Lets say:
xPos is the current locaion of the car in the X direction
yPos is the current location of the car in the Y direction

V is the distance the car can travel in a cycle, for example it could corespond to 5 pixels in each cycle.

To find the new location of the car you need to also know the direction the car is facing. I'm calling this angle A for now. It is the measure of the angle from the positive x axis to the direction the car is facing.

In C++ the code would look something like this:

int A; // If the car is facing right it would be zero.
// Update this angle by adding to it as the car turns left.
// Subtract from it as the car turn right.
int xPos, yPos; // Stores the cars position.

void UpdatePosition()
{
int XVelocity = V * cos(A);
int YVelocity = V * sin(A);

xNewPos = xPos + xVelocity;
yNewPos = yPos + yVelocity;
}

If you have any qestions PM me.
-games4thefuture-

This topic is closed to new replies.

Advertisement