Drawtiles on everyFrame?

I’m iterating through a map array, adding it to tileData array with an X/Y position and tilesheet number, then calling tilesheet.drawTiles with the tileData array. A first thing I’ve noticed is it becomes a huge memory leak unless I run:

  	#if (cpp||php)
  		 arr.splice(0,arr.length);
  	#else
  		 untyped arr.length = 0;
  	#end

to clear the array before every draw. But the performance is extremely poor doing only 40fps without moving the tiles at all or doing anything else. I’ve used Love2d and have done the same thing and gotten much better performance, have I done something wrong?

I notice the drawTiles methods first argument, sheet:Tilesheet, is a sprite in my code, should I perhaps be using something else for this? Most of my code is taken from the ‘Tile based game’ tutorial: http://haxecoder.com/post.php?id=25

Heres my everyFrame function:

private function everyFrame(evt:Event):Void {
clearArray(tileData);
tilesheetCanvas.graphics.clear();

  column = 0;
  row = 0;
  for (index in 0...map.length) {
  	if (column == 40){
  		column = 0;
  		row=row+1;
  	}
  	xpos = column*90;
  	ypos =  row*30;
  	tileData = tileData.concat([xpos, ypos, map[index]-1]);
  	column=column+1;
  }
  tilesheet.drawTiles(tilesheetCanvas.graphics, tileData);

}

public static function clearArray(arr:Array){
#if (cpp||php)
arr.splice(0,arr.length);
#else
untyped arr.length = 0;
#end
}

Everything draws okay, but on html5 I get only 9fps.

At first try to reuse allocated memory when possible (don’t use clear / concat at every cycle, it is very slow).

private static inline var MAX_TILES : Int = 40 * 40; // put real value here
private static inline var TILE_DATA_FIELDS : Int = 3; // x, y, tileId

private function atStart() : Void {
    tileData = new Array<Float>();
    tileData[MAX_TILES * TILE_DATA_FIELDS] = 0.0;
}

private function everyFrame(evt : Event) : Void {
    tilesheetCanvas.graphics.clear();

    xpos = 0;
    ypos = 0;
    tileIndex = 0;

    for (index in 0 ... map.length) {
        if (xpos == 40 * 90) {
            xpos = 0;
            ypos += 30;
        }

        tileData[tileIndex] = xpos;
        tileData[tileIndex + 1] = ypos;
        tileData[tileIndex + 2] = map[index] - 1;

        tileIndex += TILE_DATA_FIELDS; // fixed, thx 2 Lazer_Starr
        xpos += 90;
    }

    tilesheet.drawTiles(tilesheetCanvas.graphics, tileData);
}
1 Like
 tileData += TILE_DATA_FIELDS;

should be

tileIndex += TILE_DATA_FIELDS;

concat() create a new array each time !!!

You should better use what restorer suggests :slight_smile:

Thank you guys for the help, you were right it was simply overloaded with recreating the Array. Now I get 900fps which should be more than enough. :grinning:

Perhaps when I am a bit better I can have a shot at editing some of these tutorials a bit.