Optimizing Tile Drawing in Custom Tilemap Engine

Hello -

I have recently begun development of a simple tile map engine, and I am having some trouble with my rendering. I have been trying to make the array extremely large in order to test it’s drawing capabilities, and it is way slower than I think it should be. It took over 10 minutes just to load a 75x250 grid (which is large, but I doubt it should take as long as it did)

My implementation is:

    var map:Array<Array<Int>> = [
        for (x in 0...250) [
            for(y in 0...75)
                1 
        ]
    ];
    for (i in 0...map.length) {
        for(j in 0...map[0].length) {
            var tile = new Tile(map[j][i]);
            var x = i;
            var y = j;
            tile.setLoc(x, y);
                addChild(tile);
        }
    }

and my Tile class is relatively simple:

class Tile extends Sprite {

private var image:Bitmap;

public function new(id:Int) {
    super();
    switch(id) {
        case 1:
            image = new Bitmap(Assets.getBitmapData("assets/GrassLeft.png"));
        case 2:
            image = new Bitmap(Assets.getBitmapData("assets/GrassRight.png"));
        case 3:
            image = new Bitmap(Assets.getBitmapData("assets/GrassCenter.png"));
    }
    if(image != null) addChild(image);
}

public function setLoc(x:Int, y:Int) {
    if (image != null) {
        image.x = x * Main.TILE_WIDTH;
        image.y = y * Main.TILE_HEIGHT;
    }
}

}

You are calling Assets.getBitmapData each time you create a new Tile instance, which is definitely not necessary.
You should get references of your assets only once, at the beginning for example.

You should use internal openfl classes called Tilemap, Tile and Tileset with an Atlas png instead of using many different small PNG and standard display list. This sould improve performance a lot!

So would you suggest assigning each texture using Assets.getBitmapData to variables outside the switch statement, and then just using those variables inside the switch statement?

I’ll look into that, thank you!

I would load the textures in the Main class (so it’s done only once) in an array, and then pass it to the Tile constructor. Because, for now, you are loading the same texture many times, so it takes time & memory for no reason :slight_smile:
Moreover, I strongly suggest to follow advices from @loudo, because you could achieve the whole rendering of this tiles grid in a single draw call on many targets, thanks to OpenFL :slight_smile:

It shouldn’t be wrong to call Assets.getBitmapData more than once (because it caches the result by default) but I agree that Tilemap is going to handle code like this better