View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

# 2D physics in a game.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

5 replies to this topic

### #1LAURENT*  Members

Posted 30 May 2014 - 07:57 PM

I thought this was going to be a cake walk but implementing 2D physics is harder than I thought. I could use some logic help with this.

Something I tried.

I applied a constant gravity of 9. with the press of the space bar you move up. The only thing that happen was the character teleported up and floated down................

### #2Washu  Senior Moderators

Posted 30 May 2014 - 08:19 PM

POPULAR

Without code it is hard to tell what you're doing wrong... but here's something that might likely be the problem:

Your movement up is probably applying directly to the object you are moving. Instead you should apply a velocity to it, and compute the movement over the delta time of your physics step.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
ScapeCode - Blog | SlimDX

### #3Postie  Members

Posted 30 May 2014 - 10:50 PM

Typically, you'd apply a force to an object, which would cause that object to accelerate. Over time, acceleration alters the object's velocity. Over time, velocity alters the object's position.

Force, Acceleration, Velocity, Position and Time. Those are the 5 things you need to worry about. If however, you also want your object to rotate, then you have Torque, Angular acceleration, Angular velocity and Orientation to worry about.

Though it seems like 2D physics should be pretty easy compared to 3D physics, the concepts are actually the same, but some of the formulae are simpler since they involve one less dimension.

I wrote a simple 2D physics engine in C# about 4 years ago, and Chris Hecker's articles on rigid body dynamics were an invaluable resource.

Currently working on an open world survival RPG - For info check out my Development blog:

### #4LAURENT*  Members

Posted 31 May 2014 - 08:14 AM

I think it's force I don't understand. I'll look up every word so I can be sure that's not the only thing I don't know. Anyways here is my sloppy ugly looking code. It uses 2 files. My game is isometric but I've gone over the logic. All I need to do is is to create 2D gravity for certain objects for my game to work correctly

#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED

enum {EMPTY, CIRCLE, CROSS};
class Game
{
public:
Game::Game()
{
const int FRAMES_PER_SECOND = 30, YS_WIDTH = 30, YS_HEIGHT = 30,
SCREEN_WIDTH = 589, SCREEN_HEIGHT = 404;

circle= IMG_Load("circle.jpg");   // rond = circle
board= IMG_Load("board.jpg"); // grille = board
//Initialize the velocity
};
//Tic tac toe Game function
void character_level(SDL_Surface* screen);
void play(SDL_Surface* screen);
int check_victory(SDL_Surface* screen);

//Velocity and movement funtions

void handle_input(SDL_Surface* screen);

void move(SDL_Surface* screen);

void show(SDL_Surface* screen);

//The timer functions and various actions

void start(SDL_Surface* screen);

void stop(SDL_Surface* screen);

void pause(SDL_Surface* screen);

void unpause(SDL_Surface* screen);

//Gets the timer's time

int get_ticks(SDL_Surface* screen);

//Checks the status of the timer

bool is_started(SDL_Surface* screen);

bool is_paused(SDL_Surface* screen);
Game::~Game()
{
SDL_FreeSurface(horizontale);
SDL_FreeSurface(verticale);
SDL_FreeSurface(diagonale1);
SDL_FreeSurface(diagonale2);
SDL_FreeSurface(croix);
SDL_FreeSurface(circle);
SDL_FreeSurface(button);
SDL_FreeSurface(board);
};
private:
SDL_Surface *board, *circle, *croix, *horizontale, *verticale,

SDL_Event event;
int continuer,  turn,  end, nowinner, x, y, xVel, yVel;
int space1, space2, space3, space4, space5, space6, space7, space8, space9;
//int YS_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT , YS_WIDTH, FRAMES_PER_SECOND;
SDL_Rect boardPosition, positionforme, positionwon;
SDL_Rect button1, button2, button3, button4, button5, button6, button7, button8, button9;
SDL_Rect velocity;

//The timers private variables
//The clock time when the timer started

int startTicks, pausedTicks;

//The timer status

bool paused;

bool started;
};

#endif // GAME_H_INCLUDED



Cpp file

#include <stdlib.h>
#include <stdio.h>
#include <SDL.h>
#include <SDL_image.h>
#include <time.h>
#include "Game.h"
#include <string>

{

//The optimized surface that will be used
SDL_Surface* optimizedImage = NULL;

{
//Create an optimized surface

//Free the old surface

//If the surface was optimized
if( optimizedImage != NULL )
{
//Color key surface
SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ) );
}
}

//Return the optimized surface
return optimizedImage;
}

void apply_surface( int x, int y,  SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL)
{
//Holds offsets

SDL_Rect offset;

//Get offsets
offset.x = x;
offset.y = y;

//Blit
SDL_BlitSurface( source, clip, destination, &offset );
}
void character_movement( int x, int z,  SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL)
{
//Holds offsets

SDL_Rect movement;

//Get offsets
movement.x = x;
movement.y = z;

//Blit
SDL_BlitSurface( source, clip, destination, &movement );
}

{

if( YsguySheet == NULL )
{
return false;
}

return true;
}*/

void Game::character_level(SDL_Surface *screen)
{
int continuer = 1, x = 0, y = 0, xVel = 0, yVel = 0, end=0;
const int FRAMES_PER_SECOND = 30, YS_WIDTH = 30, YS_HEIGHT = 30, SCREEN_WIDTH = 589, SCREEN_HEIGHT = 404;
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
int z =0, zVel =0;
int gravity = 9;
int velocity = 36;

int startTicks = 0;
int pausedTicks = 0;
bool paused = false;
bool started = true;

while(continuer)
{
zVel += gravity;

//timer function start
startTicks = SDL_GetTicks();

//While there's events to handle
while (SDL_PollEvent( &event ))
{
//SDL_WaitEvent(&event);
if( event.type == SDL_QUIT )
{
//Quit the program
continuer = 0;
break;
}

//Handler Event function
if( event.type == SDL_KEYDOWN )
{
switch( event.key.keysym.sym )
{
case SDLK_UP: yVel -= YS_HEIGHT/10; break;
case SDLK_DOWN: yVel += YS_HEIGHT/10; break;
case SDLK_LEFT: xVel -= YS_WIDTH/10;  break;
case SDLK_RIGHT: xVel += YS_WIDTH/10; break;
/////JUMPING//////////////////////////////////////
case SDLK_SPACE:
for (zVel -= velocity ; zVel - 9 ; )

break;

}
}

else if( event.type == SDL_KEYUP )
{
switch( event.key.keysym.sym )
{
case SDLK_UP: yVel += YS_HEIGHT/10; break;
case SDLK_DOWN: yVel -= YS_HEIGHT/10; break;
case SDLK_LEFT: xVel += YS_WIDTH/10; break;
case SDLK_RIGHT: xVel -= YS_WIDTH/10; break;
}
} //Handler ends here
}

//Move function
x += xVel;
//If the dot went too far to the left or right
if( ( x < 0 ) || ( x + YS_WIDTH > SCREEN_WIDTH ) )
{
//move back
x -= xVel;
}

//Move the dot up or down
y += yVel;

//If the dot went too far up or down
if( ( y < 0 ) || ( y + YS_HEIGHT > SCREEN_HEIGHT ) )
{
//move back
y -= yVel;
} //Move ends here

z += zVel;
//If the dot went too far up or down
if(  z > y )
{
//move back
z -= zVel;
}

SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));

//Show the Ys on the screen
character_movement(x , z, YsguySheet, screen);

//Update the screen
SDL_Flip(screen);

//Cap the frame rate
if( get_ticks(screen) < 1000 / FRAMES_PER_SECOND )
{
SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - get_ticks(screen) );
}
}
}

int Game::get_ticks(SDL_Surface* screen)
{
//If the timer is running
if( started == true )
{
//If the timer is paused
if( paused == true )
{
//Return the number of ticks when the timer was paused
return pausedTicks;
}
else
{
//Return the current time minus the start time
return SDL_GetTicks() - startTicks;
}
}

//If the timer isn't running
return 0;
}


Edited by LAURENT*, 31 May 2014 - 08:20 AM.

### #5Postie  Members

Posted 01 June 2014 - 02:36 AM

Game physics is something that only works correctly if you update it at a constant, predictable rate, independent of the rate you're rendering to the screen. The way this is commonly achieved is to define how often you want to update your physics, eg, 20 times a second, and then calculate the elapsed time between each rendering frame. Accumulate that over several frames until you reach 1/20th of a second, then do a physics update, using 1/20th of a second as your time parameter in all your physics equations. This means that your physics updates are all done with the same time difference (or delta), and they happen predictably, which means the motion of your objects will be smooth.

I highly recommend you check out "Fix your timestep!", the seminal work on the topic.

Currently working on an open world survival RPG - For info check out my Development blog:

### #6LAURENT*  Members

Posted 01 June 2014 - 03:08 PM

I've found some source code of 2D games with acceptable physics. One even detects when the characters are touching the ground. Anyways thanks for the link. I see that you mention delta which was used in the sources I found. I love smooth and adore predictable so I guess I'll study delta time the most.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.