timing problems

Started by
8 comments, last by Illco 18 years, 10 months ago
I've developed several questions recently regarding timing for games. First, if I set up a timer to run my game at, say, 30 ticks per second, what code belongs within the timed loop? Obviously movement of game objects needs to go in here or else my game would run at different speeds on different systems. But should my render code also be locked in at 30FPS? It seems that a game would benefit--at least not be harmed--from being able to render as fast as possible. Related to my first question, does stuff like processing user input belong inside or outside the timed loop? My example of 30ticks/sec makes it unlikely, but I could see a player being upset if the game didn't process his keystroke because he tapped it when the timed loop wasn't executing; on the other hand, if processing input is outside the timed loop a tap might register as multiple strokes, and it would depend on the system how many keystrokes a constant length tap registers for. Third, I'm unsure about the best way to make objects accelerate. I can see two ways to do this, but both ways seem flawed. One way I've tried is simply increasing the value of an object's velocity variable, but doing this can break collision detection (in the worst case scenario, a sufficiently fast object could actually move through a thin object because jumped over the states where a collision would register). Another way I've considered is to quantize my game space: make every object's velocity either 0 or the resolution of my game space and then control acceleration by adjusting the rate at which velocity is applied to position. This method won't break collision detection because any moving object is guaranteed to pass through all significant intermediate states, but means that the speed of objects is limited by the speed of my game loop, which makes the maximum speed of objects surprisingly slow. Thanks in advance for any help you can give me.
Advertisement
First question:
Yes, everything is done every frame, In your case etery 1/30th of a second. So i’d make every 0.03333 second. If time needed to calculate and render the frame takes more than that (on slow systems), the next frame calculations, logics etc will take place instantly what can cause lags and warps. And yes - games should run as fast as possible (evey computer games player will tell you that).

Some time ago I was adviced to put the input of fast games to a separate thread. Don’t ask me how to do it – I haven’t learned yet. What I do in case of my frame independent loops is this:

float Time_Since_Keypressed;

if (keypressed())
{
playerpos+=10;
Time_Since_Keypressed=0.1 //for example
}

Time_Since_Keypressed-=time_span; //time_span is time it takes to loop through the wole frame

Keystrokes are buffored (somewhere in RAM) so there is no need to worry the Windows Message Que may miss something.

As for the acceleration and movement, well, this is what I did: I searched my attic for old phisics and maths books and had to review chapters of topics that were of interest to me. General acceleration formula looks like this:

S=V0*t+(a*t*t)/2

But all above is very nicely explained here.

Good luck

Peter
I think all three points are problematic because you fixed your timer rate at 30 ticks per seconds. Why? There is no need for a fixed-time timer.

My (single-threaded) approach would be the following. Have the game loop run indefinetely at the maximum speed -- i.e. somehwere you'll end up with:
Quote:
while( true )
{
// This is the game loop.
}


Then during each loop you compute the elapsed time since the last loop iteration. This is done by keeping track of 'last_time_the_timer_was_queried' and 'current_time_just_queried' and subtracting them; subsequently storing the second in the first for the next loop.

Then object movement can be done more continuous, as we know the time since the last frame. Hence:
velocity = velocity + acceleration * elapsed_timeposition = position + velocitiy * elapsed_time

There are some catches here but this is the basic idea. The collision will have to make do with possible objects passing each other in between frames -- i.e. it will require some sort of sweep check.

If you have certain things you don't want to do at maximum speed -- perhaps frame rate limiting or user input polls -- you can keep track of a frame counter and only do those thing every 100th or 1000th frame.

Good luck! Greetz,

Illco
You might want to check out this article as well.
Thanks to all of you. I clearly wasn't looking at this problem from the right direction and I think I'm back on track now.
I've got most of what's been suggested working excellently now. However, I'm having trouble with collision detection now (and feeling really stupid because 2D collisions should be easy to test for). Because objects now update by time and not by frame, they no longer necessarily will register a collision with a sufficiently thin object. For example: if the program is running unusually slowly, values for time will be greater so velocity * time will yield a greater displacement: if this displacement moves an object from x = 5 to x = 10 (pulling numbers out of a hat) and and another object exists at location 7 < x < 8, no collision will register because the moving object never actually exists in the intermediate state. Illco mentioned a "sweep check" as a possible solution to this problem, but I've tried googling it and haven't turned up much. Can anyone explain to me what this is, or point me to an article that does?
I'm not sure what kind of game you're making, but for most 2D games, you can test for collision pretty cheaply by just sampling the vector of movement before you apply it. It's kind of like gimp raycasting. Let's just say this is the your world (C = character, X = Obstacle)

C X $

If the player moves to the right, and the movement is Queued due to timing constraint, just sample every pixel/tile in the movement path and verifying if it's passable or not.

Depending on your data structure, this could be a hertz-hog, but if you've got either a tile-based world or a pixel-matching/linear world setup (sidescroller for example) it's pretty cheap. I used it in Not Quite FF I, and it worked quite well.

~Pax
That approach will work until the thin objects start moving as well. In such a case, you cannot sample the movement vectors (unless you perhaps sample them pairwise, but that would have an impact on you design). Here's an article about intersection tests for games.

Illco
Quote:Original post by Illco
That approach will work until the thin objects start moving as well. In such a case, you cannot sample the movement vectors (unless you perhaps sample them pairwise, but that would have an impact on you design). Here's an article about intersection tests for games.

Illco


Yes and no...

If you set up your code to move objects first then calculate the player vector, it works. If the objects move synchronously or after the players, it breaks down.

~Pax
Quote:
If you set up your code to move objects first then calculate the player vector, it works. If the objects move synchronously or after the players, it breaks down.

If an object moves from A to B, and the player subsequently moves, crossing the path AB, this fails. The collision check only sees the object in position B, allowing the player to pass, while in fact they would have collided amidst.

Also you'd have to take collisions between non-player objects into account.

Greetz,

Illco

This topic is closed to new replies.

Advertisement