T2D Tutorial moveTo
by Matthew Langley · 04/17/2005 (7:37 pm) · 18 comments
T2D Tutorial moveTo - Creating a moveTo Function
Ok, well so far I've covered a starter gui, modifying the physics, dynamic creation of sprites, a lot of gui stuff, selecting an object (simple and complex), as well as a way to keep usefull debug info...
Well that leaves one very important thing for a game open, moving a character/sprite... Well this seems simple at first, but then you realize to move an object to a specific spot is harder than anticipated... you have to find some way to check if it has reached that spot so you can stop it!
Well this tutorial will teach you how to do that :)
ok to start this tutorial create a new .cs file under the same folder as your "client.cs"... call this "moveTo.cs"...
in there lets first create a function to start this up, to test moving we first need an object to move...
create this function
this will create a simple box on the center of our screen, lets test it out... so first save this file... then open up your client.cs and find the end of your exec statements... like exec("./mainScreenGui.gui"); after all the present ones add this
note if you went through my last set of tutorials (object selection) you've already done this, no need to repeat...
now create a new .cs file in the same folder as your "client.cs" and put this in it
this will make it easy to add new exec statements :)
now create another .cs file in the same folder as your "client.cs" and call it "onStartUp.cs"... in there create a function called onStartUp() ... so this new file should contain
now go back to your client.cs and look for
after this add this line
now save your client.cs and close it, this way we don't have to keep searching for that same spot to include exec statements and choose what we want it to do on start up :) Seperating files like this not only makes it easier to modify and add new things, it also helps in basic debugging, for two reasons... one is the obvious, that since files are seperated its easier to sift through them, the other is the fact that when a syntax error is found, that whole file isn't compiled and a previous version is used, this way its more seperated and if this happens it is more modular... also creating things modular like this increases re-usability... and that means saved time.
ok, now save all your files and fire up T2D... you should see something like this

if it doesnt then compare your files to this...
in your client.cs you should have a line that says
exec("./exec.cs");
and further down
onStartUp();
your exec.cs file should look like this
your onStartUp.cs file should look like this
and your moveTo.cs file should look like this
Ok now everything should work fine, we got a box in the middle of the screen...
lets start with our first function
we'll attach it to fxSceneObject2D so all objects inherit this... so later we can simply do $player.moveToDestination();
since its in a namespace "::"... %this will automatically be the object thats calling this function and %dest will be what we pass... like this
$player.setDestination("5 5");
... ok lets add the inner workings of it
ok first we have
if((%dest != 0) && (%dest !$= ""))
this ensures the destination we pass isnt equal to 0 or an empty string, that way we can try and avoid setting an invalid destination
...
then we set the
storing the Destination inside of the object, that way each object has its own destination
we set
so later we can tell if we want to check if its reached its destination
here we have a simple debug statement (most of you should be used to my debug statements by now lol)
then we have a schedule... now whats handy about a schedule is we can tell it to perform a function at a specified time... here we tell it to run its own moveToDest in 50 miliseconds (1/20 th of a second)... the reason i chose such a quick number is to ensure little delay between setting it and performing it... nothing like clicking then getting a small delay before your unit moves... (unless of course you want that, then you would change this number)
ok now lets test this... save the file and fire up T2D... now theres two ways to test this, we'll try both... first run this command in the console (you can bring up the console by pressing the "~" tilde key)...
$debugMsg::pathDebug = true;
like this

and press enter
now type this in the console
$player.setDestination("15 15");
press enter and you should see something like this

if not, compare your moveTo.cs code to this
ok so this is the first way to check, the second way is quite handy also... its something to keep in mind... every object has a .dump() function to it... that way you can dump all the varariables and functions of that object... its quite handy
now type this in the console
$player.dump();
you should see something like this

scroll up a little until you see this

here you can see the destination variable that we set using our setDestination() function...
ok moving on... before we create "moveToDest" I'm going to give you a helper function that will be used in it... this function will return the angle between the two points passed to it... add it to the end of your file
so now we need to create a "moveToDest" function... here it is
ok first thing we check is this
we want to ensure that its still moving, just incase it has been changed within the time of scheduling this function...
here we get the direction we want to face
now we store the new direction in a variable, that way if we need to compare where it was originally needing to face we can
then we set the new rotation (note this will abruptly change the rotation and may slip collision and physics if doing this at high speeds... for our demo nothing to worry about, you can set this to set angular velocity until it reaches this rotation though thats for another tutorial ;)
now we send it moving in that direction at its speed (speed is a variable that we will need to set)
and at the end we schedule the checkDest function... thats the function that will constantly check if its reached its destination... note since these are all attached to fxSceneObject2D and namespaced... they use the %this parameter to set these functions individually for each object, so we can have multiple objects perform these actions without interfering with eachother.
ok lets fire T2D up and lets test this!
bring up the console and put these commands
$player.speed = 10;
$player.setDestination("15 15");
bring the console down and watch the box move! but wait... lol it doesnt stop!!!
should look like this

if yours doesnt work like this then compare your code to this
ok... now it didn't stop, though this makes sense, considering we don't have a checkDest function... so lets create one!
first I'm going to give you another helper function... this one you pass it two points and it gives you the distance between them
on to checkDest
ok, I'll break it down then show you the whole function
first we start with this
nothing special here, just creating the function and we check if its moving
now lets add
here we first specify a %space... this will be how close we will require the object to need to be before we will consider it "reaching" its destination (this prevents the object from bobbling back and forth trying to get it precise, especially at high speeds... we can easily change this value like this)
now lets start an if
we check if the distance between it and its destination is less than the space required to be between it and its destination...
if it is, we set it at rest (this stops it)
we set .isMoving to false, that way it doesn't check anymore
then I have a callback here... this is just for consitancy, later when you want it to do something when it reaches a point you will make the "fxSceneObject2D::onReachDestination()" function...
ok now lets handle the else (and add the ending brackets for the whole function)
ok, if it hasn't reached destination we get the direction it should be facing to get to its destination... and then we compare it to what it was set at with
if(%direc != %this.destRot)
if its different we set the direction to the new one, rotate it, and set the proper velocity with
%this.destRot = %direc;
%this.setRotation(%direc);
%this.setLinearVelocityPolar(%direc, %this.speed);
ok... you might be asking why?... this seems a littl redundant... however what this does is ensure the object is on the right path... that way if it gets moved while trying to reach the destination it will turn to the proper direction again... (this can be checked if you've gone through the object selection and moving tutorial... later try setting a path and moving it, it will adjust itself properly... nifty :)
ok we end this with
%this.schedule(100, checkDest);
that way if it hasn't reached it will keep checking... your whole function should look like this
ok time to test this... lets fire up T2D
bring up the console and lets try this again
$player.speed = 10;
$player.setDestination("15 15");
and your box should move and stop at the proper destination!!!
like this

if yours doesnt work compare it to this
ok... now everything works... except you might be asking... the tutorial was entitled "creating a moveTo Function" except we don't have a move to function lol... ok ok... so lets add one, this will simplify another step also
add this to the end of your file
now we can call
$player.moveTo("15 15", 10);
and we don't need to set speed anymore !
save it and test it out
you should get something like this

ok... now lets add one more thing before we finish, just to round it out...
now save... and fire up T2D and right click where you want to move... like this

if yours doesnt work compare it to this
ok now we can right click and move the player (or well the box in this case lol)... we got basic movement! Something similar to this is what I used in my GID... its a great starting point...
well hope you learned something and enjoyed!
- Matthew "King BoB" Langley
Ok, well so far I've covered a starter gui, modifying the physics, dynamic creation of sprites, a lot of gui stuff, selecting an object (simple and complex), as well as a way to keep usefull debug info...
Well that leaves one very important thing for a game open, moving a character/sprite... Well this seems simple at first, but then you realize to move an object to a specific spot is harder than anticipated... you have to find some way to check if it has reached that spot so you can stop it!
Well this tutorial will teach you how to do that :)
ok to start this tutorial create a new .cs file under the same folder as your "client.cs"... call this "moveTo.cs"...
in there lets first create a function to start this up, to test moving we first need an object to move...
create this function
function moveToDemo()
{
$player = new fxStaticSprite2D() { scenegraph = t2dSceneGraph; };
$player.setPosition("0 0");
$player.setSize( "7 7" );
$player.setImageMap( tileMapImageMap );
}this will create a simple box on the center of our screen, lets test it out... so first save this file... then open up your client.cs and find the end of your exec statements... like exec("./mainScreenGui.gui"); after all the present ones add this
exec("./exec.cs");note if you went through my last set of tutorials (object selection) you've already done this, no need to repeat...
now create a new .cs file in the same folder as your "client.cs" and put this in it
exec("./moveTo.cs");
exec("./onStartUp.cs");this will make it easy to add new exec statements :)
now create another .cs file in the same folder as your "client.cs" and call it "onStartUp.cs"... in there create a function called onStartUp() ... so this new file should contain
function onStartUp()
{
moveToDemo();
}now go back to your client.cs and look for
// ************************************************************************ // // Add your custom code here...
after this add this line
onStartUp();
now save your client.cs and close it, this way we don't have to keep searching for that same spot to include exec statements and choose what we want it to do on start up :) Seperating files like this not only makes it easier to modify and add new things, it also helps in basic debugging, for two reasons... one is the obvious, that since files are seperated its easier to sift through them, the other is the fact that when a syntax error is found, that whole file isn't compiled and a previous version is used, this way its more seperated and if this happens it is more modular... also creating things modular like this increases re-usability... and that means saved time.
ok, now save all your files and fire up T2D... you should see something like this
if it doesnt then compare your files to this...
in your client.cs you should have a line that says
exec("./exec.cs");
and further down
onStartUp();
your exec.cs file should look like this
exec("./moveTo.cs");
exec("./onStartUp.cs");your onStartUp.cs file should look like this
function onStartUp()
{
moveToDemo();
}and your moveTo.cs file should look like this
function moveToDemo()
{
$player = new fxStaticSprite2D() { scenegraph = t2dSceneGraph; };
$player.setPosition("0 0");
$player.setSize( "7 7" );
$player.setImageMap( tileMapImageMap );
}Ok now everything should work fine, we got a box in the middle of the screen...
lets start with our first function
function fxSceneObject2D::setDestination(%this, %dest)
{
}we'll attach it to fxSceneObject2D so all objects inherit this... so later we can simply do $player.moveToDestination();
since its in a namespace "::"... %this will automatically be the object thats calling this function and %dest will be what we pass... like this
$player.setDestination("5 5");
... ok lets add the inner workings of it
function fxSceneObject2D::setDestination(%this, %dest)
{
if((%dest != 0) && (%dest !$= ""))
{
%this.Destination = %dest;
%this.isMoving = true;
if($debugMsg::pathDebug)
echo("calling move to dest with" SPC %dest);
%this.schedule(50,moveToDest);
}
}ok first we have
if((%dest != 0) && (%dest !$= ""))
this ensures the destination we pass isnt equal to 0 or an empty string, that way we can try and avoid setting an invalid destination
...
then we set the
%this.Destination = %dest;
storing the Destination inside of the object, that way each object has its own destination
we set
%this.isMoving = true;
so later we can tell if we want to check if its reached its destination
if($debugMsg::pathDebug)
echo("calling move to dest with" SPC %dest);
%this.schedule(50,moveToDest);here we have a simple debug statement (most of you should be used to my debug statements by now lol)
then we have a schedule... now whats handy about a schedule is we can tell it to perform a function at a specified time... here we tell it to run its own moveToDest in 50 miliseconds (1/20 th of a second)... the reason i chose such a quick number is to ensure little delay between setting it and performing it... nothing like clicking then getting a small delay before your unit moves... (unless of course you want that, then you would change this number)
ok now lets test this... save the file and fire up T2D... now theres two ways to test this, we'll try both... first run this command in the console (you can bring up the console by pressing the "~" tilde key)...
$debugMsg::pathDebug = true;
like this
and press enter
now type this in the console
$player.setDestination("15 15");
press enter and you should see something like this
if not, compare your moveTo.cs code to this
function moveToDemo()
{
$player = new fxStaticSprite2D() { scenegraph = t2dSceneGraph; };
$player.setPosition("0 0");
$player.setSize( "7 7" );
$player.setImageMap( tileMapImageMap );
}
function fxSceneObject2D::setDestination(%this, %dest)
{
if((%dest != 0) && (%dest !$= ""))
{
%this.Destination = %dest;
%this.isMoving = true;
if($debugMsg::pathDebug)
echo("calling move to dest with" SPC %dest);
%this.schedule(50,moveToDest);
}
}ok so this is the first way to check, the second way is quite handy also... its something to keep in mind... every object has a .dump() function to it... that way you can dump all the varariables and functions of that object... its quite handy
now type this in the console
$player.dump();
you should see something like this
scroll up a little until you see this
here you can see the destination variable that we set using our setDestination() function...
ok moving on... before we create "moveToDest" I'm going to give you a helper function that will be used in it... this function will return the angle between the two points passed to it... add it to the end of your file
function angleBetween(%playerPos, %mousePos)
{
// Seperate Mouse Position
%mxpos = getWord(%mousePos,0);
%mypos = getWord(%mousePos,1);
// Seperate Player Position
%px = getWord(%playerPos,0);
%py = getWord(%playerPos,1);
// Calculate Angle from player to mouse (convert to degrees).
%angle = mRadToDeg( mAtan( %mxpos-%px, %py-%mypos ) );
return %angle;
}so now we need to create a "moveToDest" function... here it is
function fxSceneObject2D::moveToDest(%this)
{
if(%this.isMoving)
{
%direc = angleBetween(%this.getPosition(), %this.Destination);
%this.destRot = %direc;
%this.setRotation(%direc);
%this.setLinearVelocityPolar(%direc, %this.speed);
%this.schedule(100, checkDest);
}
}ok first thing we check is this
if(%this.isMoving)
{we want to ensure that its still moving, just incase it has been changed within the time of scheduling this function...
here we get the direction we want to face
%direc = angleBetween(%this.getPosition(), %this.Destination);
now we store the new direction in a variable, that way if we need to compare where it was originally needing to face we can
%this.destRot = %direc;
then we set the new rotation (note this will abruptly change the rotation and may slip collision and physics if doing this at high speeds... for our demo nothing to worry about, you can set this to set angular velocity until it reaches this rotation though thats for another tutorial ;)
%this.setRotation(%direc);
now we send it moving in that direction at its speed (speed is a variable that we will need to set)
%this.setLinearVelocityPolar(%direc, %this.speed);
and at the end we schedule the checkDest function... thats the function that will constantly check if its reached its destination... note since these are all attached to fxSceneObject2D and namespaced... they use the %this parameter to set these functions individually for each object, so we can have multiple objects perform these actions without interfering with eachother.
%this.schedule(100, checkDest);
ok lets fire T2D up and lets test this!
bring up the console and put these commands
$player.speed = 10;
$player.setDestination("15 15");
bring the console down and watch the box move! but wait... lol it doesnt stop!!!
should look like this
if yours doesnt work like this then compare your code to this
function moveToDemo()
{
$player = new fxStaticSprite2D() { scenegraph = t2dSceneGraph; };
$player.setPosition("0 0");
$player.setSize( "7 7" );
$player.setImageMap( tileMapImageMap );
}
function fxSceneObject2D::setDestination(%this, %dest)
{
if((%dest != 0) && (%dest !$= ""))
{
%this.Destination = %dest;
%this.isMoving = true;
if($debugMsg::pathDebug)
echo("calling move to dest with" SPC %dest);
%this.schedule(50,moveToDest);
}
}
function angleBetween(%playerPos, %mousePos)
{
// Seperate Mouse Position
%mxpos = getWord(%mousePos,0);
%mypos = getWord(%mousePos,1);
// Seperate Player Position
%px = getWord(%playerPos,0);
%py = getWord(%playerPos,1);
// Calculate Angle from player to mouse (convert to degrees).
%angle = mRadToDeg( mAtan( %mxpos-%px, %py-%mypos ) );
return %angle;
}
function fxSceneObject2D::moveToDest(%this)
{
if(%this.isMoving)
{
%direc = angleBetween(%this.getPosition(), %this.Destination);
%this.destRot = %direc;
%this.setRotation(%direc);
%this.setLinearVelocityPolar(%direc, %this.speed);
%this.schedule(100, checkDest);
}
}ok... now it didn't stop, though this makes sense, considering we don't have a checkDest function... so lets create one!
first I'm going to give you another helper function... this one you pass it two points and it gives you the distance between them
function distBetween(%loc1, %loc2)
{
%x1 = getWord(%loc1, 0);
%y1 = getWord(%loc1, 1);
%x2 = getWord(%loc2, 0);
%y2 = getWord(%loc2, 1);
%xd = %x2 - %x1;
%yd = %y2 - %y1;
return mSqrt((mPow(%xd,2)) + (mPow(%yd,2)));
}on to checkDest
ok, I'll break it down then show you the whole function
first we start with this
function fxSceneObject2D::checkDest(%this)
{
if(%this.isMoving)
{nothing special here, just creating the function and we check if its moving
now lets add
%space = 0.5; %distance = distBetween(%this.getPosition(), %this.Destination);
here we first specify a %space... this will be how close we will require the object to need to be before we will consider it "reaching" its destination (this prevents the object from bobbling back and forth trying to get it precise, especially at high speeds... we can easily change this value like this)
now lets start an if
if(%distance < %space)
we check if the distance between it and its destination is less than the space required to be between it and its destination...
{
%this.setAtRest();
%this.isMoving = false;
%this.onReachDestination();
} elseif it is, we set it at rest (this stops it)
we set .isMoving to false, that way it doesn't check anymore
then I have a callback here... this is just for consitancy, later when you want it to do something when it reaches a point you will make the "fxSceneObject2D::onReachDestination()" function...
ok now lets handle the else (and add the ending brackets for the whole function)
{
%direc = angleBetween(%this.getPosition(), %this.Destination);
if(%direc != %this.destRot)
{
%this.destRot = %direc;
%this.setRotation(%direc);
%this.setLinearVelocityPolar(%direc, %this.speed);
}
%this.schedule(100, checkDest);
}
}
}ok, if it hasn't reached destination we get the direction it should be facing to get to its destination... and then we compare it to what it was set at with
if(%direc != %this.destRot)
if its different we set the direction to the new one, rotate it, and set the proper velocity with
%this.destRot = %direc;
%this.setRotation(%direc);
%this.setLinearVelocityPolar(%direc, %this.speed);
ok... you might be asking why?... this seems a littl redundant... however what this does is ensure the object is on the right path... that way if it gets moved while trying to reach the destination it will turn to the proper direction again... (this can be checked if you've gone through the object selection and moving tutorial... later try setting a path and moving it, it will adjust itself properly... nifty :)
ok we end this with
%this.schedule(100, checkDest);
that way if it hasn't reached it will keep checking... your whole function should look like this
function fxSceneObject2D::checkDest(%this)
{
if(%this.isMoving)
{
%space = 0.5;
%distance = distBetween(%this.getPosition(), %this.Destination);
if(%distance < %space)
{
%this.setAtRest();
%this.isMoving = false;
%this.onReachDestination();
} else
{
%direc = angleBetween(%this.getPosition(), %this.Destination);
if(%direc != %this.destRot)
{
%this.destRot = %direc;
%this.setRotation(%direc);
%this.setLinearVelocityPolar(%direc, %this.speed);
}
%this.schedule(100, checkDest);
}
}
}ok time to test this... lets fire up T2D
bring up the console and lets try this again
$player.speed = 10;
$player.setDestination("15 15");
and your box should move and stop at the proper destination!!!
like this
if yours doesnt work compare it to this
function moveToDemo()
{
$player = new fxStaticSprite2D() { scenegraph = t2dSceneGraph; };
$player.setPosition("0 0");
$player.setSize( "7 7" );
$player.setImageMap( tileMapImageMap );
}
function fxSceneObject2D::setDestination(%this, %dest)
{
if((%dest != 0) && (%dest !$= ""))
{
%this.Destination = %dest;
%this.isMoving = true;
if($debugMsg::pathDebug)
echo("calling move to dest with" SPC %dest);
%this.schedule(50,moveToDest);
}
}
function angleBetween(%playerPos, %mousePos)
{
// Seperate Mouse Position
%mxpos = getWord(%mousePos,0);
%mypos = getWord(%mousePos,1);
// Seperate Player Position
%px = getWord(%playerPos,0);
%py = getWord(%playerPos,1);
// Calculate Angle from player to mouse (convert to degrees).
%angle = mRadToDeg( mAtan( %mxpos-%px, %py-%mypos ) );
return %angle;
}
function fxSceneObject2D::moveToDest(%this)
{
if(%this.isMoving)
{
%direc = angleBetween(%this.getPosition(), %this.Destination);
%this.destRot = %direc;
%this.setRotation(%direc);
%this.setLinearVelocityPolar(%direc, %this.speed);
%this.schedule(100, checkDest);
}
}
function distBetween(%loc1, %loc2)
{
%x1 = getWord(%loc1, 0);
%y1 = getWord(%loc1, 1);
%x2 = getWord(%loc2, 0);
%y2 = getWord(%loc2, 1);
%xd = %x2 - %x1;
%yd = %y2 - %y1;
return mSqrt((mPow(%xd,2)) + (mPow(%yd,2)));
}
function fxSceneObject2D::checkDest(%this)
{
if(%this.isMoving)
{
%space = 0.5;
%distance = distBetween(%this.getPosition(), %this.Destination);
if(%distance < %space)
{
%this.setAtRest();
%this.isMoving = false;
%this.onReachDestination();
} else
{
%direc = angleBetween(%this.getPosition(), %this.Destination);
if(%direc != %this.destRot)
{
%this.destRot = %direc;
%this.setRotation(%direc);
%this.setLinearVelocityPolar(%direc, %this.speed);
}
%this.schedule(100, checkDest);
}
}
}ok... now everything works... except you might be asking... the tutorial was entitled "creating a moveTo Function" except we don't have a move to function lol... ok ok... so lets add one, this will simplify another step also
add this to the end of your file
function fxSceneObject2D::moveTo(%this, %dest, %speed)
{
%this.speed = %speed;
%this.setDestination(%dest);
}now we can call
$player.moveTo("15 15", 10);
and we don't need to set speed anymore !
save it and test it out
you should get something like this
ok... now lets add one more thing before we finish, just to round it out...
function sceneWindow2D::onRightMouseDown( %this, %mod, %worldPos, %mouseClicks )
{
$player.moveTo(%worldPos, 10);
}now save... and fire up T2D and right click where you want to move... like this
if yours doesnt work compare it to this
function moveToDemo()
{
$player = new fxStaticSprite2D() { scenegraph = t2dSceneGraph; };
$player.setPosition("0 0");
$player.setSize( "7 7" );
$player.setImageMap( tileMapImageMap );
}
function fxSceneObject2D::setDestination(%this, %dest)
{
if((%dest != 0) && (%dest !$= ""))
{
%this.Destination = %dest;
%this.isMoving = true;
if($debugMsg::pathDebug)
echo("calling move to dest with" SPC %dest);
%this.schedule(50,moveToDest);
}
}
function angleBetween(%playerPos, %mousePos)
{
// Seperate Mouse Position
%mxpos = getWord(%mousePos,0);
%mypos = getWord(%mousePos,1);
// Seperate Player Position
%px = getWord(%playerPos,0);
%py = getWord(%playerPos,1);
// Calculate Angle from player to mouse (convert to degrees).
%angle = mRadToDeg( mAtan( %mxpos-%px, %py-%mypos ) );
return %angle;
}
function fxSceneObject2D::moveToDest(%this)
{
if(%this.isMoving)
{
%direc = angleBetween(%this.getPosition(), %this.Destination);
%this.destRot = %direc;
%this.setRotation(%direc);
%this.setLinearVelocityPolar(%direc, %this.speed);
%this.schedule(100, checkDest);
}
}
function distBetween(%loc1, %loc2)
{
%x1 = getWord(%loc1, 0);
%y1 = getWord(%loc1, 1);
%x2 = getWord(%loc2, 0);
%y2 = getWord(%loc2, 1);
%xd = %x2 - %x1;
%yd = %y2 - %y1;
return mSqrt((mPow(%xd,2)) + (mPow(%yd,2)));
}
function fxSceneObject2D::checkDest(%this)
{
if(%this.isMoving)
{
%space = 0.5;
%distance = distBetween(%this.getPosition(), %this.Destination);
if(%distance < %space)
{
%this.setAtRest();
%this.isMoving = false;
%this.onReachDestination();
} else
{
%direc = angleBetween(%this.getPosition(), %this.Destination);
if(%direc != %this.destRot)
{
%this.destRot = %direc;
%this.setRotation(%direc);
%this.setLinearVelocityPolar(%direc, %this.speed);
}
%this.schedule(100, checkDest);
}
}
}
function fxSceneObject2D::moveTo(%this, %dest, %speed)
{
%this.speed = %speed;
%this.setDestination(%dest);
}
function sceneWindow2D::onRightMouseDown( %this, %mod, %worldPos, %mouseClicks )
{
$player.moveTo(%worldPos, 10);
}ok now we can right click and move the player (or well the box in this case lol)... we got basic movement! Something similar to this is what I used in my GID... its a great starting point...
well hope you learned something and enjoyed!
- Matthew "King BoB" Langley
About the author
I Manage Tool Development for Torque at InstantAction
#2
04/12/2005 (6:32 pm)
lol... welcome back man! Just trying to match up your awesome product with some tutorials :)
#3
It would be more easily accessible if you could scale those screenshots down, though. I have to scroll left/right to read it because the shots are too wide to fit on the display (1024x768 res).
Keep up the good work!
04/17/2005 (10:52 am)
This is great info!It would be more easily accessible if you could scale those screenshots down, though. I have to scroll left/right to read it because the shots are too wide to fit on the display (1024x768 res).
Keep up the good work!
#4
04/17/2005 (11:19 pm)
your right, lol seems I went through a pic too quick and didnt crop it down.
#5
04/18/2005 (5:55 am)
Wow, extremely usefull. Your tutorial skills are perfect!
#6
04/18/2005 (10:56 am)
All hail King Tut BoB!! Thanks for all of the T2D tutorials.
#8
04/20/2005 (11:04 am)
glad they help you :)
#9
04/21/2005 (7:34 pm)
lol in the full pic you can see my extremely simple setup on the very old machine I create most of the tutorials on... T2D open, some script files open (In wordpad =x), paint, and notepad for the typing of the tutorial text... lol notepad, wordpad, and paint... high quality tools ;)
#10
The line.....
if((%dest != 0) && (%dest !$= ""))
....will abort the function if the x coordinate of %dest is an exact 0. I imagine the numerical eval of a string beginning with a zero equates to zero?
Also, in the callback function onReachDestination(), depending on the games precision req'ments, you may want to set......
%this.setPosition(%this.destination);
........due to the fact that a small discrepancy may exist in regards to the %space variable variance defined in the checkDest() function.
Anyways, thanks for the great resources Matt!
07/01/2005 (2:25 am)
Hi, I use this functionality in my game and it works great. One small bug i ran across:The line.....
if((%dest != 0) && (%dest !$= ""))
....will abort the function if the x coordinate of %dest is an exact 0. I imagine the numerical eval of a string beginning with a zero equates to zero?
Also, in the callback function onReachDestination(), depending on the games precision req'ments, you may want to set......
%this.setPosition(%this.destination);
........due to the fact that a small discrepancy may exist in regards to the %space variable variance defined in the checkDest() function.
Anyways, thanks for the great resources Matt!
#11
This would be a very useful Tuitorial for me... if I could get it to work. I was trying to get an animated moving sprite to move around the screen under cursor control...
I took the animated sprite demo of the lightning which work imediately :-)
Then I tried this tuitorial... first I cannot seem to get the execs to work at all. Whenever I added Any exec nothing worked. I have a feeling MacOS X isn't being straight with me with regards the file name and adding .txt or put RTF characters into the file - I'm using TEXTEDIT since jEDIT doesn't do the job on the Mac. Anyway I can something to work by putting the code in-line in the client .cs file. This is what I have:
//-----------------------------------------------------------------------------
// Torque 2D.
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
// --------------------------------------------------------------------
// Initialise Client.
// --------------------------------------------------------------------
function initialiseClient()
{
// Initialise Base Client.
InitBaseClient();
// Key-Bindings.
GlobalActionMap.bind(keyboard, tilde, ToggleConsole);
GlobalActionMap.bindCmd(keyboard, "alt enter", "", "toggleFullScreen();");
// Initialise Canvas.
InitCanvas("T2D");
// ************************************************************************
// Load-up Demo Datablocks.
// NOTE:- Remove this is you're not interested in running the demos
// or any or the default datablocks.
// ************************************************************************
exec("./demoDatablocks.cs");
// Load-up Datablocks.
exec("./datablocks.cs");
// Load-up GUIs.
exec("./mainScreenGui.gui");
// Set GUI.
Canvas.setContent(mainScreenGui);
// Set Cursor.
Canvas.setCursor(DefaultCursor);
// Setup Scene.
setupT2DScene();
}
// --------------------------------------------------------------------
// Destroy Client.
//
// Here we destroy the SceneGraph.
// --------------------------------------------------------------------
function destroyClient()
{
// Destroy fxSceneGraph2D.
if ( isObject(t2dSceneGraph) )
t2dSceneGraph.delete();
}
function moveToDemo()
{
$player = new fxAnimatedSprite2D() { scenegraph = t2dSceneGraph; };
$player.setPosition("47 7"); //here you can set attributes of the
$player.setSize( "20 40" ); //position, size, rotation, etc.
$player.playAnimation(lightningAnimation);
}
function fxSceneObject2D::setDestination(%this, %dest)
{
if((%dest != 0) && (%dest !$= ""))
{
%this.Destination = %dest;
%this.isMoving = true;
if($debugMsg::pathDebug)
echo("calling move to dest with" SPC %dest);
%this.schedule(50,moveToDest);
}
}
function angleBetween(%playerPos, %mousePos)
{
// Seperate Mouse Position
%mxpos = getWord(%mousePos,0);
%mypos = getWord(%mousePos,1);
// Seperate Player Position
%px = getWord(%playerPos,0);
%py = getWord(%playerPos,1);
// Calculate Angle from player to mouse (convert to degrees).
%angle = mRadToDeg( mAtan( %mxpos-%px, %py-%mypos ) );
return %angle;
}
function fxSceneObject2D::moveToDest(%this)
{
if(%this.isMoving)
{
%direc = angleBetween(%this.getPosition(), %this.Destination);
%this.destRot = %direc;
%this.setRotation(%direc);
%this.setLinearVelocityPolar(%direc, %this.speed);
%this.schedule(100, checkDest);
}
}
function distBetween(%loc1, %loc2)
{
%x1 = getWord(%loc1, 0);
%y1 = getWord(%loc1, 1);
%x2 = getWord(%loc2, 0);
%y2 = getWord(%loc2, 1);
%xd = %x2 - %x1;
%yd = %y2 - %y1;
return mSqrt((mPow(%xd,2)) + (mPow(%yd,2)));
}
function fxSceneObject2D::checkDest(%this)
{
if(%this.isMoving)
{
%space = 0.5;
%distance = distBetween(%this.getPosition(), %this.Destination);
if(%distance < %space)
{
%this.setAtRest();
%this.isMoving = false;
%this.onReachDestination();
} else
{
%direc = angleBetween(%this.getPosition(), %this.Destination);
if(%direc != %this.destRot)
{
%this.destRot = %direc;
%this.setRotation(%direc);
%this.setLinearVelocityPolar(%direc, %this.speed);
}
%this.schedule(100, checkDest);
}
}
}
function fxSceneObject2D::moveTo(%this, %dest, %speed)
{
%this.speed = %speed;
%this.setDestination(%dest);
}
function sceneWindow2D::onRightMouseDown( %this, %mod, %worldPos, %mouseClicks )
{
$player.moveTo(%worldPos, 10);
}
// --------------------------------------------------------------------
// Setup T2D Scene.
// --------------------------------------------------------------------
function setupT2DScene()
{
// Create fxSceneGraph2D.
new fxSceneGraph2D(t2dSceneGraph);
// Associate Scenegraph with Window.
sceneWindow2D.setSceneGraph( t2dSceneGraph );
// Set Camera Position to be centered on (0,0) with
// view width/height of (100/80).
sceneWindow2D.setCurrentCameraPosition( "0 0 100 75" );
// ************************************************************************
//
// Add your custom code here...
//
// ************************************************************************
datablock fxImageMapDatablock2D(lightningImageMap)
{
mode = cell;
cellWidth = 25;
cellHeight = 51;
textureName = "~/client/images/lightning";
};
datablock fxAnimationDatablock2D(lightningAnimation)
{
imageMap = lightningImageMap;
animationFrames = "0 1 2 3 1 2 3";
animationTime = 0.5; //seconds for animation to complete 1 cycle
animationCycle = true; //loop?
};
moveToDemo();
}
//------------------------------EOF-----------------------------
I do not see any binding to the Mouse... anyway I open the console and type $player.setDestination("20 20"); or whatever and a) the sprite rotates!!! and b) it does it immediately rather than "moves-to" not what the tile example did. Incidently I couldn't get the tile to appear. I presume there is a datablock missing? Perhaps this tuitorial is building up from another set of files that I haven't come across (???)
Anyway - another 4hours of... um... investigation. I dead jealous of these people coming up with games in a week!!! I'm feeling very dumb.
If anyone can point out the error of my ways it would be appreciated.
Andy
09/09/2005 (8:58 am)
HiThis would be a very useful Tuitorial for me... if I could get it to work. I was trying to get an animated moving sprite to move around the screen under cursor control...
I took the animated sprite demo of the lightning which work imediately :-)
Then I tried this tuitorial... first I cannot seem to get the execs to work at all. Whenever I added Any exec nothing worked. I have a feeling MacOS X isn't being straight with me with regards the file name and adding .txt or put RTF characters into the file - I'm using TEXTEDIT since jEDIT doesn't do the job on the Mac. Anyway I can something to work by putting the code in-line in the client .cs file. This is what I have:
//-----------------------------------------------------------------------------
// Torque 2D.
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
// --------------------------------------------------------------------
// Initialise Client.
// --------------------------------------------------------------------
function initialiseClient()
{
// Initialise Base Client.
InitBaseClient();
// Key-Bindings.
GlobalActionMap.bind(keyboard, tilde, ToggleConsole);
GlobalActionMap.bindCmd(keyboard, "alt enter", "", "toggleFullScreen();");
// Initialise Canvas.
InitCanvas("T2D");
// ************************************************************************
// Load-up Demo Datablocks.
// NOTE:- Remove this is you're not interested in running the demos
// or any or the default datablocks.
// ************************************************************************
exec("./demoDatablocks.cs");
// Load-up Datablocks.
exec("./datablocks.cs");
// Load-up GUIs.
exec("./mainScreenGui.gui");
// Set GUI.
Canvas.setContent(mainScreenGui);
// Set Cursor.
Canvas.setCursor(DefaultCursor);
// Setup Scene.
setupT2DScene();
}
// --------------------------------------------------------------------
// Destroy Client.
//
// Here we destroy the SceneGraph.
// --------------------------------------------------------------------
function destroyClient()
{
// Destroy fxSceneGraph2D.
if ( isObject(t2dSceneGraph) )
t2dSceneGraph.delete();
}
function moveToDemo()
{
$player = new fxAnimatedSprite2D() { scenegraph = t2dSceneGraph; };
$player.setPosition("47 7"); //here you can set attributes of the
$player.setSize( "20 40" ); //position, size, rotation, etc.
$player.playAnimation(lightningAnimation);
}
function fxSceneObject2D::setDestination(%this, %dest)
{
if((%dest != 0) && (%dest !$= ""))
{
%this.Destination = %dest;
%this.isMoving = true;
if($debugMsg::pathDebug)
echo("calling move to dest with" SPC %dest);
%this.schedule(50,moveToDest);
}
}
function angleBetween(%playerPos, %mousePos)
{
// Seperate Mouse Position
%mxpos = getWord(%mousePos,0);
%mypos = getWord(%mousePos,1);
// Seperate Player Position
%px = getWord(%playerPos,0);
%py = getWord(%playerPos,1);
// Calculate Angle from player to mouse (convert to degrees).
%angle = mRadToDeg( mAtan( %mxpos-%px, %py-%mypos ) );
return %angle;
}
function fxSceneObject2D::moveToDest(%this)
{
if(%this.isMoving)
{
%direc = angleBetween(%this.getPosition(), %this.Destination);
%this.destRot = %direc;
%this.setRotation(%direc);
%this.setLinearVelocityPolar(%direc, %this.speed);
%this.schedule(100, checkDest);
}
}
function distBetween(%loc1, %loc2)
{
%x1 = getWord(%loc1, 0);
%y1 = getWord(%loc1, 1);
%x2 = getWord(%loc2, 0);
%y2 = getWord(%loc2, 1);
%xd = %x2 - %x1;
%yd = %y2 - %y1;
return mSqrt((mPow(%xd,2)) + (mPow(%yd,2)));
}
function fxSceneObject2D::checkDest(%this)
{
if(%this.isMoving)
{
%space = 0.5;
%distance = distBetween(%this.getPosition(), %this.Destination);
if(%distance < %space)
{
%this.setAtRest();
%this.isMoving = false;
%this.onReachDestination();
} else
{
%direc = angleBetween(%this.getPosition(), %this.Destination);
if(%direc != %this.destRot)
{
%this.destRot = %direc;
%this.setRotation(%direc);
%this.setLinearVelocityPolar(%direc, %this.speed);
}
%this.schedule(100, checkDest);
}
}
}
function fxSceneObject2D::moveTo(%this, %dest, %speed)
{
%this.speed = %speed;
%this.setDestination(%dest);
}
function sceneWindow2D::onRightMouseDown( %this, %mod, %worldPos, %mouseClicks )
{
$player.moveTo(%worldPos, 10);
}
// --------------------------------------------------------------------
// Setup T2D Scene.
// --------------------------------------------------------------------
function setupT2DScene()
{
// Create fxSceneGraph2D.
new fxSceneGraph2D(t2dSceneGraph);
// Associate Scenegraph with Window.
sceneWindow2D.setSceneGraph( t2dSceneGraph );
// Set Camera Position to be centered on (0,0) with
// view width/height of (100/80).
sceneWindow2D.setCurrentCameraPosition( "0 0 100 75" );
// ************************************************************************
//
// Add your custom code here...
//
// ************************************************************************
datablock fxImageMapDatablock2D(lightningImageMap)
{
mode = cell;
cellWidth = 25;
cellHeight = 51;
textureName = "~/client/images/lightning";
};
datablock fxAnimationDatablock2D(lightningAnimation)
{
imageMap = lightningImageMap;
animationFrames = "0 1 2 3 1 2 3";
animationTime = 0.5; //seconds for animation to complete 1 cycle
animationCycle = true; //loop?
};
moveToDemo();
}
//------------------------------EOF-----------------------------
I do not see any binding to the Mouse... anyway I open the console and type $player.setDestination("20 20"); or whatever and a) the sprite rotates!!! and b) it does it immediately rather than "moves-to" not what the tile example did. Incidently I couldn't get the tile to appear. I presume there is a datablock missing? Perhaps this tuitorial is building up from another set of files that I haven't come across (???)
Anyway - another 4hours of... um... investigation. I dead jealous of these people coming up with games in a week!!! I'm feeling very dumb.
If anyone can point out the error of my ways it would be appreciated.
Andy
#12
09/09/2005 (9:03 am)
When you fire up T2D hit the "~" tilde key to bring up the console, look for red text, if you see any especially with ## signs that means it found a syntax error, you need to fix those errors and then it will compile out the extra .cs script files :)
#13
Your exactly right, lol late response, way back when you posted that I responded but guess my msg didn't go through or hit the board delete bug
so you should remove the not equal comparisson to 0 like you said
09/09/2005 (9:15 am)
Quote:if((%dest != 0) && (%dest !$= ""))
....will abort the function if the x coordinate of %dest is an exact 0. I imagine the numerical eval of a string beginning with a zero equates to zero?
Your exactly right, lol late response, way back when you posted that I responded but guess my msg didn't go through or hit the board delete bug
so you should remove the not equal comparisson to 0 like you said
Quote:if(%dest !$= "")
#14
09/09/2005 (9:28 am)
You can now get this tutorial along with 9 others in a T2D "Tutorial Pack"... in this pack each tutorial is an external html file so you can use them offline :)
#15
Firstly on debugging. Loading up the tuitorial while there was those "exec" issues hung T2D-OSX - no console available, therefore no chance of looking for syntax errors. I had to force quit T2D and re-start from the last known working version of code. Very disheartneing...
I read the post about that if((%dest != 0) && (%dest !$= "")) and deleted the wrong half of the condition! Have I been working on previously compiled code?
It doesn't explain the rotation of the image though does it?
I'll check out the new tuitorial pack and get back to you :-)
Cheers - Andy
09/09/2005 (10:46 am)
Many thanks for the reply, Matthew.Firstly on debugging. Loading up the tuitorial while there was those "exec" issues hung T2D-OSX - no console available, therefore no chance of looking for syntax errors. I had to force quit T2D and re-start from the last known working version of code. Very disheartneing...
I read the post about that if((%dest != 0) && (%dest !$= "")) and deleted the wrong half of the condition! Have I been working on previously compiled code?
It doesn't explain the rotation of the image though does it?
I'll check out the new tuitorial pack and get back to you :-)
Cheers - Andy
#16
09/09/2005 (10:48 am)
:) I beleive there still should be the in game console (not referring to the windows one)...
#17
09/09/2005 (10:51 am)
to get the same results, when you close T2D it copies the console to console.log, if you could copy and paste that up here that would help also, have a feeling thats why the exec's arent working.
#18
Very good tutorial. I was confused only once where you said
"Ok now everything should work fine, we got a box in the middle of the screen...
lets start with our first function"
I had to scroll down a bit to see to what file we were transcribing "function fxSceneObject2D::setDestination(%this, %dest){}". If you have the ability to edit that and clarify the sentence I think it would be beneficial.
09/22/2005 (1:20 am)
Edit: For the problem with high speeds, if you add this it works fine (for me, anyways):function fxSceneObject2D::onReachDestination(%this)
{
%this.setPosition( repeat your destination coords in here );
}Very good tutorial. I was confused only once where you said
"Ok now everything should work fine, we got a box in the middle of the screen...
lets start with our first function"
I had to scroll down a bit to see to what file we were transcribing "function fxSceneObject2D::setDestination(%this, %dest){}". If you have the ability to edit that and clarify the sentence I think it would be beneficial.
Torque Owner Josh Williams
Default Studio Name