How do you usually size camera view and world view?
by Johan Stenqvist (neochrome) · in Torque Game Builder · 06/03/2005 (12:57 am) · 35 replies
I'm wondering how you guys usually set up your game's camera view size and world view size?
I have a single fxSceneWindow2D at "800 600" for my game screen.
I then set the cameraposition to "0 0 800 600" to get "real pixel size" - it just seemed easier if I could specify the size of my sprites in real pixel sizes. Is this the way you're doing it as well? What is recommended?
I've run into a strange problem - which I guess might have something to do with this. At home everything looks nice and dandy, but at work all my sprites are offset about "-400 -300" compared to my "800 600" sized "viewport" - any ideas of what can cause this?
I hope someone will make any sense of my ramblings and perhaps may be able to help me with a nudge in the right direction... :-)
Happy game-coding to you all!
/Johan
I have a single fxSceneWindow2D at "800 600" for my game screen.
I then set the cameraposition to "0 0 800 600" to get "real pixel size" - it just seemed easier if I could specify the size of my sprites in real pixel sizes. Is this the way you're doing it as well? What is recommended?
I've run into a strange problem - which I guess might have something to do with this. At home everything looks nice and dandy, but at work all my sprites are offset about "-400 -300" compared to my "800 600" sized "viewport" - any ideas of what can cause this?
I hope someone will make any sense of my ramblings and perhaps may be able to help me with a nudge in the right direction... :-)
Happy game-coding to you all!
/Johan
#3
That way you dont have to translate the size of your graphics to world coordinates - or?
Like in the basic tutorial where you set the camera "viewport" to "0 0 100 80", and have a scenewindow of "640 480", then you have to give your the size of your sprite as: actual_pixelsize_x / 640 * 100 and actual_pixelsize_y / 480 * 80.
If you like to have a 32x32 sprite show up 1:1 at 640x480 it would then be "5 5.3" - or am I completely out of line here?
06/03/2005 (2:24 am)
Is it just me or isn't it easier to have the camera's "viewport" the same size as the scenewindow?That way you dont have to translate the size of your graphics to world coordinates - or?
Like in the basic tutorial where you set the camera "viewport" to "0 0 100 80", and have a scenewindow of "640 480", then you have to give your the size of your sprite as: actual_pixelsize_x / 640 * 100 and actual_pixelsize_y / 480 * 80.
If you like to have a 32x32 sprite show up 1:1 at 640x480 it would then be "5 5.3" - or am I completely out of line here?
#4
You can get everything working how you want by setting your camera as "400 300 800 600"
06/03/2005 (2:46 am)
It's done so it's resolution independant. You can also have multiple scenes on screen at once, which would cause you no end of problems if your scenes are different sizes. Your camera wouldn't know what to do.You can get everything working how you want by setting your camera as "400 300 800 600"
#5
06/03/2005 (3:03 am)
You also have less control than you really would want for a situation like that, once someone changes resolutions then your ratio gets blown, if someones running on a 1200 x 1600 monitor you won't want to force them to keep a windowed game to ensure pixel to pixel size... thats why T2D is set up in logical coordinates, so you get it working in that and you don't have to worry about the rest.
#6
Philip:
My sprites still show up with an offset of about -400 -300, the only change is that my scrolling tilemap background also got the same offset - strange problem or what!?
The debug-banner shows up allright, and I get a bounding box for my world's limits (my guess it is the world limit anyway) that has an offset of about -400 -300.
I have the following from my debug-banner when I use "400 300 800 600" for my camera:
X-pos: 400
Y-pos: 300
X-width: 800
Y-height: 600
X-min: 0
X-max: 800
Y-min: 0
Y-max: 600
Thanx for both your replies so far. I realise more and more how little I know about these things...:-)
06/03/2005 (3:47 am)
But even so, the ratio gets blown regardless what I use as logical coordinates once someone change the resolution. I just thought it would be easier to use a 1:1 mapping between graphic coords and the logical ones when you setup your game - once it's up and running it doesn't matter much anymore. But this is just a personal reflection and T2D is nice that in it doesn't force me (?) to this in any specific way.Philip:
My sprites still show up with an offset of about -400 -300, the only change is that my scrolling tilemap background also got the same offset - strange problem or what!?
The debug-banner shows up allright, and I get a bounding box for my world's limits (my guess it is the world limit anyway) that has an offset of about -400 -300.
I have the following from my debug-banner when I use "400 300 800 600" for my camera:
X-pos: 400
Y-pos: 300
X-width: 800
Y-height: 600
X-min: 0
X-max: 800
Y-min: 0
Y-max: 600
Thanx for both your replies so far. I realise more and more how little I know about these things...:-)
#7
The great thing here is that you can choose how you want it. We'll probably change the defaults sometime soon anyway to something more generally understood.
Use the "onExtentChange()" callback from your window to tell the camera to match the resolution. Details of this can be found in the reference doco.
With regards to this "offset" in your tile-layers, don't forget that the 'position' of every T2D object is defined by its center, not the top-left. If you position a sprite at (0,0) that is sized (50,30), the top-left will be at (-25,-15) and the bottom-right will be at (+25,+15), it's center at (0,0) as requested.
Hope this helps,
- Melv.
06/03/2005 (6:34 am)
Johan,The great thing here is that you can choose how you want it. We'll probably change the defaults sometime soon anyway to something more generally understood.
Use the "onExtentChange()" callback from your window to tell the camera to match the resolution. Details of this can be found in the reference doco.
// When the T2D window has changed...
function sceneWindow2D::onExtentChange( %this, %newExtent )
{
// Set my view to be the Screen-Resolution
sceneWindow2D.setCurrentCameraPosition( "0 0" SPC getWords(%newExtent, 2, 3) );
}If you want (0,0) at the top-left then use the alternate...// When the T2D window has changed...
function sceneWindow2D::onExtentChange( %this, %newExtent )
{
// Set my view to be the Screen-Resolution
sceneWindow2D.setCurrentCameraArea( "0 0" SPC getWords(%newExtent, 2, 3) );
}With regards to this "offset" in your tile-layers, don't forget that the 'position' of every T2D object is defined by its center, not the top-left. If you position a sprite at (0,0) that is sized (50,30), the top-left will be at (-25,-15) and the bottom-right will be at (+25,+15), it's center at (0,0) as requested.
Hope this helps,
- Melv.
#8
Just to be clear - the problem isn't that my tile-layer got the offset (only after trying the setCurrentCameraPosition Philip suggested), but that my sprites show up with the offset. It's if 0,0 in world coords is the top-left corner...and the strange thing is that this is only so at work - at home it's correct!
Anyway, I'll try some more...
06/03/2005 (7:43 am)
Thanks for your explanation Melv!Just to be clear - the problem isn't that my tile-layer got the offset (only after trying the setCurrentCameraPosition Philip suggested), but that my sprites show up with the offset. It's if 0,0 in world coords is the top-left corner...and the strange thing is that this is only so at work - at home it's correct!
Anyway, I'll try some more...
#9
Anyway, good luck.
- Melv.
06/04/2005 (7:05 am)
Very wierd indeed. If you're still struggling here, maybe you could post an image and indicat the world position/size of your object so as to show the offset.Anyway, good luck.
- Melv.
#10
For some reason it started working again (haven't changed any code related to this as far as I can see. :-)
If it'll come back, I'll see to posting a screenshot.
Thanx for a fantastic engine!
/Johan
06/12/2005 (11:55 pm)
Melv, sorry I didn't get back with an answer sooner (haven't really had time to work with this).For some reason it started working again (haven't changed any code related to this as far as I can see. :-)
If it'll come back, I'll see to posting a screenshot.
Thanx for a fantastic engine!
/Johan
#12

This is how I set up my game screen gui:
And this is how I initialize the sceneGeraph etc:
And here is how I setup worldlimits for my sprites:
I also put my sprites at "-150 0" and "150 0".
Can the problem derive from how I setup the gui-parts?
/Johan
06/13/2005 (12:25 am)
I think I celebrated too soon. See this:
This is how I set up my game screen gui:
new GuiBitmapCtrl(GameScreen) {
profile = "GuiDefaultProfile";
horizSizing = "width";
vertSizing = "height";
position = "0 0";
extent = "800 600";
minExtent = "800 600";
visible = "1";
wrap = "1";
bitmap = "~/client/images/gui/bg_black";
new fxSceneWindow2D(SceneWindow) {
profile = "GuiContentProfile";
horizSizing = "width";
vertSizing = "height";
position = "0 0";
extent = "800 600";
minExtent = "800 600";
visible = "1";
lockMouse = "0";
};
};And this is how I initialize the sceneGeraph etc:
// Setup 2d graphics
new fxSceneGraph2D(sceneGraph);
SceneWindow.setSceneGraph(sceneGraph);
SceneWindow.setCurrentCameraPosition("0 0 800 600");And here is how I setup worldlimits for my sprites:
%player.ship.setWorldLimit(CLAMP, "-400 -300 400 300");
I also put my sprites at "-150 0" and "150 0".
Can the problem derive from how I setup the gui-parts?
/Johan
#13
- Melv.
06/13/2005 (3:17 am)
Could you tell me what I'm looking at on the screen? I'd rather not make assumptions here. Could you just show the sprite (sprites?) ? How many scenegraphs are being view (just one)? Is the white rectangle a world limit for a sprite?- Melv.
#14
The black numbers on white background to the left is my auto panning tilemap. It's positioned "-400 -300" and shows up where I expect it to.
At the top left corner you get a glimpse of one of my two sprites - this one is positioned at "150 0" and doesn't show up where I excpect it to.
I guess the white rectangle is the world limit for my two sprites, and it is set to "-400 -300 400 300", and it looks both smaller and offset too.
Is there anything else I can tell you to help understand my problem?
Best regards,
Johan
06/13/2005 (4:17 am)
You mean it's not obvious!? *smile*The black numbers on white background to the left is my auto panning tilemap. It's positioned "-400 -300" and shows up where I expect it to.
At the top left corner you get a glimpse of one of my two sprites - this one is positioned at "150 0" and doesn't show up where I excpect it to.
I guess the white rectangle is the world limit for my two sprites, and it is set to "-400 -300 400 300", and it looks both smaller and offset too.
Is there anything else I can tell you to help understand my problem?
Best regards,
Johan
#15
If you had setup the gui window incorrectly then you'd see this with the debug-info banner as it only renders to the window and it looks aligned perfectly.
The camera is setup to look at (0,0) and the width is (800,600) so that's fine. Presumably you're saying that a sprite @ (0,0) would have its lower-right visible at the top-left of the window?
Ignoring the tile-layer, I'd be interested in know which sprite is showing here. It'd be interesting to see a sprite @ (0,0) and a different sprite (identifiable) at something (400,300). Perhaps both sprites with a different world limit.
It'd be nice to see all the code here (just creating two sprites). From the fragments of code though, I can't see anything obvious and this is definately the first time I've ever seen this effect. Which OS is this under?
Sorry I can't come up with a solution but this is one of the strangest problems I've seen so far, particularly as you say it comes and goes! Presumably you've got no log errors?
- Melv.
06/13/2005 (5:15 am)
Well, I just didn't want to assume anything. ;)If you had setup the gui window incorrectly then you'd see this with the debug-info banner as it only renders to the window and it looks aligned perfectly.
The camera is setup to look at (0,0) and the width is (800,600) so that's fine. Presumably you're saying that a sprite @ (0,0) would have its lower-right visible at the top-left of the window?
Ignoring the tile-layer, I'd be interested in know which sprite is showing here. It'd be interesting to see a sprite @ (0,0) and a different sprite (identifiable) at something (400,300). Perhaps both sprites with a different world limit.
It'd be nice to see all the code here (just creating two sprites). From the fragments of code though, I can't see anything obvious and this is definately the first time I've ever seen this effect. Which OS is this under?
Sorry I can't come up with a solution but this is one of the strangest problems I've seen so far, particularly as you say it comes and goes! Presumably you've got no log errors?
- Melv.
#16
I have wrapped the tile map handling within a custom level class:
06/13/2005 (5:43 am)
Quote:Yes.
Presumably you're saying that a sprite @ (0,0) would have its lower-right visible at the top-left of the window?
Quote:As I removed my tile-map to prepare a new screnshot everything showed up nice and dandy (this must be why it seemed to work before - I did som major changes to my tilemap). I tried putting the tilemap back and the artifact was back!
Ignoring the tile-layer, I'd be interested in know which sprite is showing here. It'd be interesting to see a sprite @ (0,0) and a different sprite (identifiable) at something (400,300). Perhaps both sprites with a different world limit.
I have wrapped the tile map handling within a custom level class:
// --------------------------------------------------------------------
// Level
// --------------------------------------------------------------------
function Level::Create(%themePath)
{
%this = new ScriptObject()
{
class = "Level";
};
%this.themePath = %themePath;
%this.map = new fxTileMap2D()
{
scenegraph = sceneGraph;
};
%this.layer = %this.map.createTileLayer("1 1 1 1");
%this.map.setVisible(false);
%this.blockCount = 0;
%this.themeBlockMapCount = 0;
return %this;
}
function Level::AddThemeBlockMap(%this, %name, %fileName)
{
%this.themeBlockMaps[%name] = Level::_LoadThemeMap(%this.themePath @ %fileName);
%this.themeBlockMapsIndex[%this.themeBlockMapCount] = %name;
%this.themeBlockMapCount++;
}
function Level::_FreeResources(%this)
{
// safeDelete all themeBlockMaps...
for(%i = 0; %i < %this.themeBlockMapCount; %i++)
{
%this.themeBlockMaps[%this.themeBlockMapsIndex[%i]].safeDelete();
}
%this.themeBlockMapCount = 0;
}
function Level::AddBlock(%this, %blockType)
{
%blockMap = %this.themeBlockMaps[%blockType];
%layerIndex = mFloor(getRandom() * %blockMap.getTileLayerCount());
%this.blocks[%this.blockCount] = %blockMap.getTileLayer(%layerIndex);
%this.blockCount++;
}
function Level::Finalize(%this)
{
// get width of level layer
%width = getWord(%this.blocks[0].getTileCount(), 0);
// calc height of level layer
%height = 0;
for(%i = 0; %i < %this.blockCount; %i++)
{
%height += getWord(%this.blocks[%i].getTileCount(), 1);
}
// resize output layer
%this.layer.resizeLayer(%width SPC %height);
%this.layer.setTileSize(%this.blocks[0].getTileSize());
// copy all layer tiles
%layerHeightOffset = 0;
for(%i = 0; %i < %this.blockCount; %i++)
{
%block = %this.blocks[%i];
%height = getWord(%block.getTileCount(), 1);
for(%y = 0; %y < %height; %y++)
{
for(%x = 0; %x < %width; %x++)
{
Layer::_CopyTile(%block, %x SPC %y, %this.layer, %x SPC (%layerHeightOffset + %y));
}
}
%layerHeightOffset += %height;
}
%this._FreeResources();
%this.map.setVisible(true);
// resize display of output layer
%tileSize = %this.layer.getTileSize();
%tileCount = %this.layer.getTileCount();
%this.layer.setSize(getWord(%tileCount, 0) * getWord(%tileSize, 0) SPC getWord(%tileCount, 1) * getWord(%tileSize, 1));
%this.layer.setPosition("-400 -300");
}
#17
The level class is used as this:
Oh, and my OS is Windows XP SP2.
06/13/2005 (5:44 am)
Continued...function Layer::_CopyTile(%srcLayer, %srcTile, %dstLayer, %dstTile)
{
// type
%type = %srcLayer.getTileType(%srcTile);
switch$(getWord(%type, 0))
{
case "static":
%dstLayer.setStaticTile(%dstTile, getWord(%type, 1), getWord(%type, 2));
case "animated":
%dstLayer.setAnimationTile(%dstTile, getWord(%type, 1));
case "active":
%dstLayer.setActiveTile(%dstTile, getWord(%type, 1), getWord(%type, 2));
}
// do we really have a tile??
if(%type !$= "")
{
// flip
%flip = %srcLayer.getTileFlip(%srcTile);
%dstLayer.setTileFlip(%dstTile, getWord(%flip, 0), getWord(%flip, 1));
// custom data
%dstLayer.setTileCustomData(%dstTile, %srcLayer.getTileCustomData(%srcTile));
// script
%dstLayer.setTileScript(%dstTile, getWord(%srcLayer.getTileScript(%srcTile), 0));
// collision
%collision = %srcLayer.getTileCollision(%srcTile);
%dstLayer.setTileCollisionActive(%dstTile, getWord(%collision, 0));
%dstLayer.setTileCollisionScale(%dstTile, getWords(%collision, 1, 2));
%dstLayer.setTileCollisionPolyCustom(%dstTile, getWord(%collision, 3), getWords(%collision, 4, getWordCount(%collision) - 1));
}
}
function Level::Scroll(%this, %speed)
{
%this.layer.setAutoPan(0 SPC -%speed);
}
function Level::_LoadThemeMap(%mapName)
{
%map = new fxTileMap2D()
{
scenegraph = sceneGraph;
};
%map.loadTileMap(%mapName);
%map.setVisible(false);
return %map;
}It goes without saying that this is a _very_ early stage of development of my game, and that the level class is far from finished - so it's not that well commented or anything....but I didn't expect it to break everything like that.. :(The level class is used as this:
%level = Level::Create("~/client/blocks/");
%level.AddThemeBlockMap("test", "test.map");
%level.AddBlock("test");
%level.AddBlock("test");
%level.AddBlock("test");
%level.AddBlock("test");
%level.AddBlock("test");
%level.Finalize();
%level.Scroll(100);Oh, and my OS is Windows XP SP2.
#18
It's hard to see how any amount of tile-map work can affect other sprites. That is very strange indeed!
- Melv.
06/13/2005 (6:23 am)
To be brutal, I haven't really got the time to go through lots of code so here's the short question; are you saying that with some portion of this code omitted, your sprites (presumably setup elsewhere) appear in a different position? What portion of the code do you need to omit to get this effect? Just the calls to your new functions as in the last code block? Could you show the sprite setup code as well?It's hard to see how any amount of tile-map work can affect other sprites. That is very strange indeed!
- Melv.
#19
But anyway, if I leave out:
I'll see if I can recreate this with a simpler setup and if I do I'll file bugreport with a complete step-by-step guide for how to get to help you solve it. In the meantime - don't give this too much of your precious t2d-time! :-)
Best regards,
Johan
06/13/2005 (6:36 am)
I fully understand you having lots to do - I really hate taking up your time with something that I suspect eventually will have a simple solution.But anyway, if I leave out:
%level = Level::Create("~/client/blocks/");
%level.AddThemeBlockMap("test", "test.map");
%level.AddBlock("test");
%level.AddBlock("test");
%level.AddBlock("test");
%level.AddBlock("test");
%level.AddBlock("test");
%level.Finalize();
%level.Scroll(100);Which is where I build my tilemap - everything works as expected. I have no errors in my logfile either. I'll try this at home as well and see if the same error is still there as well (before it didn't - but I'll have to try again just to be sure).I'll see if I can recreate this with a simpler setup and if I do I'll file bugreport with a complete step-by-step guide for how to get to help you solve it. In the meantime - don't give this too much of your precious t2d-time! :-)
Best regards,
Johan
#20
06/13/2005 (8:17 am)
......
Torque Owner Philip Mansfield
Default Studio Name
With a cam setup as you have described, the top left of your view port is -400, -300 the centre is 0,0 and the bottom right is 400,300.