Advertisement

moving objects...

Started by March 27, 2000 05:06 PM
7 comments, last by ViPeR007 24 years, 8 months ago
I forgot which way is the best way to move objects on the screen so that everything will move the same speed on all macines. I don''t think it was by time but I might be wrong? What is the best way of doing this? Thanx, ViPeR
Ahar, another person with this question. Its all I seem to be good at answering

You are right in thinking that you should update with respect to time to make your game framerate/machine independent.

The best way to do this is to record a time with timeGetTime(), or something like that, at the start of the game, then every frame/2nd frame/whatever check the time again, and update your game state using the amount of time that has passed from the previous check (then storing this current time for comparison with the next one, and so on).

Or, alternatively, you can check the time each frame, and if a certain amount of time (or greater) has passed, do an update (using the actual amount of time that has passed, not the nominated amount you are checking for), and store this current time for the next comparison, and so on.

Sorry if this is confusing, as my brain is a bit scrambled from sleeping in and having to bail to work late (good to see I''m now working hard, eh )

No doubt others will sugest using other timing mechanisms and such, but I don''t care which you use, I''m just explaining the idea behind updating by time, mmmmkay

The Time-Update Avenger strikes again...

-------------
squirrels are a remarkable source of protein...
Advertisement
Every frame, count how many seconds passed during the previous frame''s update (the time taken to move, draw, etc.. stuff). You''ll use a high resolution time function for this. Since games update many times per second you''ll end up with a fraction that you should store as a floating point number. When you move objects, give them a velocity. To determine how much you should move each object, multiply the velocity by the time. This will give you what you want - the amount of translation to add the object''s position.

www.gameprojects.com - Share Your Games and Other Projects
Ok, let me tell you whats happening. My game engine runs fine on my 3 machines (200, 400, 500MHZ), all at the same speed and everything. Now when I put it on my friends machine he runs it REALLY fast (he has a 350MHZ and same video card) for some reason. So what I tried doing is putting a variable like time_to_wait = 10; Then in my main game loop I counted it down (time_to_wait-- and when I got to zero and did movement. He said that helps a little bit but not that much. Of course if I increase the time_to_wait then it will run really slow on my machine and fine on his. So how do you use GetTickCount() to how much time it took to render the last frame? Because from what I have read from there all I have to do is take that number/fraction and set it as my vel and then move every object from this.

Thanx for the help,
ViPeR
Viper,
Probably what is happening is that your PCs are synching to the vertical refresh rate, while your friend''s PC is not.

I think by default Direct Draw waits for the vertical redraw before performing a flip, but this can be overriden by the video card drivers.
If you want to sync to the refresh rate no matter what, you can call the WaitForVerticalBlank() function right before you flip.
That should be a quick way solve the running too fast problem on your friends computer.
However, if you were scaling the movement of your objects by the elapsed time, as Nedelman suggested, you wouldn''t have to worry about limiting the speed.
It doesn''t like WaitForVerticalBlank(), its doesn''t recognize it (I all the directx files included). I want to use the method Nedelman suggested but Im not sure how I would get how much time went by when the last frame was rendered and store it.

Thanx,
ViPeR
Advertisement
WaitForVerticalBlank is a function of the IDirectDraw7 class, sorry for not stating that before.

As for timing, you have a couple of options:
1. GetTickCount() - This will return the number of milliseconds (1000ths of a second) that have elapsed since Windows started.
2. QueryPerformanceCounter() - to get the current value of the high resolution counter.
QueryPerformanceFrequency() - to get the counter frequency, or how much the counter increases each second.
You should look up these functions in your compiler help.
Option #2 is much more accurate, and preferable if you are running at high framerates, but it is not necessarily supported by old CPUs.

Each time through your game loop you want to determine how much time has passed since the last cycle through your loop.
So for example, you might have this in your game loop (very incomplete code, but just to give you an idea):

LastTicks = CurrentTicks;
CurrentTicks = GetTickCount();
ElapsedSeconds = (CurrentTicks - LastTicks) / CounterFrequency;

Then, anywhere where you add velocity to a position, or acceleration to a velocity, you multiply by the ElaspedSeconds.
Example:
Velocity = GravityAccel * ElapsedSeconds;
Position = Velocity * ElapsedSeconds;

Keep in mind that if you are switching over to this method, you will have to adjust all of your velocities so that they are in terms of units/second.
There are other things to consider as well, but this should get you started.
Well moving the objects by the time/velocity method doesn''t seem to be helping anything at all. I got it to work and everything but it doesn''t make any difference. By the way I tried to get WaitForVerticalBlank() to work but I don''t know what parameters to give it. In the .h file it looks like it can have 2 or 3 but I don''t know what they are. Have any idea?

Thanx,
ViPeR
If you have the DirectX 7 SDK, it comes with its own help, which is very useful. I refer to it all the time.

Anyway, here is the code to get it to work:

lpdd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);

And here is an excerpt from the help describing what the parameters are:

Parameters
dwFlags
Determines how long to wait for the vertical blank. One of the following flags:
DDWAITVB_BLOCKBEGIN
Returns when the vertical-blank interval begins.
DDWAITVB_BLOCKBEGINEVENT
Triggers an event when the vertical blank begins. This value is not currently supported.
DDWAITVB_BLOCKEND
Returns when the vertical-blank interval ends and the display begins.
hEvent
Handle of the event to be triggered when the vertical blank begins. This parameter is not currently used.

This topic is closed to new replies.

Advertisement