Game Development Community

X,y coordinates (Beginner question)

by William Urban · in Torque Game Builder · 04/13/2007 (8:11 am) · 12 replies

I know this is going to sound beginner but I just can't wrap my head around how torque does 2d x,y coordinates. I have used other systems and say the upper left corner is x=0 and y=0 and x positive goes right and y positive goes down. I have used some which are more like math class with the bottom left is x=0 and y=0 and positive x is to the right and positive y is up. What I can't seem to get my head around is how torque uses this? Does the camera depict what the coordinate is based on 0,0 being the origin? What if my level is really long to the left or right. Is it starting position that matters? I guess that's what I'm having the hardest time with. If my level is just the screen and never moves where is 0,0. If my level is a huge sprawling top down city where is 0,0 and does it depend on the camera?

Thanks for anyone who can clear this up and I realize it will probably an oh duh moment when I grasp it.

Thanks,

-Will

#1
04/13/2007 (8:53 am)
William,

Torque uses a center based zero system, so the center of the scenegraph is 0,0 -- it also uses a relative positioning system, so that it can be resolution agnostic ...

There are a few settings that accomplish this, the Screen Resolution can be set to 800x600 for example, while the Scene Window Size is set to something like 100x75 ... this will cause your screen to have 100 units in width, but these units are decimal based ... now, the good thing about this is, if you change your resolution to 1280x1024 ... the units still equate to the same location on the screen ...

When designing a level, you can do a number of things, code the starting position in your init scripts to move the camera view, or move all the objects in your level so that the position you wish to start is centered in the scene outline in level builder -- I personally, for larger levels ... like to use a 'starting position object' ... and I just have an 'onLevelLoaded move camera to startObject' snippet I run ...

Does that help clarify things?
#2
04/13/2007 (9:10 am)
Yes a bit thank you. Hard switching my brain to think like that though. I guess i'm still thinking of it in terms of finding the x,y and scaling it by the sprite x32 etc to find a grid point in an array. I need to get out of that mentality and use the tools that it provides :) I'm still just playing around with the demos but that always confused me hehe.

Thanks,

-Will
#3
04/13/2007 (9:13 am)
So just to clarify. If I want a true WYSIWYG on my level designer I should set the camera to 1024x768 and the design resolution to 1024x768 and that will let me say with certainty that if I spawn something at 512x and 384y it will be in the top upper right pixel?

Thanks,

-Will
#4
04/13/2007 (11:50 am)
William,

Setting Design and Scene sizes to the same thing makes your relative coordinates become pixel coordinates, but the 0,0 offset is still center ... so for 800x600 ... the 0,0 is 399,299 (0,0 + (800,600 / 2,2)) ... if that makes sense ...

If you want to find the top-right corner of an object, you have to do something like:

object.position.x - (object.width / 2) == object.top.position

obviously, those are 'faked' values ...

The real code would look something more like this:
%objTopLeft = %obj.getPositionX() - (%obj.getSizeX() / 2);



If you wanted to place a number of sprites on the screen, side by side ... you would do:

%lp = object.getPosition();
for(%x = 0; %x < 5; %x++)
{
  %obj = object.clone(true); // create a clone, with fields
  %obj.setPosition(t2dVectorAdd(%lp, %obj.getSize()); // place the object to the bottom right
  %obj.setPosition(t2dVectorAdd(%lp, "0 " @ %obj.getSizeX()); // place the object directly to the right
}

The above code works, because using 0,0 as the center or the top-left, the math is still the same ... your still placing the image One Image Width to the Right of the Last Image ... where the 0,0 of the image is in this decision is fairly irrelevant ... so long as both images use the same 0,0 position ....

Etc, etc, etc ... it's just a matter of reorienting where your center offset is ... from there, all the math is still the same ... this function can convert relative center values to relative top-left values

function getObjectTopLeft(%obj)
{
  return %obj.getPositionX() - (%obj.getSizeX() / 2); 
}

So you could use the above 'getObjectTopLeft' function to give you the relative topleft position of the object ... if you require the calculation in numerous locations ... though, I think it best to just reorient where your center position is mentally ... unless you require for game play to know the top-left of the object ...


Oh and ... just because making things more entertaining is what TorqueScript is all about ... GUI Objects use the Top-Left screen as the 0,0 and all positioning is based on a Top-Left 0,0 system ... why? I'm not quite sure ... it just is ...

Why does TGB use screen center as 0,0? Because it's 2D in a 3D World ... so the camera is just a view in OpenGL (correct term?) and the center of this view is your actual 'center point' ... when you draw sprites to the screen, your actually creating Flat 3D Surfaces which are being rendered to the screen ... and those surfaces all, by default, use a center 0,0,0 ... yes, three axis's in 3D ... TGB only allows access to modify 2 of them though ...

K, I think I'm done making things more complicated ... ;)
#5
04/23/2007 (10:58 am)
You can always change the origin so it matches the more common "0,0 is the top left corner of the screen". This is useful also because, like David pointed out, the GUI coordinate system works this way.

Let's say you're working with a screen resolution of 800x600. If you write the following code, it will place the camera on the center of the screen and match it with the screen resolution. This way, 0,0 will be the top left pixel and 799, 599 the bottom right.

%yourSceneWindow.setCurrentCameraPosition(400, 300, 800, 600);
#6
04/23/2007 (10:27 pm)
Nicolas is right. His line of code won't work, however, unless you do something like this:
%yourSceneWindow = sceneWindow2D;
SceneWindows are incredibly important. My understanding is that you have the Canvas to which GUI objects are drawn. The t2dSceneWindow is actually a GUI element that is capable of displaying t2dSceneGraph objects. By default, these are given human readable names (unique identifiers that don't require "%" [local] or "$" [global] characters in script) on creation (you can do this kind of object naming with any object, actually). Take a look at your projectDir/game/gui/mainScreen.gui file. The line
new t2dSceneWindow(sceneWindow2D) {
creates a new t2dSceneWindow named "sceneWindow2D" with all of the pertinent variables set in the following code block.

Camera functions are called on the t2dSceneWindow objects (afterall, the it's the t2dSceneWindow's camera that's actually looking at a t2dSceneGraph). Therefore, if you haven't made any changes to your default t2dSceneWindow's name, you can accomplish the change Nicolas mentioned with this one line of code:
sceneWindow2D.setCurrentCameraPosition(400, 300, 800, 600);
#7
04/23/2007 (10:32 pm)
Nicolas is right. His line of code won't work, however, unless you do something like this:
%yourSceneWindow = sceneWindow2D;
SceneWindows are incredibly important. My understanding is that you have the Canvas to which GUI objects are drawn. The t2dSceneWindow is actually a GUI element that is capable of displaying t2dSceneGraph objects. These are given human readable names (unique identifiers that don't require "%" [local] or "$" [global] characters in script) on creation. Take a look at your projectDir/game/gui/mainScreen.gui file. The line
new t2dSceneWindow(sceneWindow2D) {
creates a new t2dSceneWindow named "sceneWindow2D" with all of the pertinent variables set in the following code block.

Camera functions are called on the t2dSceneWindow objects (afterall, the it's the t2dSceneWindow's camera that's actually looking at a t2dSceneGraph). Therefore, if you haven't made any changes to your default t2dSceneWindow's name, you can accomplish the change Nicolas mentioned with this one line of code:
sceneWindow2D.setCurrentCameraPosition(400, 300, 800, 600);
#8
04/24/2007 (7:11 am)
I've not seen any reason why not to do this, but I've read quite a few threads that discussed setting the camera size to the resolution is a bad thing, and is 'taboo' ... again, not sure why ... I myself do it when I'm prototyping things ... makes for figuring things out easier ...

just good to note that it's been discussed ...


#9
04/24/2007 (8:43 am)
The individual acts themselves aren't "taboo" or even a problem--what people are suggesting (myself as well) is that if you as a developer tie your game to one resolution (which is what you are doing when you try to turn world units into pixels by setting camera size, etc), then you are severely limiting yourself, and especially your game's cross-platform capability.

Let's hypothesize for a moment, and say that you spend 6 months using the technique of "everything is aligned by pixels", and your entire game implementation is written around that. Now, let's say the game releases, and it's the next Geometry Wars, and MS, Sony, and Nintendo all want you to port to their consoles.

You also get cell phone offers, etc, etc...but, you're game only works in 800x600, because you focused on pixel and resolution matching instead of staying "loose" with the resolution flexibility--now you have to re-implement your entire game, and possibly redesign the entire environment to move to different platforms.
#10
04/24/2007 (8:51 am)
Stephen, that example is both good, and bad ... TGB doesn't port to those platforms, so you'd have to rewrite your entire game to support those platforms anyhow ... with the exception of the Xbox, but you'd still have to rewrite the game (I don't think TorqueX supports TorqueScript, and I know it doesn't support any C++ modifications) ...

But yeah ... I can sort of see restricting the game to a specific resolution ... maybe a better example might be this ...

Your target resolution is 1024x768, or higher ... but some of your players can't run at that resolution (monitor limitations, video card limitation, etc) ... now they can't run your game ... cause you can't downsize to 800x600 for them ... 1024x768 would be optimal for display ... but 800x600 or even 640x480 should still be supported ...

doing so, also allows you to have a Windowed and Fullscreen mode for your game ... cause, I personally hate when games don't offer that feature ... I like to play casual games in a window, so I can still do other things ... like chat with friends, read web news, etc ...
#11
04/24/2007 (3:35 pm)
@David:

Who says TGB doesn't port to those platforms? Ok, I'll give you the Wii, but TGB and TGE-A use the exact same underlying technology (there are rendering changes to be sure) and TGE-A has a 360 license.

In any case, the concept here is that TGB intentionally abstracts you away from the specifics of the drawing device (pixel focus), and instead gives you an abstracted system of world coordinates for a very good reason...instead of attempting to over-ride that reason, you should work with it instead :)
#12
04/24/2007 (3:56 pm)
Stephen, ok ... ok ... you got me there ... technically it can port to those platforms, given the right tender loving care (less love involved in a 360 port, obviously) ...

But ... who wants to waste money porting to those platforms when they can just get TGB to work in Linux and distribute for the GP2X? :)

haha -- all seriousness though ... I didn't mean "doesn't port" in an absolute form, more of a "generic" ... out of the box, it's a far leap to get to any of those platforms (minus 360) ...

And I did agree with the relative sizing thing being the better option, for the portability reasons alone ... it's totally worth it ...

Although ... if your camera size is 100/75 or 200/150 ... and you have specific camera locations that you move objects too ... such as 'moveTo(75, -45);' ... and you change your screen resolution ... isn't this supposed to technically move everything to the same place. .. regardless of screen resolution? So if you used 800x600 ... relative sizing would still occur ... the camera size is set to 800x600 as opposed to 200x150 ... so your coordinates are based on the absolute size of the image ... however, the absolute size of the image and the actual screen resolution would size accordingly ... due to the relative sizing code for the scene window ... no?

So if I have an absolute image size of 800x600 ... and I tell a sprite thats 100x100 to move to 200x200 ... and I change my game resolution to 320x240 ... wouldn't everything scale ... and my screen coordinates would still be the same (200x200 would be the same place on the screen for 800x600 resolution and 320x240 resolution)

(fyi, that was a thought that just crossed my mind as I was writing the first half of this post ;p)


oh and ... don't quote me on any of this ... haha, these are all assumptions I run on given my current knowledge ... if you know more, do tell ;p