Topic: Game Programming /
[AS3] Can my framerate be better?
I’m building a game that lets you connect to facebook then drops thumbnail images of your friends (50×50) from the top of the stage. It’s a bit choppy at 30fps and it really seems like it should be able to run smoothly just having a few small bitmaps moving. Below is a link to view it, and a list of things I’ve tried followed by my class. Any suggestions would be greatly appreciated. I really hope this isn’t the best I can do until molehill gpu support is available in a public flash player release. Thank you!
http://friendsonfire.brownbearstudios.com/test
1. Like I said above, I realize that using molehill gpu acceleration should fix my problem, but that’s not an option for end users yet.
2. Using tweenlite instead of enterframe to animate the bitmaps produced slightly poorer results.
3. Combining my enterframe listeners that I currently add to each object then remove when they leave the screen into one listener that loops through each object also produced poorer results.
4. The “friend” object is just a movieclip with a loader inside, and making these a sprite and loader created from actionscript didn’t provide better results.
I’m on a mac with the most recent version of osx. It runs about the same in chrome, safari and firefox3… a little choppy. I have to mention a new headache came when I upgraded to firefox4… for some reason it performs much worse than any other browser including firefox3.
Here’s the class:
package {
import com.facebook.graph.Facebook;
import fl.controls.ProgressBarMode;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.system.Capabilities;
import flash.utils.Timer;
public class FriendsOnFire extends Sprite {
protected static const APP_ID:String = "[deleted]";
protected var dropperSpeed:int = 5;
protected var dropperChangeThresh:Number = .03;
protected var friendSpeed:int = dropperSpeed;
protected var friendDelay:Number = 1000;
protected var friendDelayGap:Number = 2;
protected var needToCatch:int = 20;
protected var speedInc:int = 2;
protected var stageW:int = 800;
protected var stageH:int = 480;
protected var level:int = 1;
protected var friendCount:int = 0;
protected var numCaught:int = 0;
protected var numLoaded:int = 0;
protected var xPos:int = 0;
protected var friends:Array = [];
protected var friendsList:Array = [];
protected var isMobile:Boolean = false;
protected var timer:Timer = new Timer(friendDelay, 0);
public function FriendsOnFire() {
configUI();
}
protected function configUI():void {
var device:String = Capabilities.version.slice(0, 3);
if (device != "LIN" && device != "MAC" && device != "WIN") {
isMobile = true;
}
var accessToken:String;
if (loaderInfo.parameters.accessToken != undefined) {
accessToken = String(loaderInfo.parameters.accessToken);
}
info.text = "Checking Facebook Connection...";
connectBtn.visible = false;
connectBtn.addEventListener(MouseEvent.CLICK, onConnectBtnClick);
Facebook.init(APP_ID, onInit, null, accessToken);
}
protected function onInit(success:Object, fail:Object):void {
if (success) {
loadFriends();
} else {
showConnectBtn();
}
}
protected function showConnectBtn():void {
info.text = "";
pbarHolder.pbar.visible = false;
connectBtn.visible = true;
}
protected function onConnectBtnClick(e:MouseEvent):void {
connectBtn.visible = false;
pbarHolder.pbar.visible = true;
info.text = "Connecting...";
if (isMobile) {
Facebook.mobileLogin("http://friendsonfire.brownbearstudios.com/");
} else {
Facebook.login(onInit);
}
}
protected function loadFriends():void {
info.text = "Loading Friends...";
Facebook.api('/me/friends', onFriendsLoad);
}
protected function onFriendsLoad(success:Object, fail:Object):void {
friendsList = success as Array;
pbarHolder.pbar.mode = ProgressBarMode.MANUAL;
var count:int = friendsList.length;
for (var i:int = 0; i < count; i++) {
var f:friend = new friend();
friends.push(f);
f.loader.addEventListener(Event.COMPLETE, onImageLoad);
f.loader.source = Facebook.getImageUrl(friendsList[i].id,'square');
}
}
protected function onImageLoad(e:Event):void {
numLoaded++;
pbarHolder.pbar.setProgress(numLoaded, friendsList.length);
if (numLoaded == friendsList.length) {
initGame();
}
}
protected function initGame():void {
pbarHolder.pbar.visible = false;
info.text = "Level 1";
shuffleFriends();
stage.addEventListener(Event.ENTER_FRAME, dropper);
timer.addEventListener(TimerEvent.TIMER, drop);
timer.start();
}
protected function shuffleFriends():void {
var temp:Array = friends;
friends = [];
while (temp.length > 0) {
var r:int = Math.floor(Math.random() * temp.length);
friends.push(temp[r]);
temp.splice(r, 1);
}
}
protected function drop(e:TimerEvent):void {
if (friendCount == friends.length) {
friendCount = 0;
shuffleFriends();
}
var f:friend = friends[friendCount];
f.x = xPos;
f.y = f.height * -1;
f.addEventListener(Event.ENTER_FRAME, dropping);
friendsHolder.addChild(f);
friendCount++;
}
protected function dropping(e:Event) {
var f:friend = friend(e.currentTarget);
f.y += friendSpeed;
if (f.y > stageH) {
friendsHolder.removeChild(DisplayObject(f));
f.removeEventListener(Event.ENTER_FRAME, dropping);
numCaught++;
if (numCaught == needToCatch) {
numCaught = 0;
if (dropperSpeed > 0) {
dropperSpeed += speedInc;
} else {
dropperSpeed -= speedInc;
}
friendSpeed += speedInc;
friendDelay = f.height / friendSpeed / stage.frameRate * 1000 * friendDelayGap;
timer.delay = friendDelay;
level++;
info.text = "Level " + level;
}
}
}
protected function dropper(e:Event):void {
var rand:Number = Math.random();
xPos += dropperSpeed;
if (xPos > stageW - friends[0].width) {
xPos = stageW - friends[0].width;
dropperSpeed *= -1;
} else if (xPos < 0) {
xPos = 0;
dropperSpeed *= -1;
} else if (rand < dropperChangeThresh) {
dropperSpeed *= -1;
}
}
}
}