Intro
to code optimizations:
In this article we'd like to show some techniques to obtain
better performance for yourgames made in Flash.
Code optimizations are very important as they can help you in better
using the resources of the flash player and make your games run
smoothly on different selections of hardware.
This article is mainly focused on performance issues with Flash
player 6 and on the available techniques to solve them.
With the release of the Flash player 7 some of these issues have
been fixed and performance has improved in general, however at
the moment of writing this article the player 6 is still the most
popular and for this reason we'd like to concentrate on this version.
When to optimize:
The optimization process of existing code can be sometimes pretty
long and difficult, based on how unoptimized the original code is,
so before diving into countless hours of code hacking it should
be necessary to evaluate the areas of code to alter.
The most critical part of a game code is usually the main-loop
section, the one that usually is repeated on every frame and takes
care of updating sprites, graphics and general game status data.
Other code portions outside the main loop, that may need tweaking,
could be those where long loops are run: in this cases it is also
very important to check if you're not wasting too much time and
resources other than those needed for the task in object.
By saving hundreds of milliseconds from different part of your
code you'll be definitely make your SWFs run smoother and enhance
the gaming experience.
Clean code vs. efficient code:
Writing very clean and reusable code (and possibly object oriented)
is a fine art and takes years of experience but sometimes it
can be too expensive in terms of performance.
When dealing with limited resources (and this can be the case of
the flash player) using a high level approach such as the one just
mentioned can lead to poor and unsatisfactory performance .
We're not saying that OOP is bad for game programming, it is just
a little more time consuming and sometimes the “old programming
school” can lead to better results.
In general it is always better to go OOP as it makes code maintenance
much easier but you'll see later in this article that sometimes
you can avoid it in order to squeeze every bit of performance out
of the flash player, for example when dealing with fast scrolling
or running very complex math.
Basic Optimizations:
When talking about code optimizations we usually refer to speed
improvements and not very much to memory savings as today, even
not so recent computers, have good amount of memory for our flash
games (128mb is more than enough for most games and today the standard
for a new machine is 512mb)
>> Variables
One of the most important optimization tip is to always declare
local variables using the keyword var. Local variables are faster
to access for the player and are destroyed when the function returns.
An example of not-so-good code would be this:
function doSomething()
{
mx = 100
my = 100
ar = new Array()
for (y=0; y < my; y++)
{
for (x=0; x < mx; x++)
{
i = (y * mx) + x
arr[i] = i
}
}
return arr
}
This code is not very good because it does not declare those variables
as local, making them slower to access and leaving them alive after
the function has finished.
A better version would be this:
function doSomething()
{
var mx = 100
var my = 100
var ar = new Array()
for (var y=0; y < my; y++)
{
for (var x=0; x < mx; x++)
{
var i = (y * mx) + x
arr[i] = i
}
}
return arr
}
In this case all variables are defined locally and are faster to
access. This is very important as the function runs a 10.000 iterations
loop! When the function returns, all local vars will be destroyed
saving resources.
>> onEnterFrame events:
the onEnterFrame event is very useful for game developers
as we can run code continuously at the frame rate set in the SWF.
Back to the days of Flash 5 it was a pretty common technique to
use many different of these handlers to manage for example the enemies
logic or having one onEnterFrame on each bullet shot etc...
Actually it is not reccomendable to attach many of these event
handlers all over the movie clip because this can lead to spaghetti
code and also it can significantly degrade performance.
Most of the times using one single onEnterFrame can be a good solution:
just one main loop that takes care of the various operations to
carry on.
Another simple tip is to set the fps parameter to a reasonable value:
remember that the higher is the fps the more CPU power you will
need to execute your code in every frame.
Values between 25 and 35 fps can be good to for executing pretty
complex code in every frame even on slower machines and it is not
desirable to exceed the value of 60fps (unless there's a specific
reason)
>> Bitmaps vs Vectors:
Talking about graphics it is very important to choose the right
approach before starting.
Flash seamlessly works with vector art as well as images but these
two have very different impact on the flash player.
In using vector graphics try to simplify the shapes as much as
possible eliminating redundant points. This will help in reduce
the amount of calculations that the player has to compute for each
vector shape. Another important aspect is the usage of outlines,
which can definitely kill your performance. Whenever possible try
to avoid them.
Using alpha values < 100 can also have bad impact on your general
speed, so if you experience noticeable slow downs go hunting all
those alpha values in your movieclips!
Moreover if you really need many sprites on screen and many animated
art you may want to consider bitmap graphics.
Flash is not really a champion of speed in handling bitmaps, (for
example compared to his elder brother Director) however images
are faster than vectors and this is why many tile based flash games
are based on pixel art.
Even if Flash supports GIF, JPG and PNG formats the latter seems
to render faster than the others, therefore we recommend using PNG
whenever possible.
>> Movieclip visibility:
Very often you can have a large number of offscreen movicelips that
are waiting their turn to come into the visible game area. This
usually happens when the game area is larger than the actual game
screen.
When dealing with offscreen stuff it is important to understand
that the flash player still consumes a certain amount of resouces
for each of them. (doesn't matter if they are one frame only or
animated)
One of the best solutions to this problem is to have an empty frame
in your movieclips where you can gotoAndStop(), freeing up some
work to the flash player.
Please remember that setting the visibility property ( _visible
= false ) doesn't work as the movieclip still consumes some player
time.
>> Arrays:
Arrays are widely used in any application and games need arrays
quite often to store their data.
A typical scenario is a tile-based game where the game map is held
in a bi-dimensional array, something like: arr[y][x].
Although this is a very common technique, you can speed up the
access to your game data by using a simple 1-dimension array.
Another important tip to optimize looping in an array is to use
the for in loop instead of the usual for
or while syntax.
Code like this:
for (var i in arr)
{
if (arr[i] > 50)
{
// do some processing here
}
}
has proved to be faster than this code:
for (var i=0; i<10000; i++)
{
if (arr[i] > 50)
{
// do some processing here
}
}
by a 30% ratio! Not bad as a speed improvement especially if you
think that this code may be executed on every frame in your main
game loop!
( ... continues on page 2 )
|