View Full Version : How do you do your timers?
Gnatinator
05-09-2005, 12:02 PM
Hey guys.
I've got a pretty crappy timer system in place for my game atm. Do any of you have any suggestions/code for good high performace timers? (under windows and or unix/osx)
Thanks :)
ggambett
05-09-2005, 12:17 PM
Heh, try to beat me at crappy timers! I use SDL_GetTicks() with supposedly reports milliseconds, calculate time since last update, and send onUpdate() to various parts of the framework; there, I do this
void PlayMode::onUpdate (float fTime)
{
m_fTimeSinceSomething -= fTime;
if (m_fTimeSinceSomething < 0)
{
m_fTimeSinceSomething = SOMETHING_INTERVAL;
doSomething();
}
...
}
Mike Boeh
05-09-2005, 12:21 PM
Timer.h
#ifndef TIMER_H
#define TIMER_H
#include <windows.h>
class Timer{
private:
LARGE_INTEGER tstart, tticks, tnow;
int Started;
int HighFreq;
public:
Timer();
~Timer();
void Start();
int Check(int FracSec); //Enter the fractions of a second you'd like the result in, e.g. 1000 for ms.
};
#endif
Timer.cpp
#include <Timer.h>
Timer::Timer(){
HighFreq = QueryPerformanceFrequency(&tticks);
Started = FALSE;
}
Timer::~Timer(){
}
void Timer::Start(){
if(HighFreq){
QueryPerformanceCounter(&tstart);
}else{
tstart.LowPart = timeGetTime();
}
Started = TRUE;
}
int Timer::Check(int FracSec){
if(!Started) return 0;
if(HighFreq){
QueryPerformanceCounter(&tnow);
return (int)(((tnow.QuadPart - tstart.QuadPart) * FracSec) / tticks.QuadPart);
}else{
tnow.LowPart = timeGetTime();
if(tnow.LowPart < tstart.LowPart){ //Oops, millisecond rollover.
return (int)(((tnow.LowPart + (0xffffffff - tstart.LowPart)) * FracSec) / 1000);
}else{
return (int)(((tnow.LowPart - tstart.LowPart) * FracSec) / 1000);
}
}
}
Pyabo
05-09-2005, 02:07 PM
So did we ever figure out if QueryPerformanceCounter is still reliable with the new step-down power saving CPUs?
I seem to recall from another thread that this was an issue...?
Larry Hastings
05-09-2005, 02:27 PM
So did we ever figure out if QueryPerformanceCounter is still reliable with the new step-down power saving CPUs?We figured out that it is not reliable. On hyper-threaded P4M laptops with SpeedStep, the actual frequency of QPC will jump all over the map. (All the while, QPF will report the same number.) I'm trying to solve this problem in my timing class too, but it's hard to wrap my brain around the eleventy-seven different conditions I have to handle simultaneously. But I'll get there eventually.
wazoo
05-10-2005, 07:27 PM
This could be a question worthy of MS's attention, but for now what's wrong with just sticking with plain ol' timeGetTime()?
True it may not have the same granularity as the QPF, but for 90% of the projects out there it should be good enough right?
*shrug*
Jim Buck
05-10-2005, 10:34 PM
Like I had said in another thread, Quake 2 uses it with no problem. But that game might move so fast that you wouldn't notice the granularity problems. I now when I was making tests with mouse movement, timeGetTime was radically inaccurate.
soniCron
05-10-2005, 11:28 PM
But that game might move so fast that you wouldn't notice the granularity problems. I now when I was making tests with mouse movement, timeGetTime was radically inaccurate.
If that's the case, and Q2 (obviously) uses mouse input as well, wouldn't that make Q2's mouse input radically inaccurate? Maybe there's a way?
Travis Dorschel
05-11-2005, 09:29 AM
Personally I have just used QueryPerformanceCounter in all of my projects and I fall back to a ms resolution (timeGetTime or GetTickCount) approach if it isn't there. I also keep an array of the last X number of frames time steps and average them out for the current time step.
After the discussion about QPC not being accurate all the time I think I will also use a hybrid approach where the QPC result is tested against the ms resolution and if it is off by more than a few ms the last frames result is used or the ms time is used. Basically I think using multiple timers and comparing the results and averaging out over a number of frames could solve these problems.
ggambett
05-11-2005, 09:36 AM
This could be a question worthy of MS's attention, but for now what's wrong with just sticking with plain ol' timeGetTime()?
I second that, do you really need more than milliseconds? Do you even need milliseconds?
soniCron
05-11-2005, 09:48 AM
I second that, do you really need more than milliseconds? Do you even need milliseconds?
Well, you can run into problems that don't make themselves obviously aparent. For one, with MS accuracy, depending on how you're handling movement in the game, things can get pretty jerky. That can be worked around. However, as someone said on another thread, online play actually gets out of sync, and after a while, they just quit because they're too far out of sync. Same reason why you souldn't cap your framerate at 60FPS (usually), because the granularity doesn't afford you much flexibility if stuff starts getting out of sync. Then again, if it works for ya, stick with it!
Jim Buck
05-11-2005, 10:34 AM
If that's the case, and Q2 (obviously) uses mouse input as well, wouldn't that make Q2's mouse input radically inaccurate? Maybe there's a way?
Since Quake2 is a fast action game, the inaccuracies are probably only a small % of the wide range of mouse movement used in the game. In my own tests, I was plotting graphs of mouse velocity and acceleration while moving the mouse slowly.. I was getting *huge* spikes when using timeGetTime and got baby-smooth graphs when using QPC.
Though timeGetTime uses milliseconds, and most games wouldn't need more resolution than that, I get the feeling that the milliseconds that timeGetTime *does* give are often divergent from actual milliseconds.
Mike Boeh
05-11-2005, 10:54 AM
timeGetTime() can have a granularity as high as 14 ms, meaning that you can't get the precision you need for silky smooth motion....
Adrian Lopez
05-11-2005, 11:38 AM
A granularity of 14ms would give you 74 clicks per second, which doesn't seem that bad to me.
BantamCityGames
05-11-2005, 12:08 PM
timeGetTime() can have a granularity as high as 14 ms, meaning that you can't get the precision you need for silky smooth motion....
Yeah, which is all too obvious when making an arkanoid game.
ggambett
05-11-2005, 12:11 PM
timeGetTime() can have a granularity as high as 14 ms, meaning that you can't get the precision you need for silky smooth motion....
If an object moves at 600 pixels per second, which sounds relatively fast, it will travel 0.84 pixels in 14ms. I'm surprised this isn't smooth enough :confused:
Jim Buck
05-11-2005, 12:16 PM
Check your math - it would move 8.4 pixels in 14ms. :)
soniCron
05-11-2005, 12:22 PM
I'm surprised this isn't smooth enough
You have to understand that timeGetTime() isn't very accurate. It's not always exactly 1ms. Because of that, things that are traveling like a ball in an Arkanoid clone can get jerky. 8.4 pixels in 14ms may seem smooth, but it may actually be 8.4px in 14ms, then 8.4px in 16ms, then 8.4px in 8ms, then 8.4px in 13ms. You get the idea. That doesn't look as smooth as it could. But it IS mostly functional.
Adrian Lopez
05-11-2005, 01:01 PM
I think soniCron makes a good point, as smoothness has nothing to do with how many pixels your sprite moves every second. After all, if your screen has a refresh rate of 70 Hz (70 frames per second, like clockwork), a speed of 600 pixels per second means you'll see it move about 8.5 pixels every frame. With a refresh rate of 85 Hz, you'll see it move about 7.05 pixels every frame. Even with a refresh rate of 120 Hz, it would move 5 pixels per frame.
Smooth animation is achieved if your sprites, while traveling at a particular speed, move the same distance every single frame.
Adrian Lopez
05-11-2005, 02:01 PM
Regarding problems with SpeedStep, look at what I found (http://www.intel.com/cd/ids/developer/asmo-na/eng/209859.htm?page=1) on Intel's website.
Edit: Spoke too soon. I can't find the code for this etimer the paper discusses.
Ryan Clark
05-11-2005, 02:29 PM
This article discusses the timer issue, and it makes note of the SpeedStep problems. It might help:
http://www.gamedev.net/reference/articles/article2086.asp
I'm not overly concerned myself, as our current (puzzle) game does quite well with SDL_GetTicks only!
Mike Boeh
05-11-2005, 03:12 PM
I have never understood how so many people, including game developers, can't perceive what smooth really is. To me, 14 ms is totally unacceptable, and looks night-and-day different than a true 1 ms timer.
Adrian Lopez
05-11-2005, 03:17 PM
For a 1ms timer to be significant (compared to a 2ms timer) you'd need a refresh rate higher than 500 Hz. Somehow, I don't think that's very realistic :D.
soniCron
05-11-2005, 03:21 PM
I have never understood how so many people, including game developers, can't perceive what smooth really is.
Well, in their (our?) defense, smooth is somewhat relative. Without a reference of what smooth really is, it is actually very hard to notice in your own programs that something isn't very smooth. I often run other software that I've noticed is very smooth for a reference.
It's like noticing the difference between 24FPS and 30FPS video. Subtle, but with a comparison, it's like night and day. However, a lot of people don't know there's a difference. I am aware of the technical differences in the two major motion video methods (film and video), so of course, by now I'm able to detect the framerate of video without a hitch (to a point). But because most people don't know there is a difference, it's not at the tip of their brain when they see video, so they don't even notice.
Mike Boeh
05-11-2005, 03:24 PM
For a 1ms timer to be significant you'd need a refresh rate higher than 500 Hz. Somehow, I don't think that's very realistic :D.
That would only be true if timers were sync'd to the refresh rate of the monitor, which they aren't.
For example, if you take a 14ms, you don't know how far into the 14 ms you are when the screen draws, so there are going to be "rounding" errors there, causing choppy motion.
Adrian Lopez
05-11-2005, 03:39 PM
What I'm trying to say is that querying the timer more than once per frame will gain you nothing because -- in most cases -- you're relying on a single time sample to tell you what to draw each frame. If the refresh rate is 70 Hz then there's not much use in being able to query the clock more than once every 14 milliseconds.
soniCron
05-11-2005, 04:32 PM
(Note: this post assumes single-threaded logic/draw, because I'm using frame rate as a time quantifier because of it's simplicity.)
For a 1ms timer to be significant you'd need a refresh rate higher than 500 Hz. Somehow, I don't think that's very realistic :D.
First of all, "higher than 500 Hz" would need to be 1,000Hz (1MHz), or 1,000 ms per second, for your example. Second, it's not about seeing every frame update, but scaling down the high frequency data to fit onto a monitor (game logic and drawing -> monitor refresh rate). With a refresh rate of 60Hz (or any lower than very, VERY high refresh rates), you run into certain issues that aren't so easy to overcome: quantization.
Quantization is created when converting an analog signal to a digital signal. Think of the analog signal as the logic and motion in your game. (The definition of analog is any data that are represented by continuously variable, measurable quantities. ie. Anything you can break down in half, in half, in half, forever, but never reach a discrete and exact value.) Think of the digital signal as your refresh rate, or better yet, your draw rate. (Digital is anything that uses discrete values rather than a spectrum of values. ie. Whole numbers, the pixel locations on the screen, are discrete, irrational number, sound waves, are analog.)
Now, when you take an analog signal (your object's motion) and try to display it on your monitor, you must convert that analog signal to digital, because you must pick an exact point in your logic (which isn't discrete) to capture everything that needs to be drawn at their current locations, and draw them on the screen (which makes that exact moment discrete, thus digital). Herein lies the problem:
Imagine you've got one object moving at 1 pixel per frame, and you've got another object moving at 1.5 pixels per frame. You take a picture of the first frame. Frame one, both are at their starting locations. You take a picture of the second frame. They've both moved their respective distances in your logic. You draw them on screen, and object #1 is exactly 1 pixel over to the side. However, object #2 is 1.5 pixels over to the side. But there aren't half-pixels! So where do you draw him? Well, if you're interested in being exact, you'll blend between those two pixels. But he's still being drawn in a discrete (digital) location, you've just fooled the user's eyes into thinking he's between pixels.
Now, there's a problem with that last example. We were talking about them moving at 1 pixel per frame, and 1.5 pixels per frame. These speeds are, you guessed it, discrete! They're digital representations of speed because you're using pixels and frames as a reference. Let's suppose, instead, you use "units" as the movement reference. You want your object moving across the screen at 313 units per second. But what is a unit relative to the pixels on the screen? Doesn't matter. We just need to know that it's moving at 313 units per second. We'll assume for simplicity that 1 unit = 1 pixel, but it doesn't really matter. A unit can be equal to a foot, a nanometer, whatever you'd like. How you draw it on the screen is up to you.
So now you must pick a timeframe to pause motion calculation and draw everything to screen. When do you do that? 10 times a second? 42? 9,000? Well, 9,000 is too fast for the monitor to display, so we'd be wasting our time drawing so much (and be getting wicked bad tearing). 10 is too slow, our eyes would notice such jerky gameplay. Lets pick a nice number...say, 60 times per second. That just so happens to be most monitor's lowest refresh rate (and some monitors' only refresh rate).
So 60 times a second, we pause everything, take all the data of the objects' positions, and draw them on the screen. Let's find out how far the object has gone in 1 ms at 313 units per second:
313 units per second / 1,000 ms (one second) = 0.313 units per ms
At 313 units per second, the minimum we can move the object is 0.313 units per ms. This may not seem like a lot, but now we hit the wall. Since we're redrawing at 60fps, we need to draw every 16.66666 ms. (1 second / 60fps = 16.66666)
But wait! We can't draw on the .66666 part, because we can only detect when a new whole ms has arrived. So this means that sometimes we're gonna draw every 16ms, and sometimes we're gonna draw every 17ms. "Bah, 1ms, who cares?" you ask. "BAH! You will!" I say!
The object is moving at 0.313 units per ms, so before we draw the frame it can move:
0.313 units per ms * 16 ms = 5.008 units
at minimum, and:
0.313 units per ms * 17 ms = 5.321 units
at maximum. Remember, we can't draw on the 0.66666 ms, because we can't detect it.
That's a difference of, you've got it, 0.313 units per frame! So let's say we've got a rendering path with 40 16ms frame times, and 20 17ms frame times, which would equal the number of frames drawn in one second. (40 frames @ 16ms + 20 frames @ 17ms = 60 frames per second, our framerate) Let's add this all up:
40 * 5.008 units = 200.32 units
20 * 5.321 units = 106.42 units
Total: 200.32 units + 106.42 units = 306.74 units
The object has moved 306.74 units in 1 second. WHOA! But our object is supposed to move at 313 units in 1 second! We're 6.26 units SHORT of where we should be right now!
6 pixels is, however, barely noticable. Let's say, instead, we're making an arkanoid clone. The ball is moving at 3x the speed of our last object, at 939 units per second. This is going pretty fast, but not as fast as it would get during a highly heated session of gameplay. Now let's multiply our error factor by 3x:
6.26 units short * 3 = 18.78
Over 18 units off where we should be! And that's just for one second. Imagine second after second after second of gameplay. After 10 seconds, the ball is 187.8 units off course. That's over 1/3 the width of a 800x600 resolution! That's a huge discrepency.
So, as you can see, there is nothing to lose with finer granularity. Slow moving games wouldn't notice much improvement in the finer granularity, because the offsets would be very minor per frame.
If you'd like to see a more common example of this, open up Sound Recorder. Open your favorite Windows sound (usually in C:\Windows\Media\). Play the sound a couple times to familiarize yourself with it. Now click File->Properties. Click the "Convert Now..." button, and under the "Attributes" dropdown list, change it to 8 Bit, while keeping the same sample rate (Hz). Click your Ok's, and listen to the sound again. That, my friend, is a prime example of quantization, our enemy in this digital world.
What I'm trying to say is that querying the timer more than once per frame will gain you nothing because -- in most cases -- you're relying on a single time sample to tell you what to draw each frame. If the refresh rate is 70 Hz then there's not much use in being able to query the clock more than once every 14 milliseconds.
Your not getting it. First off, if you lock the game to vsync you don't need to use a timer. The duration of a frame is 1/vsync seconds. But many games do not use vsync, because they are windowed or rendering time can't be guaranteed, and they do need a hires timer.
Let's do a quick example. Timer accuracy is 14 milliseconds. Framerate vary between 50 and 100 fps, 10 - 20 ms (think high end first person shooter where smal change in direction can result in large difference in rendering time).
frame 0 - real time = 0 ms, mesured time = 0 ms
frame 1 - real time = 13 ms, mesured time = 0 ms (notice no update)
frame 2 - real time = 29 ms, mesured time = 28 ms (a clock tick was skipped)
This is worst case, but it is because of this kind of things that you really need atleast 1 ms accuracy.
sparkyboy
05-11-2005, 04:36 PM
Hey guys.
I've got a pretty crappy timer system in place for my game atm. Do any of you have any suggestions/code for good high performace timers? (under windows and or unix/osx)
Thanks :)
Check this out guys:-
http://olofson.net/examples.html
Download and try the PIG example.On my old 350mhz AMD,this example
ran smoother than silk,even with all the usual background programs running.
Out of all the games i've downloaded and tested,only this plus those from arcade lab ran on my pathetic machine without skipping a beat. :cool: :eek:
Everything else I've tried has missed frames here and there causing jerkiness. :(
Forgot to mention,if you haven't tried.It includes all source.I'm sure you c++ gurus may find the timing code useful.
Adrian Lopez
05-11-2005, 06:36 PM
soniCron: Reading your post makes my head hurt, but it seems to me there's a flaw in your argument. You're assuming that you'd update each sprite a fixed number of units every frame, which would defeat the purpose of using a timer in the first place. Proper use of a timer would not lead to the accumulation of error you allude to.
tom: You're right. I was assuming the game's drawing would be tied to vsync, but the scenario you present is certainly possible when vsync is ignored. However, I do not agree that timers are unnecessary when vsync is enabled, as the framerate will sometimes drop to (1 / 2X) of the refresh rate.
Perhaps if I disclose my assumptions you can better understand what I was trying to say: if vsync is enabled and the two timers (vsync and time) aren't slipping relative to each other, it wouldn't make any sense to have a timer more accurate than is necessary for a particular refresh rate.
In any case, I stand corrected.
Adrian Lopez
05-11-2005, 08:00 PM
Somebody brought up this link (http://www.cbloom.com/misc/) in another thread (http://forums.indiegamer.com/showthread.php?t=2394&page=1).
soniCron
05-11-2005, 08:02 PM
soniCron: Reading your post makes my head hurt, but it seems to me there's a flaw in your argument. You're assuming that you'd update each sprite a fixed number of units every frame, which would defeat the purpose of using a timer in the first place. Proper use of a timer would not lead to the accumulation of error you allude to.
Adrian, you're quite missing the point. The use of fixed motion in the example was for nothing more than simplicity. The crux of it is simple: quantization. If you do not understand or know what quantization is (even after reading my last post), then I suggest you Google it and learn more. If you are arguing that what I had to say is useless and flawed (at least fundamentally) then you obviously do not understand what quantization is. However, since the post made your "head hurt", it is obvious you're either missing something entirely or unwilling to educate yourself on the theory involved in any kind of discrete processing method, and nothing I do can help you.
Edit: Adrian, I appologize. I just re-read this post, and it sounds very rude. I surely didn't mean to come across as rude! So please forgive the harshness of this post.
Adrian Lopez
05-11-2005, 08:22 PM
I'm glad you've edited your post, so I'm not offended, but I'd still like to offer my reply:
I understand there are no screens with an infinite number of pixels whose positions are described by floating point numbers. All I meant is that errors would not accumulate in the manner you suggest when a timer is used appropriately.
In any case, I have experienced quantization problems myself (a long time ago) as my scrolling backgrounds would jerk around every so often as my floating point accumulator would cross the (0.999...) limit and be rounded down to the next integer. In addition, I've also alluded to the (1 / 2X) change in framerate whenever a frame takes slightly longer to draw than X monitor frames.
By the way, the reason I said your post made my head hurt is that I felt it was more than slightly patronising, ("WHOA!"), not to mention rather verbose.
soniCron
05-11-2005, 08:28 PM
By the way, the reason I said your post made my head hurt is that I felt it was more than slightly patronising, ("WHOA!") not to mention rather verbose.
I appologize again, Adrian. I was trying to make it "friendly" Not for you, but everyone. It's been a long day, and I guess my charm has taken a vacation!
Adrian Lopez
05-11-2005, 08:39 PM
In addition, I've also alluded to the (1 / 2X) change in framerate whenever a frame takes slightly longer to draw than X monitor frames.Damn... make that ( 1 / (X + 1) ). Wish I had a time machine.
Mike Boeh
05-12-2005, 07:33 AM
Here is a little test to show the difference in smoothness with different timer precisions. Just press F1-F6 for different precisions and watch the sprite closely. It will be much easier to see on a CRT of course (which is a big reason I don't like LCD's)
http://www.indiegamer.com/test/timer_test.zip
James C. Smith
05-12-2005, 07:47 AM
Mike, your example just gives me a "memory access violation". :eek: Now I feel dirty. ;)
Mike Boeh
05-12-2005, 08:08 AM
Mike, your example just gives me a "memory access violation". :eek: Now I feel dirty. ;)
Instead of running straight from your browser, try double clicking the icon... EDIT: I just made it a zip to avoid that little problem :)
Jim Buck
05-12-2005, 10:04 AM
I get the access violation too if I double-click from within Winzip. I had to extract and run. But, what a great test! What are each of the timers? It definitely shows "the proof is in the pudding".
Adrian Lopez
05-12-2005, 10:07 AM
What are the timer resolutions for each number? They all seem to jump on my system, some worse than others, but I can't tell whether they're arranged in ascending, descending or random order.
In any case, it seems I was wrong on all counts. I think I see what you meant by the timer being synced with the refresh, because unless the timer's granularity is an exact multiple of the refresh rate, it's going to jump every so often.
Oh well. I always learn the most when I make a fool of myself, so I guess it's all for the best.
soniCron
05-12-2005, 10:10 AM
I always learn the most when I make a fool of myself, so I guess it's all for the best.
You didn't make a fool of yourself! You just didn't understand. I promise that every one of us has made plenty of mistakes just like that one! Some even more embarrasing! So don't worry about it, ok? :)
Adrian Lopez
05-12-2005, 10:40 AM
I'll be fine :D.
On the bright side, my name does appear in the acknowledgments page of the second edition of Real-Time Rendering. It's for alerting them about "very minor" errors... but don't tell anybody, so I can gloat :D.
Mike Boeh
05-12-2005, 12:31 PM
I get the access violation too if I double-click from within Winzip. I had to extract and run. But, what a great test! What are each of the timers? It definitely shows "the proof is in the pudding".
If you hold down the key, it will say on the screen (upper left) what the resolution is.
F1: 1
F2: 2
F3: 4
F4: 8
F5: 14
F6: 20
soniCron
05-12-2005, 12:43 PM
it will say on the screen (upper left) what the resolution is.
Resolution in relation to what? MS? Clock ticks? Screen refreshes?
Adrian Lopez
05-12-2005, 12:44 PM
Ah... I can see it now. I was pressing the number keys instead of the function keys.
wazoo
05-12-2005, 02:20 PM
Hey Retro64, NICE timing demo..
Anyway the source could be posted??
Maybe we can clamour for it to become a sticky, since so many (ok everyone) is affected by timers (good and bad)
Mike Boeh
05-12-2005, 02:26 PM
Resolution in relation to what? MS? Clock ticks? Screen refreshes?
MS
Anyway the source could be posted??
Maybe we can clamour for it to become a sticky, since so many (ok everyone) is affected by timers (good and bad)
Sure, but it's in blitz basic, not c... But blitz has a reliable 1 ms rez timer.
; Refresh rate Independent smooth graphics for Anthony
;
; In a nutshell, this runs at a high frame rate internally, then scales down
; to what ever hz the user happens to be running
;
;
timerPrecision = 1
Graphics 640, 480
SetBuffer BackBuffer()
ClsColor 255,255,255
Ship = LoadImage("flack.png")
MidHandle(Ship)
ShipX# = 300
ShipY# = 300
ShipXSpeed# = .23
ShipYSpeed# = .35
;set a first value for LastTime (it will be used in the main loop)
LastTime = MilliSecs()
LastNumTicks = 1
;start the program loop
While Not KeyHit(1)
Color 0,0,0
Locate 20,20
If KeyDown(59) Then timerPrecision = 1:Print timerPrecision
If KeyDown(60) Then timerPrecision = 2:Print timerPrecision
If KeyDown(61) Then timerPrecision = 4:Print timerPrecision
If KeyDown(62) Then timerPrecision = 8:Print timerPrecision
If KeyDown(63) Then timerPrecision = 14:Print timerPrecision
If KeyDown(64) Then timerPrecision = 20:Print timerPrecision
;get in the time
TmpMS = (MilliSecs()/timerPrecision)*timerPrecision
;little sanity check here in case the timer flips back to 0 :)
If TmpMS < LastTime Then LastTime = TmpMS - LastNumTicks
NumTicks = TmpMS - LastTime
LastTime = TmpMS
;account for when the user alt-tabs :)
If NumTicks > 60 Then NumTicks = LastNumTicks
LastNumTicks = NumTicks
;now we do the logic loop
For i = 1 To NumTicks
;################################################# ################################
;# in here is all the game loop's logic, like collisions, movement, etc
;################################################# ################################
ShipX# = ShipX# + ShipXSpeed#
If ShipX# < 0 Or ShipX# > 640 Then ShipXSpeed# = 0 - ShipXSpeed#
ShipY = ShipY + ShipYSpeed
If ShipY# < 0 Or ShipY# > 480 Then ShipYSpeed# = 0 - ShipYSpeed#
Next
;################################################# ################################
;# here is where you draw all the graphics
;################################################# ################################
Cls
DrawImage(Ship, ShipX#, ShipY#)
;CopyRect 0,0,GraphicsWidth(),GraphicsHeight(),0,0,BackBuffe r(), FrontBuffer()
Flip False
Wend
Adrian Lopez
05-12-2005, 02:34 PM
Maybe we can clamour for it to become a sticky...Please don't. I've been embarassed enough as it is.
Adrian Lopez
05-12-2005, 03:13 PM
Hmm... even with the 1 ms timer I'm getting very jumpy movement on my PC (2.4 GHz P4, Radeon 9500), though admittedly it's not as jumpy as with 14 ms. What's going on?
dxgame
05-12-2005, 05:37 PM
"First off, if you lock the game to vsync you don't need to use a timer."
I would disagree with that perspective due to the fact of varying monitor refresh rates.
"I have never understood how so many people, including game developers, can't perceive what smooth really is."
In my opinion, the only way to get that "smooth" as butter animation is to use Vsync in your application. To render graphics with vsync off, you can end up rendering graphics, ontop of graphics, leads to a shearing effect.
"Here is a little test to show the difference in smoothness with different timer precisions..."
I've seen this code demo before and it never has run smooth for me, including this download. I've played Anthony Flack's Platypus, which I believe uses the same type code, and it (while being a FANTASTIC game) runs choppy. I'm beginning to think it's a Blitz thing? (All of our test pc's use Intel onboard graphics?)
I experienced similar problems and went to a system that averages the time delta over the last 10 frames. While not perfect, it really ended up smoothing out the frame rate while still providing time based movement.
Mike Boeh
05-12-2005, 08:04 PM
I've seen this code demo before and it never has run smooth for me, including this download. I've played Anthony Flack's Platypus, which I believe uses the same type code, and it (while being a FANTASTIC game) runs choppy. I'm beginning to think it's a Blitz thing? (All of our test pc's use Intel onboard graphics?)
Anthony never used this in platypus, it is locked to 60 hz, which is why it's choppy. The little demo I made runs smooth on my pc, but I have never developed a blitz2d game before, so I can't say if it's smooth on all systems.
Powered by vBulletin™ Version 4.1.3 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.