Game Development Community

Working on a tile map

by Robert Lohaus · in Torque 2D Beginner · 11/30/2013 (9:20 am) · 11 replies

Looking through the documentation doesn't really shed too much light on rendering a tile map with template sprites.

Very raw algorithm:

for Render column
for Render row

if tile.type == "plains"

set properties

scene.add(random sprite from the plains template resource)

...

end
end

I don't need any help with the algorithm itself, I just need to know which sprite type to use and which methods allow me to pick out a sprite from a template and add it to the scene.

#1
11/30/2013 (9:50 am)
CompositeSprite is the class to use for tilemaps. An example:

function CompositeToy::create(%this)
{
	%map = new CompositeSprite();
	%map.setBatchLayout("rect");
	%map.setDefaultSpriteStride(10, 10);
	%map.setDefaultSpriteSize(10, 10);

	for (%y = 0; %y <= 2; %y++)
	{
		for (%x = 0; %x <= 2; %x++)
		{
			%map.addSprite(%x SPC %y);
			%map.setSpriteImage("ToyAssets:tiles", 5);
		}
	}

	%map.setPosition("-10 -10");
	SandboxScene.add(%map);
}

github.com/GarageGames/Torque2D/wiki/CompositeSprite-Guide
#2
11/30/2013 (12:26 pm)
Simple and easy, thanks.
#3
12/06/2013 (9:36 pm)
I have done some experimenting and I am finding the results to be unsatisfying and I am wondering if I am doing it correctly. I know I am using the CompositeSprite correctly, so far as illustrated above. My problem is that the performance is pretty poor.

I am creating a tile map for a strategy game that has tiles that are basically 64x64, plus there are many "layers". Just piling tiles on top of each other (land on top of water, forest on top of land on the same layer) doesn't work for what I am trying to do, hence the use of layers.

At first I tried just doing it manually, creating sprites and just adding them to the scene individually. Rending just 3 layers (out of a possible 10-15) got me 46 fps on my high end desktop. Using a CompositeSprite for each layer got me to 125 fps. An improvement, but it is quickly going to grind to a halt. I know fps is only a relative measurement, but I don't need any further testing to realize I need to do something different.

I created a barebones engine using Direct2D and it handled many, many layers just fine, even on my older and much slower desktop. My question is this: What is the best way in Torque2D to create a complicated tile map?
#4
12/07/2013 (6:46 am)
When you say "layers", you mean you mean multiple CompositeSprite objects? How many are you creating? Can you post the values you use for the CompositeSprite?
#5
12/07/2013 (9:48 am)
%tlx = $mapTopLeftX;
   %tly = $mapTopLeftY;

   %layer1 = new CompositeSprite();
   %layer1.setBatchLayout("rect");
   %layer1.setDefaultSpriteStride(1,1);  
   %layer1.setDefaultSpriteSize(1,1);

   %layer2...

   %layer3...

    ect...

   //Add map tiles to scene
   for(%col = 0; %col < $mapHeight; %col++)
   {
      for(%row = 0; %row < $mapWidth; %row++)
      {
         %layer1.addSprite(%tlx SPC %tly);  
         %layer1.setSpriteImage("Base:waterTemp12",getRandom(0,11));
         %layer1.SceneLayer = 31;

         %layer2...
         %layer3...
         ect...
      }
    }

   %layer1.setPosition("0 0");  
   mapScene.add(%layer1);

   %layer2...
   %layer3...

Yes, to answer your question. I do the same with each layer. The map is 50x50 tiles, just for testing, could be much bigger.
#6
12/07/2013 (10:37 am)
And let me clarify that I am using the debug executable. The regular one is much faster obviously, but performance is still a concern. I am running a high end desktop and my game is meant to run on a range of systems. On my older desktop using a Direct2D engine and the debug runtime, I was getting 200fps with everything rendering (gui,icons, 10 different layers or more).

Does Torque simply not run hundreds of small tiles at the same time well?
#7
12/07/2013 (11:00 am)
It handles it pretty well on my end. CompositeSprites are particularly optimized. You are always going to have poor performance in debug mode. I can get upwards of 500-600 fps on complex scenes.

I can generate up to 10,000 sprites in a single CompositeSprite and not dip below 60 fps on my Mac. My PC is significantly less powerful, but can stay above 60fps with that many. I'll have to try creating multiple layers on my PC to see what results I get.

After all the sprites are created and the scene is running, that's when you get the bad performance? The for loop is going to cause some stuttering at first.
#8
12/07/2013 (11:08 am)
Why are they all being added to the same location, btw? You aren't using %col or %row.
#9
12/07/2013 (11:18 am)
Ok, tested on my low-end PC. I can show 7,500 sprites and get a steady 34 fps. That's 3 CompositeSprite objects, each with 50 rows and 50 columns. When I zoom in to only show 420 sprites, I'm getting about 410 fps.

On my high-end Macbook Pro, I can get about 55 fps when I increase the rows and columns to 100. That's 30,000 on screen sprites.
#10
12/07/2013 (12:05 pm)
Its not verbatim code.

I will do more testing under a heavier load. I just wanted to make sure that I was using the most efficient way without tinkering with the engine.

A couple of things:

1) Only the part of the CompositeSprite that is within the camera view affects system performance? I am going to be using a lot of them.

2) The camera size setting in the sceneWindow dictates the scaling of everything else added to that window? I obviously got my code working, so that seems to be the case. The documentation didn't really mention that important detail or at least explicitly say how it worked.

Thanks for the help, btw.
#11
12/07/2013 (12:06 pm)
Quote:1) Only the part of the CompositeSprite that is within the camera view affects system performance? I am going to be using a lot of them.
Correct. Anything outside of the camera view is occluded.

Quote:2) The camera size setting in the sceneWindow dictates the scaling of everything else added to that window?
The render scale and perspective, yes. It does not dictate the physical scale of objects.