Tile based game - drawTiles individually or generate a 'big map'

I’m porting some tile-based games through openFl and they all run fine except in ios html5 of course which I’m imagining it because I’m doing drawtiles on every single tile and it doesn’t like that - even in webgl mode.

Do you folks prefer to generate a big old bitmap of the whole map before running - or go with the ‘every single tile every time’ method as demonstrated in this tutorial ?

http://haxecoder.com/post.php?id=25

It does amaze me how the ios Mobile browser can run so much slower than the android ones. I thought it would be the other way round !

anyway cheers for any pointers team x

Hum…Seems to be the opposite, there is only one drawTile each frame. But be careful with this example, you shouldn’t use concat() with an array because it will create a new array on each loop :frowning:

Cheers Loudo - I don’t think I wasn’t specific enough

  • currently I’m doing this below (which I shouldn’t be concatting ! - I’m going to change that as soon as ) but I thought it might be quicker if instead of dealing with mapRows * mapCols amount of small gfx objects, I just moved one laaarge pre-drawn map graphic around - which I had created with copypixels at level init.

for (rowCtr in 0…mapRows)
{
for (colCtr in 0…mapCols)
{
if(bgyDif + rowCtr < fList.length)
{
var cellVal:Int = fList[bgyDif + rowCtr][bgxDif + colCtr];

			var yPos:Int = rowCtr * tileSize      - Math.floor(bgy - (bgyDif * tileSize));
			var xPos:Int = colCtr * tileSize      - Math.floor(bgx - (bgxDif * tileSize));
			  
			Main.instance.displayWorld.tileData = Main.instance.displayWorld.tileData.concat([xPos, yPos, MasterTileCreator.BASE_FRAME_TILES + cellVal,1,0,0,1]);
			}
	
		}
		
	}
	
}

There are a bunch of factors at play here.

  • How much time does it take to move all the tiles? (Should be less once you stop using concat(), but it won’t be 0.)
  • How much time does it take to render an enormous bitmap?
  • Is there a limit on bitmap size? (Flash has one, as do some low-end Android devices.)
  • How often do you move from area to area?
  • Do you have a small number of tiles that you reuse a lot, or a large number that you use a few times each? (If it’s the former, then rendering to a single bitmap would waste memory.)

The “big bitmap” option is simpler to understand, but if you’re willing to learn about OpenGL, you’ll find that there are many more options for optimizing the “individual tiles” option. That said, you might not experience lag at all, in which case optimization would be a waste of time. Profile before optimizing.

If you see like big map possible bugged version openfl 3.6.1

Please downgrade to Openfl 3.6.0 and set from haxelib set openfl -> 3.6.0

And compile again if you see result if your game works fine if you use Openfl 3.6.0 Thanks!

I’d suggest that you just try to pre-render the tiles that you know will be immediately needed:   at least, “the tiles that are right-now needed by the game, and those that are (± n=[1…2]) adjacent to it.   As the player’s (x,y) position within the game changes, this background-task should strive to keep up.

Whenever a particular previously-rendered square goes out-of-range, it should be disposed-of.

One possible way to handle the case of “I’d really like to hang on to this, if I can, but I’ve no way to know if I have enough memory to do so …” is to simply write code that confidently attempts to do so, throwing an exception if anything goes wrong.   This piece of code is then executed within a surrounding block of code that “is prepared for the worst.”   If the rendering routine throws an out-of-memory exception, the surrounding-code releases a previously-cached square and tries again.   In this way, the algorthm “adaptively, but opportunistically,” tries to adapt itself to the prevailing memory conditions.

Quite frankly, I would never presume that you can actually get away with “rendering a ‘big map.’” … …   Most-unfortunately, the memory constraints in the real-world Mobile environment are not “virtual.”   They are … most-decidedly … real.

I’d advise against @sundialservices’s suggestion, for a few reasons:

  • Exceptions are slow. You should try to avoid using them in performance-critical code.
  • Exceptions are meant to alert you, the programmer, to an error, so that you can fix it. Using them as an integral part of your algorithm is considered bad practice.
  • Object creation is slow. You should try to avoid using it in performance-critical code.
  • Garbage collection is slow. You should try to avoid using it in performance-critical code. (That said, GC usually runs whenever there’s time to spare, so it may not be as bad.)
  • Trying to get an out-of-memory exception is a terrible idea. Also, it’s kind of rude to the end user, because you’re taking away memory that could be used for background apps.

You can do this with drawTiles() - that’s one of the “options for optimizing” that I mentioned. Simply allocate a big enough array to display a screen’s worth of tiles, and load your spritesheet. Your array tells the game which parts of the spritesheet to show, and where onscreen to show it, so when the camera scrolls, all you have to do is update the array.

This method is efficient about memory. The spritesheet accounts for at least 95% of the memory, and you have to load that no matter what.


@KBsGameTOILET: it looks like drawTiles() will be removed in the next update. Consider using Tilemap instead; it’s easier to use and gives the same performance benefits.

I know Tilemap isn’t documented yet, but BunnyMark uses it, so you can use that to guide you.

As was said above you want to stay away from concat’ing an array, as it recreates it and has crazy overhead. I had that issue as well and people told me exactly how to fix it.

Thanks for all the sage replys - Lots to think about there . I’ll think i’ll end up testing both approaches on a variety of devices to see how far each one can be stretched.

Regarding drawTiles() being removed - I hope the Tilemap replacement uses similar functionality or my previous set-up is going to be a sausaged :frowning:

I’ll go and check out the documentation !