Get World Position of a Tile, opposite of pickTile()
by David Higgins · in Torque Game Builder · 02/12/2007 (6:09 pm) · 2 replies
Ok -- I didn't exactly have a need for this code, but I was recently working with a tile layer and using pickTile() to retrieve tile's based on the %worldPosition of a mouse-click ... I was thinking on my way home from work and realized, there was no "get world position of tile" function that mirrored pickTile ... so I wrote one in TorqueScript ...
This is more or less for the n00b's... shows some fairly basic math calc's that can be used to determine position of things, this function is specific to the t2dTileLayer ... but the math used can be re-used in many other concepts ...
This is more or less for the n00b's... shows some fairly basic math calc's that can be used to determine position of things, this function is specific to the t2dTileLayer ... but the math used can be re-used in many other concepts ...
function t2dTileLayer::getTileWorldPosition(%this, %tileXPosition, %tileYPosition)
{
// determine if we were passed a word-list or x/y coords
if(getWordCount(%tileXPosition) > 1)
{
%tilex = getWord(%tileXPosition, 0);
%tiley = getWord(%tileXPosition, 1);
}
else
{
%tilex = %tileXPosition;
%tiley = %tileYPosition;
}
// %buff just stores stuff real quick -- I like 'getSize' over 'getSizeX', personal preference
%buff = %this.getTileSize();
%tsx = getWord(%buff, 0);
%tsy = getWord(%buff, 1);
%buff = %this.getTileCount();
%tcx = getWord(%buff, 0);
%tcy = getWord(%buff, 1);
%p = %this.getPosition();
%px = getWord(%p, 0);
%py = getWord(%p, 1);
// get the top-left
%tlx = -(((%tcx * %tsx) / 2) + (%tsx / 2));
%tly = -(((%tcy * %tsy) / 2) + (%tsy / 2));
// determine tile world position
%wx = %px + (%tlx + (%tsx * (%tilex++)));
%wy = %py + (%tly + (%tsy * (%tiley++)));
return %wx SPC %wy;
}About the author
#2
But yeah, if you want to help out, and can't think of a way ... surfing the forums and converting useful examples into TDN Articles is a great way for a n00b or non-programmer to 'give back' to the community, and I, along with many others, would greatly appreciate it.
02/12/2007 (6:12 pm)
BTW -- If anyone would like to convert any of my 'examples' (be they from my .plans or forum posts) into TDN Articles -- PLEASE do so, and let me know that they've been created -- I find it fairly quick to write up .plan's and forum posts with GG codes (code, b, i, etc) but writing TDN Articles drives me absolutely bonkers ... there's just too much for me to remember when I'm writing them and then going back and making sure the article is linked from somewhere on top of that ... bleh ... not much of a wiki person, I tried writing a few TDN articles ... and just gave up ...But yeah, if you want to help out, and can't think of a way ... surfing the forums and converting useful examples into TDN Articles is a great way for a n00b or non-programmer to 'give back' to the community, and I, along with many others, would greatly appreciate it.
Associate David Higgins
DPHCoders.com
Ok -- first, we check to see if the parameters passed to the function were x/y coordinates, or a world-list -- %worldPosition in a mouse callback is a 'word list' ("X Y") [also known as a vector, but I call them word-lists since you use 'getWord' to retrieve the values)
If %tileXPosition is a 'vector'/'word-list', we split it up ... otherwise, we set the %tilex/%tiley variables according to the parameters passed -- why not just change the value of the parameters in-line? Well, I tried that, heh ... didn't work ... I was able to change the value of %tileXPosition but I'm thinking that since %tileYPosition was not passed, theres no memory held for it, and therefore it could not be set ... *shrug* -- things you learn, eh?
Next, I grab a few values that we'll need in the calculation -- I could have over-complicated the entire process and just made one HUGE one-liner ... BUT, I figured I'd go for code readability ... ;)
After we retrieve all the values we need, we then have to do some math ... and I'll explain that now ...
If we have a Tile Layer with a size of 50,50 ... and it has 10 tile rows and 10 tile columns, and each tile is sized at 5,5 -- we do the following:
First, we need to find the top-left of the tile-layer, we do this by grabbing it's "Top-Left X" and "Top-Left Y" coordinates, here's the top-left-x coordinate algorithm:
If we break this down, we are multiplying the number of X tiles by the X size of the tiles -- given the above mentioned values, we would have 10 * 5, which is 50, we then divide this by 2 ... and get 25 -- then, we take the tile X size (5) and divide it by 2, and get 2.5, then add that to the previous calculation.
Now we have 27.5 -- hrm ... ok, 25 is basically the 'center' of the X axis ... adding 2.5 to it makes sure that were in the center of a 'tile' (in this case, the center of the 6th row on the X axis) ... now, wait ... are you wondering what that funky -() that surrounds the entire equation is for? Heh ... well, if you guessed it's used to negate the value of the wrapped algorithm, your right ... if not, well, now you know ...
Why do we negate the value? Simple. TGB uses a 'center of object' 'zero' point -- so the center of the tile-layer (0,0) is actually in the middle of it -- if we made the value position, it would go down ... not up ... we want to go up, so we negate it's value.
We do the same for the Y axis ... and we get the relative world-position of the 0,0 tile (currently, our reference is only 'relative' because its basing itself off the center of the world)
Now, we take the current world position of the tile layer itself, and determine the absolute position, here's the code for that again:
%wx will eventually store the X position of the tile in world coordinates, we do this by taking the current X position of the entire tile layer (%px) and adding to it a small algorithm ... that algorithm does the following;
We take the tile you requested, let's say you asked for tile 0,0 (top-left tile) ... and we add 1 to it (%tilex++ -- simply increments %tilex by 1, and we use the resulting value -- its shortcut code)
We then multiply the size of the tile on it's X axis by the tile your asking for, in this case, were doing 5 * 1
We then add the value we previously calculated (the relative 'top-left') to this, and now we have a 'relative' tile position ... but were still 'relative' ... so we then add the current tile layers 'x position' (%px) to this.
Now ... if it looked like i went 'backwards' in that explaination, it's because of math precedence ... though the algorithm puts the 'tile layer x position' first, the way the algorithm is performed is based on math precedence ... which is forced by the use of the () but is not all of them are necessarily needed ... as the operators take precedence as well (just like in School, wee!)
Hope this finds itself as a useful example ... feel free to ask questions if you have any ...