OmegaTimer

Introduction

OmegaTimer provides high-precision timing for your games. It has the following features:

TOmegaTimer Published Properties

Enabled: Boolean When enabled the timer will start calling it's OnTimer() event at the specified interval.
TargetFPS: Integer The number of frames per second you want to 'emulate'. This means that the OnTimer() event will be called this number of times. Defaults to '0', which means OnTimer() will be called as many times as possible.
MinFPS: Integer The number of frames per second you want to have as a minimum elapsed amount of time in between each OnTimer() event. This prevents the timer calling your OnTimer() event handler with an amount of time that is more than you can handle. For example: If you set MinFPS to 50 you are actually saying you don't want your OnTimer() event handler to be called with more than 1/50th of a second in-between. So, if the system is busy and forces your game to have a half second pause before it can call the OnTimer() event again, your game will behave like it was only 1/50th of a second that passed. Imagine what would happen if you did not do this! Then your game would move and update everything like a half second had really passed, possibly moving some of your sprites 'through' walls, for example! Set to 0 to ignore. Default: 10
MaxFPS: Integer The number of frames per second you want to have as a maximum elapsed amount of time in between each OnTimer() event. This prevents the timer calling your OnTimer() event handler more than necessary. For example: You have a very simple menu scene in your game which could render at 1500 fps. This is ofcourse not necessary and, even worse, the Delta property can give such small values that it's not even useable anymore! So you stick to, say, 120 fps maximum (most monitors can't refresh better than that anyway!), and you give Windows and some other threads more time to execute properly. Set to 0 to ignore. Default: 120
FPSWarningFrames: Integer The number of frames that did not reach the MinFPS setting after each other before the FPSWarning property is set to True. For example, if you have MinFPS set to 10 and at least 10 frames in a row dropped out of this setting, FPSWarning will be set to true. Default: 10

TOmegaTimer Public Properties

Delta: Double Can be read in the OnTimer event handler. If TargetFPS > 0 this represents the number of target frames that have passed since the last call (it is always possible a computer is too slow, in which case this value van be >1, but this can be controlled with the MinFPS property also!). If TargetFPS = 0 this represents the number of seconds that have passed since the last call.
DeltaSecs: Double Can be read in the OnTimer event handler. Regardless of TargetFPS, this represents the number of seconds that have passed since the last call. Always.
FPS: Integer The current frames-per-second. This actually means the number of times the OnTimer event handler has been called, ofcourse. The FPS is not weighted or anything since this is just for indication of the FPS and should not take too much CPU time to process this way.
FPSWarning: Boolean This Boolean is set to True when the computer did not reach the MinFPS settings a number of frames in a row, as set in the FPSWarningFrames property. It will be set to False again as soon as a frame meets the MinFPS setting again. Note that this property will never be set to True if MinFPS is 0, ofcourse.

TOmegaTimer Events

OnTimer: TNotifyEvent This event handler is called by the timer when the specified amount of time according to TargetFPS and MaxFPS is reached.

TOmegaTimer Examples

Using TargetFPS > 0: Your OnTimer event handler could look like this to have a sprite move 2 pixels per frame, regardless of the actually called frames per second, where OmegaTimer is the instance of TOmegaTimer calling this event handler:

MySprite.x := MySprite.x + OmegaTimer.Delta * 2;

Or, to be framerate indepenant, you could use this to have your sprite move 30 pixels a second so you can always change the TargetFPS to whatever you like:

MySprite.x := MySprite.x + OmegaTimer.DeltaSecs * 2;

Using TargetFPS = 0: Your OnTimer event handler could look like this to have a sprite move 30 pixels per second, regardless of the actually called frames per second, here OmegaTimer is the instance of TOmegaTimer calling this event handler:

MySprite.x := MySprite.x + OmegaTimer.Delta * 30;

Or, exactly the same:

MySprite.x := MySprite.x + OmegaTimer.DeltaSecs * 30;

About MinFPS and MaxFPS and FPSWarning

I understand this is a bit tricky to understand at first, so I would suggest leaving these at their default values for a while. But let me try to explain in more detail. Say, you have a maze-game with blocks of 16x16 pixels and you want your main player sprite, which is 16x16 pixels also, to move exactly 16 pixels per second. This means, that if you want to update your main player sprite position each OnTimer() event handler and also check whether it collided with any blocks of the maze, you'll never want your sprite to move more than 32 pixels at a time! (Otherwise it could 'jump over' a maze block, right?)

So, literally taken, this means you never want to loose 2 seconds of game-logic time, in other words: You want your FPS to be a minimum of 0.5 to make it playable so that your sprite will never move more than 32 pixels at a time. So you set your MinFPS to 1 since that is the minimum you can specify.

Also, since your movement requires you to calculate with the DeltaSecs or Delta property, you don't want it to be too small to prevent rounding errors. In other words: You want a maximum of, say, 100 frames per second since more would not be useful for a simple game like this. So you set your MaxFPS to 100.

Now, you also want to know when the computer is not capable of at least reaching your MinFPS setting, since this could mean that the user is getting an advantage because the game runs slower on their system. So each frame you check the FPSWarning property of the timer. If it is True you quit the game, for example, with a warning to the user that their system is not capable of properly running your very-time-dependant game.

Back to the Index