AS3 Tips and Tricks

18 posts

Flag Post

Share your tips for optimizing AS3 games and applications!

 
Flag Post

http://gaming.adobe.com/technologies/scout/

 
Flag Post

If only Scout worked on 32 bit computers…

 
Flag Post

I use The miner it’s nothing like Scout but still helpful

 
Flag Post

Hmmm. The Miner looks interesting. Thoughts anyone?

 
Flag Post

a few off the top of my head:

  • use vectors instead of arrays.
  • iterate backwards through vectors instead of forwards.
  • when iterating through an vector, but before the loop, instantiate a var tempClass:Class where class is the type of object your vector contains. At the beginning of each loop, set tempClass to tempVector[i] where tempVector is the vector you are iterating through. From then, just use tempClass.function() or tempClass.variable etc rather than tempVector[i].function() or tempVector[i].variable. In this way you minimize the number of retrievals.
  • if dealing with a lot of objects on screen (such as bullet hells) look into object pooling. This is where you have a pool of instances of say, Bullet, already instantiated and ready for use. You have two (or more) vectors, the most conventional setup being an activePool:Vector and an inactivePool:Vector (both, of type Bullet, formatting prevents me from showing such here). As you need bullets, you pop from the inactive pool into the active, and as they hit or otherwise expire (such as go off screen or whatever) you pop that specific one from the active pool and put it back into the inactive pool. An activate() and deactivate() function may be helpful in your Bullet class, in this case, or at the very least the ability to reset needed vars (such as a lifeTime:int variable, worldX/Y, dx/dy)
  • most of your processing is eaten up via your rendering. Focus on this first. For example, dont render something if it is off the screen or outside of your camera bounds. However, DO update its position, state, etc.
  • when rendering a sprite containing a tile sheet of sorts (or, preferable, a reference to a common tile sheet for all other instances of its ‘type’ of creature), that has a delay between its various frames (for example, a delay of 5 ticks between each tile of its “walk-state”), do not render its current bitmapData tile UNTIL it is actually changing tiles, or only on instantiation. (Where current bitmapData tile is what is copied to the game canvas or camera). And again, ONLY if it is in camera bounds. i.e.
    if (GameControllerClass.inCameraBounds(tempBlitSprite)) tempBlitSprite.renderCurrentTile()
 
Flag Post

If you want to write down some ‘Tips & Tricks’ for others, use the existing sticky thread.

 
Flag Post

@Lucidius
Iterating backwards through arrays is good practice even when not considering performance. If you remove an element while mid-loop it will not disrupt anything if you are iterating backwards.

 
Flag Post
Originally posted by Lucidius:

iterate backwards through vectors instead of forwards.

I don’t know about this one. In many cases, the machine will optimize for iterating forwards. That is, when you retrieve tempVector[3], it will also retrieve and cache tempVector[4], tempVector[5], and perhaps a few more. This won’t be any use if you iterate backwards, though.

If you’re worried about looking up tempVector.length every iteration, store it in a variable.

Edit: I’ve just tested these suggestions, and on my machine it makes approximately no difference. 1.2 million iterations takes ~0.013 seconds, regardless of which way you iterate, regardless of whether you store the vector length. (Though if you’re using Haxe/OpenFL and compiling to C++, storing the vector length is a huge improvement. I guess in this case Flash is surprisingly well optimized.)

Originally posted by RTL_Shadow:
If you remove an element while mid-loop it will not disrupt anything if you are iterating backwards.

That’s certainly a valid reason, though others would suggest using a linked list if you want to remove things while iterating. Or wait until you’re done iterating through the vector and then remove them.

Actually, I know of performance-focused libraries that use each of these methods. TweenMax iterates backwards, Box2D uses linked lists, and AndEngine crashes if you remove something before it’s done iterating.

 
Flag Post

Iterating forwards allows the fastest removal of objects (if order is not important). Thanks to UG for this.

var length:int = vec.length;
for(var i:int = 0;i<length;i++){
   if(vec[i].isDead){
      vec[i] = vec[length-1];
      i--;
      length--;
      vec.length--;
   }
}
 
Flag Post

Read everything here.

 
Flag Post

vector[vector.length] = value seems to be faster than vector.push(value)

 
Flag Post

For my tips in AS3 i would say, dont take Number strings for granted. These little beauties can be timers, have Race qualities for RPG game elements and also for a Level up and XP system if you code deep enough with number strings.

 
Flag Post
Originally posted by mixta11:

For my tips in AS3 i would say, dont take Number strings for granted. These little beauties can be timers, have Race qualities for RPG game elements and also for a Level up and XP system if you code deep enough with number strings.

Also, don’t post drunk. Or on drugs. Or whatever the hell it is you were on when you posted this.

“Number strings”…

Edit: \/ Number strings don’t add. They concatenadd.

 
Flag Post
Originally posted by Lucidius:

iterate backwards through vectors instead of forwards.

The main concern developers have with iterating forward instead of backward is this:

for (i = 0; i < array.length; i++)

If you store the length in an int prior to beginning the loop, it becomes a non-issue.

@feartehstickman: Technically, that method for array element removal can still be used when iterating backward as well:

vec[i] = vec[length - 1];
vec.length--;
length--;

…Wait, what’s this about Number Strings? This sounds like dangerous witchcraft, and I can’t wait to see what happens when you try to add them together.

 
Flag Post
Originally posted by Aesica:
@feartehstickman: Technically, that method for array element removal can still be used when iterating backward as well:

vec[i] = vec[length – 1];
vec.length—;
length—;

Indeed. It seems that forwards or backwards makes no difference. But once again, UG has come up with an even faster way.

var current:int = 0;
for (var i:int = 0; i < a.length; i++)
{
	if(i != current)// if not same slot
	{
		a[current] = a[i];
	}
	if (!b) //keep condition << this is not throw away condition! (should be !b)
	{
		current++;
	}
	
}
a.length = current;
trace("end", a);
 
Flag Post

Speed of that function is largely dependent on where elements are being removed at, since that loop preserves array order. Likely you’ll find the existing (and unordered) vec[i] = vec[length-1] to be faster in certain scenarios. (i.e. long arrays, with elements being removed near the front)

 
Flag Post

Ah, ok. Testing time then.