Sign in to follow this  

Time Based Movement?

This topic is 4818 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

Can somebody please explain to me what time based movement is and how I would incorporate it into games? I decided to remake my Pong clone since my other game project is going a bit slow but with sounds and a font engine. Last year when I first made it, it was just the ball bouncing back and forth between the paddles and there was no score or anything. Back to my question, how would I use time based movement for the game objects like the paddles and balls? If it helps, I'm using C/C++ with the SDL graphics API.

Share this post


Link to post
Share on other sites
I read through that article but it isn't working properly. Here's some source snippets:

float paddleMovement; // How far can the paddles move in a second?
float movementValue; // Value to move each frame
float secondsPerFrame; // Holds the value for how many seconds have elapsed between frames
float timeDifference; // How much time has elapsed?
float timer; // Keeps track of the time

void CEngine::CalculateTime()
{
// Determine how many seconds have elapsed
timeDifference = SDL_GetTicks() - timer;

// The function reads in milliseconds so convert to seconds by dividing by 1000
secondsPerFrame = (float)(timeDifference / 1000.0f);

// Now compute the movement value
movementValue = (float)(paddleMovement * secondsPerFrame);

// Get the new time
timer = (float)SDL_GetTicks();
}



if (Engine.keys[SDLK_s] && Player1.GetY() != 400)
{Player1.AddY((float)1 * Engine.movementValue);}


If I push S, the paddle doesn't move at all. If I take out the multiplication, the paddle moves. So my guess is that somewhere along the lines movementValue is getting assigned to 0. Unless it has to do with my type casting but I kinda doubt that.

Share this post


Link to post
Share on other sites
first of all, a simple design thing. i notice you are doing the player's movement outside of the player's code (i saw a Change_Y() function). This probably isnt a good idea. you should encapsulate all the player's abilities to inside the player...

secondly, your calculating the time passed in a not-so-good way. i notice you record the time at the bottom, then calculate the difference at the top. first of all, isnt this backwards? wouldnt you want to start the timer at the top, and record the difference at the bottom? otherwise, your just recording how much time since the bottom end of the loop till the top. this is probably 0 MS. hence, why your movement is 0 when you multiply....

anyway, even reversing it isnt a good idea. you should do all time calculations in one place. this is because your OS / game can act funky and the time wont be accurate. (sorry i dont know the exact reason why, i cant describe it in words, but someone here might.) anyway, you should do time-recording in one spot. like this:


previous_time = current_time;
current_time = SDL_GetTicks();
time_passed = (float)(current_time - previous_time) * 0.001f;




this block of code should be at the top of the loop.

why are you changing the Y by 1*movement? whats the 1* there for? anyway, it should look something like this then:

BTW - timer and timeDifference need not be a float. an Uint32 or int would be fine here.

void CEngine::CalculateTime()

{

previous_time = current_time;
current_time = SDL_GetTicks();
time_passed = (float)(current_time - previous_time) * 0.001f;
}





now, in your player movement code.. (move this to inside your player class!!!


if (Engine.keys[SDLK_s] && yPos != 400)
{yPos += (time_passed * paddle_velocity));}




that should work.

Share this post


Link to post
Share on other sites
Still no go. Here's my main.cpp file where I have everything:


#include "CEngine.h"
int main(int argc, char *argv[])
{
int previous_time = 0;
int current_time = 0;
int time_passed = 0;
CEngine Engine; // Generic engine used throughout game
Engine.Init(); // Initialize everything
// Begin the main game loop
bool done = false;
while (done == false)
{
previous_time = current_time;
current_time = SDL_GetTicks();
time_passed = (float)(current_time - previous_time) * 0.001f;
// Check for events
SDL_Event event;
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT) {done = true;}

if (event.type == SDL_KEYDOWN)
{
if (event.key.keysym.sym == SDLK_ESCAPE) {done = 1;}
if (event.key.keysym.sym == SDLK_p) {Engine.paused = !Engine.paused;}
if (event.key.keysym.sym == SDLK_1 && Engine.menuDrawn) {Engine.menuDrawn = false; Engine.paused = false;}
if (event.key.keysym.sym == SDLK_2 && Engine.menuDrawn) {done = 1;}
}
}

// Poll key events
Engine.keys = SDL_GetKeyState(NULL);

if (Engine.menuDrawn == false && Engine.paused == false)
{
// Player 1 controls
if (Engine.keys[SDLK_w] && Player1.GetY() != 0)
{Player1.AddY((time_passed * -2));}
if (Engine.keys[SDLK_s] && Player1.GetY() != 400)
{Player1.AddY(1);}

// Player 2 controls
if (Engine.keys[SDLK_UP] && Player2.GetY() != 0)
{Player2.AddY(-1);}
if (Engine.keys[SDLK_DOWN] && Player2.GetY() != 400)
{Player2.AddY(1);}
}

// Draw everything
Engine.DrawScene();
}
Engine.CleanUp();
return 0;
}



I push 's' and it still doesn't move at all. Also, I have two main classes that are in use here. CEngine with does all the game related functions and CSprite which handles all Sprite related functions. When s is pushed, it uses the AddY() function defined in CSprite to change it's position on the Y axis.

Share this post


Link to post
Share on other sites
hmm. it apears in your code you do

if(s is pushed)
add 1 to y

why is this? you dont even use your time based movement here, so pushing S definetly should move your sprite. this is a problem in the addY() function then...

also, while previous time and current time should be int's, time_passed needs to be a float. this is because most of the time it should be a number less then 1, like 0.4 or something like that.

lastly, i notice where you DO use time based movement to move the sprite, you have it * -2. when doing time based movement, you will want to use numbers much bigger then when you didnt use it. try switching this to -200.

Share this post


Link to post
Share on other sites
Sorry about talking about "s" when it was actually "w". I have one last question now. The time-based movement stuff works now but how do I know what values will allow the sprite to move X pixels? time_passed * 200 works fine but how do I know it's moving 200 pixels? time_passed * 100 doesn't work so apparently it doesn't exactly move it 200 pixels, that's just the only acceptable value right now.

Share this post


Link to post
Share on other sites
Well, it moves it very slowly and sometimes it's unevenly moved. Like...it'd jump.

if (Engine.keys[SDLK_w] && Player1.GetY() != 0)
{Player1.AddY((time_passed * -100));}

Same time calculation code as before. I guess for later projects I should just fool around with the numbers until I get what I think is a good speed?

Share this post


Link to post
Share on other sites
I don't mean to sound rude, but use your debugger! Check out your time values, trace through your movement methods and check the values of you sprite positions. It would probably take less time that sitting there posting code snippets and asking why it doesn't work.

Again, I do not mean to sound rude, but using the debugger is quite helpful!

Share this post


Link to post
Share on other sites

This topic is 4818 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this