Quantcast
The World Famous 8bitrocket.com Home Page



Tutorial : Creating an Optimized AS3 Game Timer Loop
4/8/2008 12:00:00 AM by: Jeff Fulton
Category: Tutorials, Series:AS3 Asteroids , Syndication:(XML/RSS)

Blogs In This Series


Blogs In This Category


Last 10 Blogs

utorial : Creating an Optimized AS3 Game Timer Loop

It this tutorial we create what I consider to be my most optimized game timer loop. I will start with the game loop created in my last tutorial and optimize it further. We will add three different optimizations to the game loop. First, we will simply lock our canvas before we use the copyPixels operation on it. Then we will unlock it after. Second, we will implement a sleep based active render timer. Third, we will make sure our game loop updates on every event rather than on every frame.

One of the most discussed, least understood and ultimately most frustrating aspects of Flash game programming is keeping a constant frame rate across all of the different SWF players. We seem to get a different frame rate inside of the IDE, in the stand alone player, and in different browser / wmode combinations.

Normally, the theory is to keep your game running at about 30 FPS for smooth game play. So, what most of us do is set our Flash Movie frame rate at 30 FPS or more and hope for the best. If we are lucky enough to either create a game engine that doesn't tax the Flash player, or are skilled enough to create an optimized engine, we will get a pretty constant frame rate in the Flash environment. When we export the game and try it in the external player, we might also get pretty close to 30 FPS. We are really happy, and then we try the game in a browser. Usually this is where the trouble starts In an IE browser with wmode set to the default (Window), we will usually see a 2-5 frame rate drop. If any other browser, especially Firefox, our frame rate can vary wildly downward from there. Now, the latest Firefox update might repair this, but there seems to always be a situation where the frame rate outside of the Flash IDE (and sometimes inside of it) will just not be what you expect.

One other common problem with game timer loops is the game engine taxing the processor in such a way that it causes the game to drop frames and at the same time drop update and render cycles. This results in a slowdown in game play because the rendering engine cannot keep up with demand. Nothing is going to keep a game playing smoothly on a very old machine, but within reason, we should be able to keep our game running pretty smoothly at our desired frame rate. How can we do this?

1. BitmapData.lock and BitmapData.unlock.
The simple theory behind locking a BitmapData object is to stop display objects that reference it from updating themselves (a very costly operation) when the BitmapData object is being rendered with multiple copyPixels operations. When unlock() is called, all of the changes are then reflected in the display object.
In practice, it would look like the following. We are going to take the game loop from my 7800 Asteroids game out of context here, but it is being used just for demonstration purposes.


    checkKeys();
    updatePlayer();
    updateRocks();
    updateMissiles();
    checkCollisions();
    canvasBD.lock();
    drawBackground();
    drawPlayer();
    drawRocks();
    drawMissiles();
    drawParts();
    canvasBD.unlock();

The above is a simple demonstration of the 7800 Asteroids game loop. Before any of the draw operations, we lock the canvasBD, which is our single display canvas for our game. All of the drawXXX() functions use copyPixel operations to BLIT to this canvas. By locking it, we stop the canvasBitmap display object (not in code above) from being updated until the canvasBD.unlock() is called. This helps to not use as much CPU during the copyPixel operations and is effectively a poor man's doublebuffer operation without the double buffer overhead of having to copyPixels twice - once to the buffer and once to the display object.

2. The Sleep Based Timer using Active Rendering
The sleep based timer is definitely not my unique creation, and the code we will use isn't even my implementation. A fellow Flash Game Head , and friend of mine, Chris Cutler, takes the credit for introducing me to this AS3 implementation of Andrew Davidson's Java based version. Chris created the AS3 version based on Andrew's excellent book, Killer Game Programming in Java. I don't know Andrew, but his book is quite excellent and a great game development reference especially for AS3 programmers.

Andrew introduces a sleep based timer to actually slow down his code so it will run the same on all machines. In Flash we sometimes need to do this, but more regularly, we need to keep we struggle to keep our frame rate constant across platforms. He times the number of milliseconds it takes his game loop to run, and if he has time left over, he sleeps (or pauses) the loop until the next interation. This makes for a smooth loop. He adds to this technique to what he deems, Active Rendering. What he does is actually measure the time it takes to render the screen, and then make adjustments to his sleep timer based on these measurements. In this way, he has ultimate control over his game loop. By implementing this is AS3, so do we. Below is this code added to our game loop:

 

    
private function runGame(e:TimerEvent) {
    _beforeTime = getTimer();
    _overSleepTime = (_beforeTime - _afterTime) - _sleepTime;


    checkKeys();
    updatePlayer();
    updateRocks();
    updateMissiles();
    checkCollisions();
    canvasBD.lock();
    drawBackground();
    drawPlayer();
    drawRocks();
    drawMissiles();
    drawParts();
    canvasBD.unlock();
    
    _afterTime = getTimer();
    _timeDiff = _afterTime - _beforeTime;
    _sleepTime = (_period - _timeDiff) - _overSleepTime;        
    if (_sleepTime <= 0) {
        _excess -= _sleepTime
        _sleepTime = 2;
    }        
    gameTimer.reset();
    gameTimer.delay = _sleepTime;
    gameTimer.start();

    while (_excess > _period) {
        checkKeys();
        updatePlayer();
        updateRocks();
        updateMissiles();
        checkCollisions();
        _excess -= _period;
    }
    
    frameTimer.countFrames();
    frameTimer.render();
    if (aRock.length ==0 && aActiveParticle.length==0) stopRunningGame();
    
}

In our Variable Definition Section, we have added these variables:

    public static const FRAME_RATE:int = 40;
    private var _period:Number = 1000 / FRAME_RATE;
    private var _beforeTime:int = 0;
    private var _afterTime:int = 0;
    private var _timeDiff:int = 0;
    private var _sleepTime:int = 0;
    private var _overSleepTime:int = 0;
    private var _excess:int = 0;

FRAME_RATE is set to be the number of updates we want per second. I like 40, so I have set mine to that.

_period is the number of milliseconds that we have to perform all of the operations per period.
In this case it is 25 (1000/40)

_beforeTime and _afterTime will create a simple code profiler.
We time all of the operations in our loop and see how long it too in milliseconds..
We hope for it to take less than 25 milliseconds (or _period value).

_timeDiff is the difference between the _afterTime and the _beforeTime.

_sleepTime is the period (25) minus the _timeDiff.
From both of these we subtract our _overSleepTime.

_overSleepTime is a measure of how accurate or sleepTime is on the last interval.
If the sleep time was off by a couple milliseconds, they will be added to the overSleep
for the next interval.

_excess holds all of the excess time that occurs in the render loop.
It is a running total in a way and it keeps the whole loop honest.
When the _excess is greater than our period (25) then we do an extra checkeys(), update(), and check collisions() of our objects.
We don't render them though.

What this code produces is a game loop that looks like it is rendering at the same speed even though in some cases the processor cannot keep up with the load. In that case, we update without rendering to keep objects moving at a constant rate. In the next render() the objects will appear at the new locations.

We have also mode a change to our gameTimer variable to make this work:


    gameTimer=new Timer(_period,1); //changed in part 3 from 50
    gameTimer.addEventListener(TimerEvent.TIMER, runGame);
    gameTimer.start();

Our gameTimer variable used to be created with just the number of milliseconds to update on each interval. This would make it run constantly until we called gameTimer.stop(). That's not the case any more. We just run our gameTimer one time, then check the value produced (above) and the restart of loop after sleep is necessary. The number of milliseconds to repeat our interval is now to our _period (25), for this first one time run. We do this because our new method of timing will reset and start the timer inside the game loop - like this:

gameTimer.reset();
gameTimer.delay = _sleepTime;
gameTimer.start();

This starts up our gameTimer only after sleeping for the appropriate amount of time.

3. UpdateAfterEvent()
The third and final optimization we will add to this timer will be the use of the event.updateAfterEvent() method.
After taking a look at Keith Peter's latest book on AS3, Actionscript 3.0 Animation (it should be on every Flash Game Developer's book shelf, right next to the collective works of Colin Moock and Jobe Makar) I found this little tid bit.

By calling the event.updateAfterEvent() method of the TimerEvent object, we force Flash to update the screen immediately. In this way, we can set our movie Frame Rate to a relatively low number. I like 40. So, usually I would have set my FrameRate to 60 in hope that I would ge 35-40 in my browser. The result of this actually taxes the processor more because it is always trying to keep up with the 60 intervals per second. Now, with it set to 30, I can get the 40 updates a second I want and it will look smooth in all current browsers.

What do you do if the designer has created all of his animations set to 18 FPS, but the game needs to run at 30? Before now, I would have had to be very clever to handle this. Now, I can just set the movie to 18FPS and the FRAME_RATE (above) to 30. This will let you display animations at 18FPS, but game play can run at 30 updates a second.

Here is the game loop with this code added:


private function runGame(e:TimerEvent) {
    _beforeTime = getTimer();
    _overSleepTime = (_beforeTime - _afterTime) - _sleepTime;


    checkKeys();
    updatePlayer();
    updateRocks();
    updateMissiles();
    checkCollisions();
    canvasBD.lock();
    drawBackground();
    drawPlayer();
    drawRocks();
    drawMissiles();
    drawParts();
    canvasBD.unlock();
    
    _afterTime = getTimer();
    _timeDiff = _afterTime - _beforeTime;
    _sleepTime = (_period - _timeDiff) - _overSleepTime;        
    if (_sleepTime <= 0) {
        _excess -= _sleepTime
        _sleepTime = 2;
    }        
    gameTimer.reset();
    gameTimer.delay = _sleepTime;
    gameTimer.start();

    while (_excess > _period) {
        checkKeys();
        updatePlayer();
        updateRocks();
        updateMissiles();
        checkCollisions();
        _excess -= _period;
    }
    
    frameTimer.countFrames();
    frameTimer.render();
    if (aRock.length ==0 && aActiveParticle.length==0) stopRunningGame();
    e.updateAfterEvent();
}

Here is the 7800 Asteroids game Running with this new game loop code. This has a movie frame rate set to 30FPS, and in the IDE, external player and browser, it runs at a pretty constant 40-42 FPS.

 

Here is the 7800 Asteroids game Running with the older, non optimized game loop code. This has a movie frame rate set to 50 FPS, and the IDE, external player and browser, the frame rate wildly differs. The game loop is set to run every 15 milliseconds I can get 50-60 FPS in the external player and IDE (sometimes) but it drops to 30-35 when a lot of particles on the screen. In the browser (at least for me) it doesn't get above 35FPS.

 

Here You can download the .fla and new class files for your own use.



GamerBlips: vote it up!

Comments
ColbyCheeze: 4/9/2008 1:27:39 AM
Wonderful! Thank you. I'm getting the book right now. Great game loop, I'm going to put that into my game.
Squize: 4/9/2008 9:30:44 AM
Great tut. mate, I was looking forward to this. There are lots of things there for me to steal and pass off as my own )
Jeff: 4/9/2008 10:02:25 AM
Thanks, Colby! It's great to have you wondering around our site!
ColbyCheeze: 4/9/2008 10:57:48 AM
Unless I'm horrible at finding things, I think that you might have left out the "new" game loop in the source files you included. All I can see is the "new" swf and the "old" source files. I got the code I needed from the tutorial part, but figured I'd let you know so others wouldn't get confused if they downloaded it. Keep up the good work!
Jim: 4/9/2008 12:24:27 PM
Great article. There was a similar discussion on the kongregate boards here: http://www.kongregate.com/forums/4/topics/1773
Jim: 4/9/2008 12:25:15 PM
Great article. There was a similar discussion on the kongregate boards here: http://www.kongregate.com/forums/4/topics/1773
Jim: 4/9/2008 12:26:50 PM
Sorry for double post :O Anyways, In my current project I'm using the enterframe event and sending the deltaTime between frame updates to my objects that need to move. It works really well, I set the movie to 120 fps and it runs as smooth as possible while maintaining the same gameplay experience for all players. The downside to this technique is you have to be careful with collisions, if your delta is too high stuff will jump over each other between updates.
Jeff: 4/9/2008 1:30:30 PM
Colby, I'll fix the .zip file right now. Sorry about that. It was a late night. Jim, I like the distance based movement timers too. I will test one of those next and write about it.
Jeff: 4/9/2008 1:34:22 PM
The new zip file is up. It has the correct main.as for the new timer as well as the old moldy code just in case anyone is interested!
Felixters: 4/10/2008 1:59:00 PM
Nice tutorial! One question though. I noticed all of your graphics are being drawn directly to the screen. If you wanted to make your player ship subclass the Sprite object (so it could have, lets say, mouse event support), how would that fit into the mix? At that point, all you're doing is an addchild(SpriteObject) to the stage and a graphics update on every frame wouldn't fit anymore since it's handled by the stage (Am I missing something). Does that make any sense?
Jeff: 4/10/2008 3:59:36 PM
Just add the ship to the display list after the canvas and make sure to update it after you update the other objects. if the ship has bitmapData, you can use it for collisions if you are into that. The sprite would still get mouse events. I would only respond to the mouse events as part of the gameLoop (like the getKeys) that way you wouldn't get out of sync.
Rick: 4/11/2008 8:01:48 AM
ops, typed in the wrong email :) Thanks for the reply as well, just one other question then. Lets say I didn't always want the player to be on top of all other graphics. Perhaps I want some of the boulders to overlap the player? (Doesn't make sense in this game, but would in others). How would this work? My thought would be to have two canvas bitmaps that are added around the Sprite object. Then I would have to manage which boulders are drawn to which canvas. I can see this sol
Jeff: 4/11/2008 11:13:37 AM
You can have as many canvas' as you want layers (up to the processor giving out). That way you can mix the different rendering types. Just make sure to render them all in order or the final canvas will wipe out the screen (if it isn't transparent that is).
Nate: 4/13/2008 4:54:59 AM
Fantastic post Jeff! I will be testing this out later today and probably putting it into my latest game. I will let you know how it goes. :-)
Megan Fox: 5/27/2008 2:28:10 PM
hile the loop code does maintain a very consistent FPS, what I've noticed is that it appears to do so at the cost of input lag. If my scene gets particularly dense, for instance, I can maintain a near perfect FPS - but Flash starts losing mouse events. All my input is tied to the mouse, and suddenly I can't jump, or it completely forgets where my mouse was positioned, or whatever else. Is there any way to convince the mouse input events to keep updating within the inner catch-up loop?
Jeff: 5/27/2008 7:32:25 PM
Megan (you were extra hot in Transformers BTW) I have not tried that yet. You might try to make sure that you are not excluding the mouse listener check when the loop goes inside the while (_excess > _period) code.
Megan Fox: 5/29/2008 9:03:48 AM
Sorry, not the actress Megan Fox, I'm the programmer one (http://www.shalinor.com). I'm checking against the mouse input, my standard UpdateInput() function (you call yours checkKeys()), but as far as I know I can't force the listeners themselves to update?
Jeff: 5/29/2008 5:16:58 PM
Darn =) I know you're not her, I was just kidding around. Hmm, maybe you can send me your code to info[at]8bitrocket[dot]com and I will take a look? -Jeff
ptdgames: 6/20/2008 11:13:48 AM
I have the best luck using a timer set to 1 milisecond. Every tick, it calls my main game loop. With most types of games I can get 200-300 FPS at 600x400 pixels. Any objects that need to move around the screen have their own checks to see how much time has passed, etc. and then they can tell how far to move. Also, to avoid spamming the CPU, most things (let's say an Orc) are told to move every 20ms or so. If it's 25, they move a little farther this update.
Jeff: 6/20/2008 3:55:36 PM
pdtgames! Thanks for the great ideas. I thought about adding those in too and probably will in a follow-up version.
Ollie Glass: 6/21/2008 1:46:17 PM
Brilliant tutorial, thanks! Have you read Colin Moock's chapter on screen updates and using Event.RENDER in Essential Actionscript 3.0? Do you think it would make your timer loop even more efficient?
Jeff Fulton: 6/22/2008 12:50:11 AM
Hey Ollie, I have that book right here. I'll take a look and see what old Colin has to say. Somehow I missed that one.
david doull: 7/27/2008 1:33:15 AM
thanks for this article - great work, really appreciate it.
Jeff: 7/27/2008 12:45:45 PM
David, if you make a game with it, let us know. I'd love to hear how it went, explore any problems you find, and see your successes. Plus, we'll high light your game if you do. That goes for anyone. if you make use of one of our tutorials, sound loops, engines, etc, tell au about it. We'll write up an article on your game and feature it on the site in some way.
Nick: 8/4/2008 1:11:12 PM
But it seems that nearly all browsers are trying to limit the max framerate of the Flash plugin..... http://www.tekool.net/blog/2008/05/27/overriding-flash-player-60fps-limit-in-firefox-up-to-950fps-as-silverlight-2-in-bubblemark/
spir: 10/9/2008 7:33:43 AM
I have noticed something interesting, i get a higher frame rate with the older game loop, not only in my own experiments but also in the two examples above, im using Google Chrome to view these. im averaging out about 40 - 42 fps in the optimised loop and 52 - 57 in the old un-optimised loop. its playing through flash player 10 with hardware graphics turned on, i have a geforce7900 gs and a 2ghz dual core.
Jeff: 10/9/2008 12:27:28 PM
The above optimized one is set to fun at 40 MAX. You can change to run higher. The older ones were set to 60.
MrBob: 1/4/2009 6:18:34 AM
Hi there.  Awesome website, I've found it very helpful in getting started with Flex + AS3 + Flashdevelop.  This timer tutorial works great in the standalone player and Firefox on my machine.  However, in IE8 it will fail to run correctly (pauses, fails to update the screen and close to locks the entire browser) when the IE8 window is maximized.  It does this in my game, but the sample application fails to show anything other than a grey-ish screen.  From my inexperienced-in-flex/flash perspective it appears the application is hogging event updates.

The flash player I am using is version 9 (9,0,124,0) from the Flex SDK.  Any ideas as to what could be causing this?
MrBob: 1/4/2009 6:25:43 AM
Hi there.  Awesome website, I've found it very helpful in getting started with Flex + AS3 + Flashdevelop.  This timer tutorial works great in the standalone player and Firefox on my machine.  However, in IE8 it will fail to run correctly (pauses, fails to update the screen and close to locks the entire browser) when the IE8 window is maximized.  It does this in my game, but the sample application fails to show anything other than a grey-ish screen.  From my inexperienced-in-flex/flash perspective it appears the application is hogging event updates.

The flash player I am using is version 9 (9,0,124,0) from the Flex SDK.  Any ideas as to what could be causing this?
Jeff: 1/8/2009 11:32:31 AM
Mr. BOB - Try to turn off the e.updateAfterEvent - that is what is probably hogging the updates. (just comment it out).
Chris Keegan: 2/4/2009 5:54:34 PM
Hi!

@Jeff: Any idea why this e.updateAfterEvent behaves this way or if there is a better solution than to just comment it out?

Chris...
Jeff: 2/4/2009 6:57:30 PM
Hey Chgris,
We are currently convinced that the AS3 virtual machine for the stand alone and in IDE players doesn't has a bug. It could be that we are pushing the limits of the player with this timing structure, but it seems to work fine in-browser (well, Squize has seen a few people on slower machines get hiccups in his latest game).  I could be wrong though. the updateAfterEvent keeps everything ruinning very smooth, so I always keep it in, but when exporting in the ide for testing I comment it out. So far I have not found any browsers that have had any problems, but I have not done an exhaustive search. I have tried Firefox and Safari on the Mac, and IE abd Firefox on the PC.
Chris Keegan: 2/5/2009 5:26:41 AM
Hi Jeff,

Thanks for the update, I think you're right that there's a bug in the VM and also that we're pushing the limits of the performace of the timing systems. For 60fps we're looking at 16ms updates, then when you remove the actual update times you're probably looking at maybe 10-14ms. I imagine this is right on the limits of what's possiblewith Flash - problem is that flash is limited depending on architecture so what works on PC doesn't necessarily work on a mac and god help you if you run linux!

We recently shipped a game that was targetted at the main european  territories (EFIGS) and we got enough instances of lock-ups in-browser to force us to disable updateAfterEvent in our main loop so I think that the problem isn't limited to the standalone players. Our experience is that while the game keeps rendering correctly in most cases on low-end machines (as per Squize's experience) you get loss of input and ultimately lock-up.

Sadly because we need our games to hit the mass-market we have to support pretty low-spec machines (which I currently make my old 800MHz Vaio laptop running ubuntu) on a wide variety of platforms.

Chris...
Jeff: 2/5/2009 10:53:38 AM

I don't see the disabling of updateAfterEvent being a HUGE problem, but it does make the display a little less smooth. There are really 3 elements to this timer loop: <br>

1. The Active renderer and sleep that helps settle the display and allow for garbage collections, etc.
2. The Double Buffering" by locking the bitmapdata canvas before the render and unlocking after
3. The updateAfterEvent

<br>

All 3 together create the smoothest Flash motion I have ever worked with and all help to keep a constant framerate between different platforms. Removing the update after event or even not having the bitmapdata.lock (if you are not using bitmapdata) doesn't kill this rendering scheme, it just makes it a little less smooth. The Active rendering is what is really keeping the constant framerate.

Squize: 2/5/2009 1:12:37 PM
Just to join back into the conversation here, I'm busy looking at the loop during my brief not working on other things moments.

I've dropped the updateAfterEvent() but you lose _a lot_ of smoothness with that, so on my machine where everything always worked well, it's no longer smooth. Not good.

One thing my game does ( Or doesn't ) is that the rendering isn't separated from the logic, so say a particle instance has a copyPixel call in it. I use lock(), but it's got to have some sort of overhead calling a copyPixel x number of times even if it doesn't actually alter the pixels til the canvas is unlocked().

So now I'm thinking of some kind of "render farm" approach, where every request to plot something is stored away and then just looped through in one hit.
Off the top of my head this will mean some sort of hash for each object in the game so it overwrites any of it's own requests.
I'm unsure about this though, as it's a ton of work for something which may not make a difference for a bug I can't replicate on my machine anyway.
Jeff: 2/5/2009 6:55:28 PM
Hey Squize!

I am designing my generalized Flex game engine to combat that lock and unlock problem with bitmapData. I'll keep you in the loop.  I still think this active render loop works fine, but it on older and some strangely configured machines is has some problems. Those machines would probably have problems with these games anyway though. The active render loop leaves time for garbage collection (one of its main uses in java) so you don't have on e HUGE hiccup and garbage collect at once. It seems to help in Flash the same way. Without that, some of these machines that don't work with it would have even more problems because there would be an escalating memory footprint that would hiccup the game right as it is being collected.
Chris Keegan: 2/7/2009 6:18:30 AM
Hi Guys,

I've been playing around with this a bit over the last couple of days and evolved the framerate smoothing a bit. I was troubled by the fact that on a given frame the granularity of the timer being only one millisecond is nowhere near accurate enough. So I sample over a period of a second, which gives me a much better idea of how long my code is taking to execute. Since we know that Flash starts the timer again at the end of the execution of the event handler it's pretty accurate to say that any time over 1 second is unavoidable overhead and simulation, I just subtract that from the timer.delay value and voila - seems pretty robust. I think it will also be possible to dynamically adjust framerate depending upon performance using the same timing technique and thus avoid the case where overloading the system causes. (if the overhead/simulation is too big compared to your expected time-per-frame then just double the time per frame, you lose fidelity but at least it's not dead, right?)

My engine fully decouples the rendering and the simulation via a scheduling system, motion controller and scene graph. This means that the above "just works" as the simulation doesn't actually care what the framerate is. (actually the motion controller is pretty great even though I do say so myself =) trhe simulation sets linear and angular velocities and the rendering pipeline gets the precise position and orientation at render time by lerping equals very, very smooth motion.

Chris...
Chris Keegan: 2/7/2009 6:31:30 AM
@Squize

For what it's worth, it's definitely a bug that will affect you if you want your games to target that maximum possible audience, we've had pretty comprehensive test feedback confirming that updateAfterEvent is a killer.

Also, decoupling rendering from simulation is a fair bit of effort but without doubt it is worth it. The flexibility it affords is highly beneficial in the long run.

@Jeff

Speaking about flex, what's your mileage been on building games with it? I've been able to import swf files well enough, but wholesale exporting of symbols has so far eluded me in a scalable way. I really cannot stad writing code in the Flash IDE but building our whole games in Flex just hasn't seemed possible because of the symbol importing hassles (ie it's possible - I think! -but painful)

Chris...
Jeff: 2/7/2009 12:36:56 PM
Chris, I'd love to see that updated code and add it to this post and or my engine (if you are willing to share).  On the Flex front - I have not yet used it for games that need a huge number of imported swfs. My engine has been built around using PNGs and bitmap based animation. I can see  the potential (especially with Flash develop) for long waits when importing swfs at compile time. I don't know if Flex pro is any better.
Chris Keegan: 2/7/2009 1:48:28 PM
Hey Jeff,

Happy to share. I'm off for the evening now but I'll post tomorrow if I get the chance to make it presentable.

I've just spent the day building a predictive collision system, very nice. Hooks into velocity changes, predicts the earliest possible collision and sleeps until then. I love the accuracy and the cheapness, the only downside is the quadratic math but that's not so bad.

Chris...
Lummox: 2/8/2009 8:30:34 AM
@Chris: Just wanted to encourage you to post your solution (pretty please!) would really love to see it. @Jeff: Love the site / blog. Great stuff. Found it a couple months back, and it's been a terrific resource. So thanks for that! Was recently trying to create an improved update method for my own engine which is a sad, choppy mess and so am clearly enamored with this concept of locking / unlocking the canvas drawing calls. Can't wait to give it a try.
Chris Keegan: 2/8/2009 12:30:00 PM
Hi All,

Today's got away from me, I'm afraid. I'm been in the world of swept-sphere collision detection. Got the bulk of the problem solved but no time left for posting the smoothing.

Will do it as soon as I've got the collision detection code sorted.

Chris...
Jeff: 2/8/2009 2:21:45 PM
Chris, no problem. When you have a chance, let us take a look!!

Lummox! Great to see you on the site and I'm glad our little corner of the infobaun has been a help to you.
Chris Keegan: 2/12/2009 2:32:14 PM
Hey Jeff,

I've got some code that's does a pretty decent job at managing framerate smoothing and degradation. It ended up needing a bit more work to get the heuristics right (I say right but I'm not totally happy with it). It's a fair amount of code so I'd question the helpfulness of just sticking it into a comment - purely from a formatting point of view.

I'm happy to email it to you and then you can do with it as you will. Just drop me a line to nospa m at th eisolationist do t  com with your email address and I'll send it on through.

Chris...


P.Svilans: 4/18/2009 3:26:02 PM
That's a very nice game timer loop, and it seems to give an incredible speed boost to any game!
I was just needing to know if I can include a class or a couple classes that are clones of this timer loop in a Flash library I'm making that will have lots of basic and some not-so-basic classes to make game development a lot faster. I hate engines/frameworks that are premade, so I thought making a low level library could benefit even the experienced developers...

Thanks for this tutorial!

P.
Jeff: 4/18/2009 10:36:50 PM
Hey P.Svilans,

You sure can include it if you want to.  I'd love to see / use that library when it is complete. If you want to give some credit back, I would appreciate it, but it is not mandatory.
Bart Burkhardt: 5/10/2009 4:45:12 PM
Hi, thanks for your article. I'm wokring on a news ticker, and altough I have created some corrections on the drawing of the x coordinates, it is still stuttering sometime. I have read this article, but must admit that I do not understand all of it, Can you show me your correction frame rate code in a simple example that shows something scrolling at a constant speed? Thanks, Bart
Andrej Vojtas: 5/19/2009 8:44:15 AM
Great site and great insight! Thank you for posting this.

I would like to ask about the topics mentioned in the comments:

Is there any follow up to this article with the Chris Keegan code?
And what about the : Colin Moock's Event.RENDER in Essential Actionscript 3.0?
David: 7/1/2009 12:45:33 PM
I too am curious about these other possible methods. Any updates? :-)
Yvan Cartwright: 8/24/2009 10:16:32 AM
Hi Jeff,

I made a version of Andrew Davidson's active renderer for a PSPLua engine and it worked well. I'm now trying to create a 3D engine in Flash using Away3D but I'm having trouble getting the Active Renderer to work properly with it. It looks like I may be having the same problem as Megan Fox (the programmer not the actress) did above. Everything works fine and the rendering appears smoother but it looks like the key and mouse listeners don't receive events beyond first being called. This ends up with the previous mouse/key combinations being repeatedly used. Any ideas what might be causing this?

Thanks in advance!
8bitjeff: 8/24/2009 11:33:41 AM
Hi Andrew.

 I have a new version of the render and a new game loop that might work better. I can't release it yet, but if you send me an email to info[at]8bitrocket[dot]com, I will check out your code and see if there is anything obvious, and share with you the in-progress version of  the code.
moly: 9/21/2009 5:31:24 PM
Can you release the new version yet?
Quakeboy: 9/26/2009 7:30:33 AM
Thanks for the updateAfterEvent tip. I was able to remove tearing complete and play the game graphics @ 160 FPS in browser with movie FPS set to 30 only :)

I have provided the source code also which is a port of andre-michelle's AS 2.0 code.
http://qdevarena.blogspot.com/2009/09/andre-michelles-tile-based-scrolling.html
Paul: 11/5/2009 1:43:00 PM
I didn't realise why this worked so well until I read that Flash slices time independently of frame rate. So much they hide from us oO
8bitjeff: 11/5/2009 7:55:18 PM
There is a problem with the updateAfterEvent and the new plug-in (just released) windows XP. It works fine in the Mac and Windows 7, but XP is a HUGE problem. I am trying to find a work-around because this timer works very well with it, but just adequate without it.
YopSolo: 1/30/2010 11:24:57 AM
I have noticed a memory leak (with System.totalMemory), but i can''t find the origin of the leak.


Add Your Own Comments
Message
Name:
Email:


This will not be displayed. It is used for a email one-time validation only.
Note: You MUST Respond To The Verification Email The First Time To Have These And all future Comments Displayed!
Validation Text:
Please type in validation text from the graphic.
Comment:

Max: 2500 Characters characters left


Questions? Comments?
For more information, contact: info@8bitrocket.com