
The last time I looked for something like this I was only able to find horrible implementations. They somewhat worked for the most part, but boy where they ugly. All of them. Well, to tell the truth I gave up pretty quickly. I decided to use a simple 18 lines long version which utilized trace for the output.
And that was fine. However, as I experimented around with Kostas Michalopoulos's Flash mod player I found out that the Debug Standalone Flash Player can be much slower if the bottleneck is on the code-side. It was over 10 times slower. That was a bit of a surprise, given that this kind of thing is free in Java. Of course I wanted to know now how fast my game can actually run in it's current state.
There aren't many calculations right now and there won't be all that many once it's done. Therefore it only runs about 20% faster with a non-debug plugin. But that's still good to know. Now I do at least know that there isn't much of a speed up to expect.
The FPS counter listens to ENTER_FRAME events, because that's the only way to know how many frames are actually displayed. If you render in response to timer events, you may enter that function far more often than new frames are displayed. The enter frame event is the most reliable pulse generator, I'm afraid. Be sure to use the deltas though and cap them in order to avoid warp-through effects and the like.
If you do use deltas and if you also cap them and if the passed time is of any relevance (e.g. a time limit) then use those capped deltas to calculate the elapsed time. The reason for that is rather logical: if the player can move 100 pixels per second and the delta cap is at 30msec (~33fps), but the machine only manages a delta of 40msec (25fps), then the game will slow down by about 25%, which of course means that he'll be only able move up to 75 pixels per second.
If the actual time is used he might not be able to make it - even if he plays perfectly.
Using the FPS counter is easy. Just add it to your Sprite or MovieClip like this:
addChild(new FPSCounter());
In that screenshot above I overwrote the x parameter for placing it on the right side:
addChild(new FPSCounter(13 * 48));
package{
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.utils.getTimer;
public class FPSCounter extends Sprite{
private var last:uint = getTimer();
private var ticks:uint = 0;
private var tf:TextField;
public function FPSCounter(xPos:int=0, yPos:int=0, color:uint=0xffffff, fillBackground:Boolean=false, backgroundColor:uint=0x000000) {
x = xPos;
y = yPos;
tf = new TextField();
tf.textColor = color;
tf.text = "----- fps";
tf.selectable = false;
tf.background = fillBackground;
tf.backgroundColor = backgroundColor;
tf.autoSize = TextFieldAutoSize.LEFT;
addChild(tf);
width = tf.textWidth;
height = tf.textHeight;
addEventListener(Event.ENTER_FRAME, tick);
}
public function tick(evt:Event):void {
ticks++;
var now:uint = getTimer();
var delta:uint = now - last;
if (delta >= 1000) {
//trace(ticks / delta * 1000+" ticks:"+ticks+" delta:"+delta);
var fps:Number = ticks / delta * 1000;
tf.text = fps.toFixed(1) + " fps";
ticks = 0;
last = now;
}
}
}
}If you've seen my texture font article you might have probably wondered what needs to be done to use that for your FPS counter as well. Fortunately it's very easy:
package{
import flash.utils.getTimer;
public class FPSCounter2{
private static var last:uint = getTimer();
private static var ticks:uint = 0;
private static var text:String = "--.- FPS";
public static function update():String {
ticks++;
var now:uint = getTimer();
var delta:uint = now - last;
if (delta >= 1000) {
var fps:Number = ticks / delta * 1000;
text = fps.toFixed(1) + " FPS";
ticks = 0;
last = now;
}
return text;
}
}
}FPSCounter2 returns the FPS string (and it will be correct as long as update is only invoked once per frame) and we can draw it right away:
DText.draw(buffer, FPSCounter2.update(), W - 1, 0, DText.RIGHT);
The result is pretty crispy:

Comments
thanks!
...for sharing your FPS counter, i just needed that =)
Cheers,
Yespunk++;
Yup thanks
Does the trick!
Thanks
Works like a charm :)
Great
works perfect, thanks for posting!
thanks a lot
Your code saved me some time, thanks for that :)
Post new comment