# Thread: 2D Acceleration/Velocity Processing

1. ## 2D Acceleration/Velocity Processing

Hello,

In my spare time I'm having a go at creating a 2D platform game with what I hope to be a realistic simulation of physics. I've got a looong way to go, but something akin to what you might see with the Source engine, only in 2D.

Anyways, I've tried creating a function that is called every frame to process the basics (collisions, gravity, etc.). However it doesn't work the way that I expect it to.

When the object reaches the bounds of the screen I invert the acceleration vector to cancel out any movement, however I seem to get a slight jitter.

Also, in the main game loop, during processing of input I add vectors to the player's acceleration vector whenever they press left, right, etc. but I don't see this reflected on screen.

I think the problem might have something to do with scale but I'm not sure.

My vector struct has both Cartesian and polar coordinates to aid debugging.

(btw this is good old-fashioned C):-
Code:
```// pGame = game object, uiTime = delta time in ticks
void Physics_Think(t_game *pGame, unsigned int uiTime)
{
t_physicsobject *pObject;
t_vector vNow;

// iterate through linked list of objects
pObject = (t_physicsobject *)pGame->listPhysics.lpHead;
while (pObject)
{
// don't bother processing if not visible
if (!(pObject->pspr->fFlags & SPRF_VISIBLE))
{
pObject = (t_physicsobject *)pObject->node.lpNext;
continue;
}

// collision test (to implement)
...
// apply gravity to acceleration (magnitude = 10, direction = 90 degrees)
Vector_Add(&pObject->vAcceleration, &pGame->vGravity);
// limit object to inside screen
if (pObject->vVelocity.dblDx < 0.0)
{
if (pObject->pspr->x + pObject->vVelocity.dblDx < 0)
{
pObject->pspr->x = 0;
Vector_Set(&vNow, pObject->vAcceleration.usMagnitude, 360 - pObject->vAcceleration.usDirection);
Vector_Add(&pObject->vAcceleration, &vNow);
}

}
else if (pObject->vVelocity.dblDx > 0.0)
{
if (pObject->pspr->x + pObject->vVelocity.dblDx >= 640 - pObject->pspr->w)
{
pObject->pspr->x = 640 - pObject->pspr->w;
Vector_Set(&vNow, pObject->vAcceleration.usMagnitude, 360 - pObject->vAcceleration.usDirection);
Vector_Add(&pObject->vAcceleration, &vNow);
}

}

if (pObject->vVelocity.dblDy < 0.0)
{
if (pObject->pspr->y + pObject->vVelocity.dblDy < 0)
{
pObject->pspr->y = 0;
Vector_Set(&vNow, pObject->vAcceleration.usMagnitude, 360 - pObject->vAcceleration.usDirection);
Vector_Add(&pObject->vAcceleration, &vNow);
}

}
else if (pObject->vVelocity.dblDy > 0.0)
{
if (pObject->pspr->y + pObject->vVelocity.dblDy >= 480 - pObject->pspr->h)
{
pObject->pspr->y = 480 - pObject->pspr->h;
Vector_Set(&vNow, pObject->vAcceleration.usMagnitude, 360 - pObject->vAcceleration.usDirection);
Vector_Add(&pObject->vAcceleration, &vNow);
}

}

// apply acceleration to velocity
Vector_Set(&vNow, pObject->usMass * pObject->vAcceleration.usMagnitude * uiTime, pObject->vAcceleration.usDirection);
Vector_Add(&pObject->vVelocity, &vNow);

// clamp
if (pObject->vVelocity.usMagnitude > 3000)
Vector_Set(&pObject->vVelocity, 3000, pObject->vVelocity.usDirection);

// move object
if (pObject->vVelocity.dblDx != 0)
pObject->pspr->x += pObject->vVelocity.dblDx;

if (pObject->vVelocity.dblDy != 0)
pObject->pspr->y += pObject->vVelocity.dblDy;

pObject = (t_physicsobject *)pObject->node.lpNext;
}

}```
I'm not sure if I am supposed to be applying the full value of the gravity vector to the acceleration vector every frame. The acceleration vector is scaled to delta time before being added to the velocity.

Little help?

2. The coding is good, it's the right idea, but there are lots of conceptual errors going on.

1) Don't add gravity to the acceleration each frame. Acceleration due to gravity is constant - what happens in this code is a constant increase in acceleration. Set it to the gravity acceleration vector at the beginning and leave it alone - or if you need to, calculate and set net acceleration based on the forces that are currently acting on the object. But it's generally unwise to add to the acceleration vector like this.

2) Consider the part in bold:
Code:
```if (pObject->pspr->x + pObject->vVelocity.dblDx < 0)
{
pObject->pspr->x = 0;
Vector_Set(&vNow, pObject->vAcceleration.usMagnitude, 360 - pObject->vAcceleration.usDirection);
Vector_Add(&pObject->vAcceleration, &vNow);
}```
This is not the opposite of your original acceleration vector. Try a few test cases to see what I mean.
You'll want to set the direction to 180+original to get the opposite motion.
On the other hand, if you're going to cancel out acceleration, why don't you just set the magnitude to 0?

3) Canceling out acceleration isn't going to keep the object in the screen anyway - an object with 0 acceleration will still move with its initial velocity. I'd suggest leaving acceleration as it is and setting velocity to 0, at least until collisions are properly implemented. And do this sort of clamping after your new position has been calculated. That has 2 benefits: you're can use the new current_position in those if statements (instead of calculating the next position for each comparison), and it eliminates that jitter you were describing.

4)
Code:
`Vector_Set(&vNow, pObject->usMass * pObject->vAcceleration.usMagnitude * uiTime, pObject->vAcceleration.usDirection);`
I'll leave it to you to decide what's wrong with this.

Umm... with all that said, good luck .

And take a look at this when you have time. It's a fantastic explanation of physics for game devs.

3. Ah. This serves me right.
I need more Coke for late-night coding (the drink, not the other stuff)...

Popular pages Recent additions