"How about if you call c.graphics.clear() at the beginning of runTimeTest?"
James Ward
Yes, adding c.graphics.clear() fixed it.
Matt
Flash persists all drawing commands (i.e. graphics) until you call graphics.clear(). This so that you can draw over multiple frames without having to draw everything at once.
The reason it takes longer and longer to draw the triangles is that each time you call runTimeTest() Flash is having to draw an extra 10,000 triangles.
So the first time it is called Flash draws 10,000 triangles, the second time you call runTimeTest() it has to draw the first 10,000 triangles (because you haven't cleared the canvas) and then the second 10,000 triangles.
The solution, as Glenn points out, is to clear the canvas prior to drawing each set of triangles. That way Flash only has to draw the current set of triangles.
If, for whatever reason, you do need to draw an absurd number of items to the screen you can take advantage of bitmap caching: if you draw graphics on a different Canvas/Sprite each time then Flash only has to draw each graphic once (the others are cached in memory behind the scenes).
e.g.
private function drawTriangles():void
{
var x0:int, x1:int, x2:int;
var y0:int, y1:int, y2:int;
// set triangle vertices
x0 = 100; y0 = 500;
x1 = 120; y1 = 515;
x2 = 155; y2 = 500;
// This is the important part.
// Draw 10,000 triangles only on this new sprite.
var c:Sprite = new Sprite();
c.cacheAsBitmap = true;
addChild(c);
for (var i:int = 0; i < 10000; ++i)
{
c.graphics.beginFill( 0xff0000, 1 );
c.graphics.moveTo( x0, y0 );
c.graphics.lineTo( x1, y1 );
c.graphics.lineTo( x2, y2 );
c.graphics.lineTo( x0, y0 );
c.graphics.endFill();
}
}
With this method you will notice that it takes approximately the same amount of time to draw the triangles every time (because, Flash is really only drawing the same number of things each time).
Just note that you gain the greatest benefits to bitmap caching when you are dealing with largely static graphics.
In general, only draw what you need and do a graphics.clear() if you don't need to keep what was previously on the canvas.
In response to Matt's comment:
Do you mean if endFill() was not called after each triangle (as it currently is)?
That wouldn't have any performance benefits, it would just change what was drawn. If you draw over the same area during the same beginFill/endFill section it will "invert" the drawn section each time.
It's a little hard to explain without an example...
Lets alter your triangle function so that it will draw two triangles in the same beginFill/endFill section:
c.graphics.beginFill( 0xff0000, 1 );
for (var i:int = 0; i < 2; ++i)
{
c.graphics.moveTo( x0, y0 );
c.graphics.lineTo( x1, y1 );
c.graphics.lineTo( x2, y2 );
c.graphics.lineTo( x0, y0 );
}
c.graphics.endFill();
If you run that then you won't see anything on the screen!
That's because you are drawing over the same area twice and it's being inverted (made transparent) - Flash is technically still drawing it, but you just can't see it.
If you change the number of iterations to 3 then you'll see the triangle again (because it toggles each time from visible -> invisible -> visible).
This page explains it quite nicely (see the 'Winding' section about a third of the way down) - although it's talking specifically about Flash Player 10, the same idea applies in previous versions, we just didn't have control over it back then :)
http://www.flashperfection.com/tutorials/Flash-Player-10-Drawing-API-10877.html