0
votes

I'm working on a small game in Flash (AS3) that generates levels using small tiles.

The location,width,height and other properties of the tile are stored in an array upon generation. Each tile is added to the same container movieclip. When all tiles have been generated, the container movieclip is converted to a bitmap, all tiles are removed from the stage, and the original container is removed from the stage and then deleted. The bitmap is the only remaining "graphic" on the stage, aside from the player.

This yields far better performance than allowing all 60,000+ tiles to be rendered individually during gameplay; however, the framerate still reduces as the number of tiles is increased. This makes no sense, as all the tiles are added to a single bitmap that is always the same size, regardless of the amount of tiles.

With 20,000 tiles during generation, the game runs at the full FPS, but with 60,000 it runs relatively choppy, probably around 4-5 FPS.

I've removed collision detection and any/every script that runs through the tile array to rule out the possibility that some other CPU intensive part of the script is lagging the framerate.

Any idea why, despite the fact that all tiles have been removed from the stage and their container is deleted, the game is still running slow even though the background bitmap contains the same amount of data regardless of the number of tiles generated?

Here is the last part of the level generation algorithm which converts the container movieclip to a bitmap and then removes all the tiles:

        var temp_bitmap_data:BitmapData = new BitmapData(this.stage_background_mc.width,this.stage_background_mc.height);

        temp_bitmap_data.draw(this.stage_background_mc);

        this.stage_background_bitmap = new Bitmap(temp_bitmap_data);


        main_class.main.stage.addChild(this.stage_background_bitmap);

        for (var block in blocks_array)
        {

             //every block in blocks_array has a child that is the actual graphic of the tile
             blocks_array[block]["block"].removeChild(blocks_array[block]["block"].getChildAt(0));

            if (blocks_array[block]["type"] == "bg_block")
            {
                this.stage_background_mc.removeChild(blocks_array[block]["block"]);
                blocks_array[block]["block"] = null;
            }
            if (blocks_array[block]["type"] == "path_block")
            {

                //path_blocks have a second child in addition to the first one that's already been removed. the second child is the only other child
                blocks_array[block]["block"].removeChild(blocks_array[block]["block"].getChildAt(0));
                this.stage_background_mc.removeChild(blocks_array[block]["block"]);             

            }




        }

        this.stage_background_mc = null;

[Edit] Here is a picture of the game to give you a better idea of what's going on: the game level

[Update:]

Even removing the final created bitmap from the stage, ending up with only 1 child on stage, and setting that removed bitmap to null doesn't improve the speed.

1

1 Answers

4
votes

A couple of thoughts.

First, you're sorta half taking advantage of AS3's quick work with blitting. You've got the right idea about having only one single Bitmap on the stage, but the steps before (adding DisplayObjects to a MovieClip and the doing draw on that MovieClip) isn't the fastest process. For one thing, BitmapData.draw is slower than BitmapData.copyPixels (here is a post on that). One of the best ways to get speed is to pre-blit all of your graphics, and store them as BitmapData. Then, keep Object references (containing position, etc) for each graphic. In your render loop, run through each object, and use copyPixels to copy the graphic's pixel information to the appropriate positon in your single, on-stage Bitmap. This way, all slow BitmapData.draw commands have happened upfront, and now you are just pushing pixels, which Flash is really fast at.

That process isn't without its downsides, however. For instance, you can't do easy transforms with it. You'd have to pre-blit all frames of a rotation, for instance, in order to rotate the individual graphic (since you can't rotate a BitmapData, and you aren't using draw on a DisplayObject). Still, it is mighty fast if you can live with the limitations.

Here is a post that serves as a tutorial of the process I explained above. It is old, but informative none-the-less.

Finally, 60,000 is a very large number. Flash isn't exactly a "speed demon." No matter how optimized, eventually you'll hit a limit. Just something to keep in mind.

Oh, and this additional post gives some great tips on performance in Flash.