Question about scrolling, layer size, and tiling
by Jacob Vann · in Torque Game Builder · 08/16/2005 (9:25 pm) · 12 replies
I just purchased T2D a few days ago, and am pretty impressed with how easy certain things are. It definitely borrows a lot of concepts from the 3d world, which took some getting used to for a old-schooler like me. I plan to make a scrolling game with many different-sized "levels" (more like corridors or rooms) loaded on the fly.
I'm able to create my tile imagemap and load the tilemap and it displays and scrolls just great (after some "forehead on the desk" moments). However, here are some questions/concerns:
1. You have to specify the size of the Tile Layer before drawing it. However, since I'll be loading the tile maps from files, and there will be no guarantee on the size of the maps, is there a way to have T2D automatically detect the size of the tilelayer?
I tried this piece of code, but it ended up just not showing the tiles at all:
function CreateTileMap() {
// Create the tilemap
%scrollerMap = new fxTileMap2D() {scenegraph= t2dSceneGraph;};
%scrollerMap.loadTileMap("~/client/maps/sjtilemap1.map");
%groundlayer = %scrollerMap.getTileLayer(0);
%groundlayer.setPosition("512 0");
%groundlayer.setTileSize("64 64");
%layersizex = getWord(%groundlayer.getTileCount(), 0) * 64;
%layersizey = getWord(%groundlayer.getTileCount(), 1) * 64;
echo("LayerSize X="@%layersizex);
echo("LayerSize Y="@%layersizey);
%groundlayer.setSize("%layersizex %layersizey");
%groundlayer.setWrap(false, false);
}
... any idea? I echo out layersizex and layersizey to make sure they are getting set, and they have the right values... It seems to me there should be a way to have the engine use a default tilelayer size calculated from tilecount*tilesize?
2. Similar question, but for setting the World Limit for the camera and for the player object. Is the programmer expected to hard code these values in for each level? Is there a preferred method of calculating these (again based on the tilemap that is being loaded)? It would be a great hinderance to have to calculate the WorldLimit rects every single time a new region is entered.
3. I know this has been asked/addressed before, but I want to repeat it. The gaps inbetween the tiles (do to a texture filter or whatever) is really not good. The inset option is not valid, as I already have many, many tiles drawn and it creates seams whenever I set the inset value (they no longer tile cleanly). I hope there is a real fix on the way for this...
Thanks again for your time. I really am enjoying Torque2d, and look forward to being part of the community!
-Jacob
I'm able to create my tile imagemap and load the tilemap and it displays and scrolls just great (after some "forehead on the desk" moments). However, here are some questions/concerns:
1. You have to specify the size of the Tile Layer before drawing it. However, since I'll be loading the tile maps from files, and there will be no guarantee on the size of the maps, is there a way to have T2D automatically detect the size of the tilelayer?
I tried this piece of code, but it ended up just not showing the tiles at all:
function CreateTileMap() {
// Create the tilemap
%scrollerMap = new fxTileMap2D() {scenegraph= t2dSceneGraph;};
%scrollerMap.loadTileMap("~/client/maps/sjtilemap1.map");
%groundlayer = %scrollerMap.getTileLayer(0);
%groundlayer.setPosition("512 0");
%groundlayer.setTileSize("64 64");
%layersizex = getWord(%groundlayer.getTileCount(), 0) * 64;
%layersizey = getWord(%groundlayer.getTileCount(), 1) * 64;
echo("LayerSize X="@%layersizex);
echo("LayerSize Y="@%layersizey);
%groundlayer.setSize("%layersizex %layersizey");
%groundlayer.setWrap(false, false);
}
... any idea? I echo out layersizex and layersizey to make sure they are getting set, and they have the right values... It seems to me there should be a way to have the engine use a default tilelayer size calculated from tilecount*tilesize?
2. Similar question, but for setting the World Limit for the camera and for the player object. Is the programmer expected to hard code these values in for each level? Is there a preferred method of calculating these (again based on the tilemap that is being loaded)? It would be a great hinderance to have to calculate the WorldLimit rects every single time a new region is entered.
3. I know this has been asked/addressed before, but I want to repeat it. The gaps inbetween the tiles (do to a texture filter or whatever) is really not good. The inset option is not valid, as I already have many, many tiles drawn and it creates seams whenever I set the inset value (they no longer tile cleanly). I hope there is a real fix on the way for this...
Thanks again for your time. I really am enjoying Torque2d, and look forward to being part of the community!
-Jacob
#2
I tried setting inset to 0.5. This doesn't create seams, but it doesn't fix the problem everywhere either. Here's a screen capture:
www.jacobvann.com/T2D/screenshot.png
And the tiles are being rendered at the same resolution they are in the .png file (64 x 64 pixels). So they look fine (i.e., not blurry) but the seams have got to go. :) Setting the tile size to 32 x 32 (having it filter down to a lower size) doesn't seem to help with the seams, and isn't what I want anyway.
I'm not trying to achieve "pixel perfect" graphics (most are drawn by hand in photoshop, not a pixel at a time), but when I would like it to look as close as possible as it does when I created them.
08/16/2005 (10:30 pm)
Thanks Jason for the reply.I tried setting inset to 0.5. This doesn't create seams, but it doesn't fix the problem everywhere either. Here's a screen capture:
www.jacobvann.com/T2D/screenshot.png
And the tiles are being rendered at the same resolution they are in the .png file (64 x 64 pixels). So they look fine (i.e., not blurry) but the seams have got to go. :) Setting the tile size to 32 x 32 (having it filter down to a lower size) doesn't seem to help with the seams, and isn't what I want anyway.
I'm not trying to achieve "pixel perfect" graphics (most are drawn by hand in photoshop, not a pixel at a time), but when I would like it to look as close as possible as it does when I created them.
#3
of course, big disclaimer that i am speculating as to the cause of the problem... i have not done ANY research to back that up.
08/17/2005 (1:05 am)
Without looking into the engine code, i suspect that this random gapping may be due to floating point rounding errors, especially when translating tile coords to screen coords.of course, big disclaimer that i am speculating as to the cause of the problem... i have not done ANY research to back that up.
#4
08/17/2005 (1:53 am)
It's not random gaps, it's simply a rendering artifact from the bilinear filtering that goes on by default. Jacob, if you can handle it, just keep plugging away and ignore the edge artifacts. Melv has stated that an upcoming (I don't recall if it's the next one) update to T2D will have options to control the filtering applied to your sprites (bilinear, next pixel, etc).
#5
The drawback is it does nearest neighbor to the entire sprite so if you have some sprites you want bilinear filtered and some you want nearest-neighbor filtered, you'll need to split them into different image files (you can't define two datablocks, one with bilinear and one with nearest-neighbor with the same file either, since the file gets processed on-load and cached by the resource manager.)
08/17/2005 (8:00 am)
Also if you choose not to wait for the next release, you can modify the engine to support a 'nearest neighbor' flag in the fxImageMapDatablock2d using the code in this thread. The drawback is it does nearest neighbor to the entire sprite so if you have some sprites you want bilinear filtered and some you want nearest-neighbor filtered, you'll need to split them into different image files (you can't define two datablocks, one with bilinear and one with nearest-neighbor with the same file either, since the file gets processed on-load and cached by the resource manager.)
#6
And, is there a better way to assign the tilelayer sizes and the world limit for sprites? Can someone tell me what's wrong with my example in #1? (in the first post). Can someone point me to a document that describes the tile map format? I'm trying to make decisions about how to design how the areas connect together, and it would be good to know what T2D has that can be useful...
Thanks all! You have been quite helpful!
-Jacob
08/17/2005 (1:20 pm)
I can live with the gaps if it'll be "officially" solved soon. Nearest Neighbor does sound like what I will need. I will download the patch mentioned above (it's really quite small) and give it a shot. Is the official fix just going to be controlling the filtering down to the sprites and tiles? Or is there a more all-purpose solution that still uses bi-linear filtering and just removes the gaps?And, is there a better way to assign the tilelayer sizes and the world limit for sprites? Can someone tell me what's wrong with my example in #1? (in the first post). Can someone point me to a document that describes the tile map format? I'm trying to make decisions about how to design how the areas connect together, and it would be good to know what T2D has that can be useful...
Thanks all! You have been quite helpful!
-Jacob
#7
If you search through the forums, you can see the engine changes required if you want to bring your maps up to date.
08/17/2005 (1:55 pm)
The file format for the maps is going to change in the next release, which will mean your current maps will be unusable.If you search through the forums, you can see the engine changes required if you want to bring your maps up to date.
#8
So I won't spend too much energy building tile maps for a while :) This is fine, I'll just keep building test tilemaps to test parts of the game engine and sprite behavior.
08/17/2005 (10:21 pm)
Quote:The file format for the maps is going to change in the next release, which will mean your current maps will be unusable.
So I won't spend too much energy building tile maps for a while :) This is fine, I'll just keep building test tilemaps to test parts of the game engine and sprite behavior.
#9
If it's the same issue I had Melv may need GL_CLAMP_TO_EDGE for tiles. Using that solved my border seam problems.
08/17/2005 (10:34 pm)
When it moves, (if it moves) does it kind of "jiggle" at the seams? Are the seams mostly white? It really looks like the same thing I fixed in my code a long time ago.If it's the same issue I had Melv may need GL_CLAMP_TO_EDGE for tiles. Using that solved my border seam problems.
#10
For question number 2: You don't need to hard code the world limits for each level. Again, here's what I do:
Hope that helps.
-Peter
08/18/2005 (8:58 am)
Hay Jacob! Good to have you on board. I'll try to help you a little. The lines will be fixed. In the code in your first post you're setting the position to 512 0. This is setting the center of your tile map to that location. Unless you're moving your camera this is probably not what you want. You should just be able to set it to 0 0. Also you called set size. You shouldn't have to do that. This is all I do to load my tile maps.// Create tile-map
$level = new fxTileMap2D() { scenegraph = t2dSceneGraph;};
$level.loadTileMap("~/client/test.map");
%myLayer = $level.getTileLayer(0);
%myLayer.setPosition("0 0");For question number 2: You don't need to hard code the world limits for each level. Again, here's what I do:
%myLayer = $level.getTileLayer(0); %levelSize = %myLayer.getTileCount(); %levelSizeX = GetWord(%levelSize,0); %levelSizeY = GetWord(%levelSize,1); %tileSize = %myLayer.getTileSize(); %tileSize = GetWord(%tileSize,0); %levelSizeX *= %tileSize; %levelSizeX /= 2; %levelSizeY *= %tileSize; %levelSizeY /= 2; sceneWindow2D.setViewLimitOn(-%levelSizeX SPC -%levelSizeY SPC %levelSizeX SPC %levelSizeY);
Hope that helps.
-Peter
#11
Thanks for the reply! You got me in the right direction ...
In your second code sample, I see exactly what it's doing. And it makes sense. However, it was off by half to the top and left. I had to change
to
Any ideas why? I am moving the camera (mounted to the player sprite), and the level (in this case) is 2 screens wide by 1 screen tall. I will clean up my code and see if it works for an arbitrarily sized tilemap.
Thanks!
08/18/2005 (3:26 pm)
Hi Peter -Thanks for the reply! You got me in the right direction ...
In your second code sample, I see exactly what it's doing. And it makes sense. However, it was off by half to the top and left. I had to change
%levelSizeX *= %tileSize;
%levelSizeX /= 2;
%levelSizeY *= %tileSize;
%levelSizeY /= 2;
sceneWindow2D.setViewLimitOn(-%levelSizeX SPC -%levelSizeY SPC %levelSizeX SPC %level
SizeY);to
%levelSizeX *= %tileSize;
%levelSizeY *= %tileSize;
sceneWindow2D.setViewLimitOn("0 0" SPC %levelSizeX SPC %levelSizeY);Any ideas why? I am moving the camera (mounted to the player sprite), and the level (in this case) is 2 screens wide by 1 screen tall. I will clean up my code and see if it works for an arbitrarily sized tilemap.
Thanks!
#12
-Peter
08/19/2005 (3:27 pm)
Its because my level for example would go from -60 to 60 and your's would go from 0 to 120. Make sense?-Peter
Torque Owner Jason Cahill
Default Studio Name
I've been playing with trying to get "pixel perfect" graphics out of T2D since day one and the bilinear filtering issues are really nasty. It's not Melv's fault, it's just the way that 3D graphics hardware works. There are a couple of things to consider:
a) Your graphics will look bad if you are filtering up (art resolution < on screen resolution)... in other words, you have tiles that are 16x16 texels, but are rendering to 64x64, for example. Going the other direction looks much, much better.
b) I've done a bunch of experiments myself and cannot tell much of a difference between a single tile image (fxImageMapDatablock2D mode = "full") and a tiled image map (fxImageMapDatablock2D mode = "cell" / inset = 0.5). The important thing is that you've got to have the inset=0.5. That seems to be the magic value that causes the best results out of cell and key based image maps.