Torque 2D/Getting Started/ObjectSelection1Tutorial
From TDN
|
[edit] Torque 2D Tutorial – Object Selection 1: The Simple Methodby: Matthew "King BoB" Langley [edit] This tutorial will cover the following:
[edit] Getting Started
function sceneWindow2D::onMouseMove( %this, %mod, %worldPos, %mouseClicks )
{
}
function sceneWindow2D::onMouseDragged( %this, %mod, %worldPos, %mouseClicks )
{
}
function sceneWindow2D::onMouseDown( %this, %mod, %worldPos, %mouseClicks )
{
}
function sceneWindow2D::onMouseUp( %this, %mod, %worldPos, %mouseClicks )
{
}
function sceneWindow2D::onMouseEnter( %this, %mod, %worldPos, %mouseClicks )
{
}
function sceneWindow2D::onMouseLeave( %this, %mod, %worldPos, %mouseClicks )
{
}
We might not need all of these, but it's always good to check out all the tools and methods available before starting to code. These are what we refer to as "callbacks". Basically a callback is just the engine (the C++ part of T2D) "calling back" the scripting language. The functions above were placed in the source code at certain points to allow us to perform actions in script when mouse events occur. Without them we wouldn't be able to know when the mouse moves, drags, clicks etc. Callbacks are the main method T2D uses to allow interaction between script and C++ code. To find more callbacks, just search for “callbacks†in the T2D reference documentation.
function sceneWindow2D::onMouseMove( %this, %mod, %worldPos, %mouseClicks )
{
echo("Mouse Moving");
}
function sceneWindow2D::onMouseDragged( %this, %mod, %worldPos, %mouseClicks )
{
echo("Mouse Dragging");
}
function sceneWindow2D::onMouseDown( %this, %mod, %worldPos, %mouseClicks )
{
echo("Mouse Down");
}
function sceneWindow2D::onMouseUp( %this, %mod, %worldPos, %mouseClicks )
{
echo("Mouse Up");
}
function sceneWindow2D::onMouseEnter( %this, %mod, %worldPos, %mouseClicks )
{
echo("Mouse Entered... Knew it would come crawling back");
}
function sceneWindow2D::onMouseLeave( %this, %mod, %worldPos, %mouseClicks )
{
echo("Mouse Left... Go Get It!");
}
Save the file. Now create another script file in the same folder called "exec.cs". In that file put this line of code:
exec("./simpleMouse.cs");
Save that file and open client.cs. Find the area (towards the beginning) where it has a series of exec statements and at the end of these add:
exec("./exec.cs");
You may have figured out that what we've done is create a file (exec.cs) where we can execute all of our script files without having to change client.cs every time. This method also helps separate your files and can aid make debugging easier as well. Okay, now save the exec.cs and client.cs files and close them. Fire up T2D and move the mouse around a bit. Now press the "~" tilde key to bring up the console and you should see something like this:
if($debugMsg::mouse::callBacks) Like this:
function sceneWindow2D::onMouseMove( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Moving");
}
function sceneWindow2D::onMouseDragged( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Dragging");
}
function sceneWindow2D::onMouseDown( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Down");
}
function sceneWindow2D::onMouseUp( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Up");
}
function sceneWindow2D::onMouseEnter( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Entered... Knew it would come crawling back");
}
function sceneWindow2D::onMouseLeave( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Left... Go Get It!");
}
Now save and fire up T2D, move the mouse around and bring up the console. You shouldn't see any of those echo statements. Now type this in the console: “$debugMsg::mouse::callbacks = true;†Hit enter and close the console, move your mouse around, and bring up the console again. Now you should see the echo statements again. To turn them off type: “$debugMsg::mouse::callbacks = false;†If we organize all our debug statements like this then later if we need to debug this part of our code again we can just toggle the messages back on with a simple command. %this.mousePos = %worldPos; Your new functions should look like this:
function sceneWindow2D::onMouseMove( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Moving");
//lets store the mouses position
%this.mousePos = %worldPos;
}
function sceneWindow2D::onMouseDragged( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Dragging");
//lets store the mouses position
%this.mousePos = %worldPos;
}
Now we've stored the mouse's position... we just need an object to set to that position. Add this function to the end of simpleMouse.cs:
function simpleMouse()
{
$test = new t2dStaticSprite() { sceneGraph = t2dScene; };
$test.setImageMap( tileMapImageMap );
$test.setSize( "5 5" );
$test.setPosition( "0 0" );
$test.isSelectable = true;
$test.objectName = "test box";
}
Now go to client.cs and add a call to simpleMouse() where it says:
// ************************************************************************
//
// Add your custom code here...
//
// ************************************************************************
Just add this: simpleMouse(); Save client.cs then run T2D... you should see something like this:
function sceneWindow2D::onMouseMove( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Moving");
//lets store the mouses position
%this.mousePos = %worldPos;
}
function sceneWindow2D::onMouseDragged( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Dragging");
//lets store the mouses position
%this.mousePos = %worldPos;
}
function sceneWindow2D::onMouseDown( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Down");
}
function sceneWindow2D::onMouseUp( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Up");
}
function sceneWindow2D::onMouseEnter( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Entered... Knew it would come crawling back");
}
function sceneWindow2D::onMouseLeave( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Left... Go Get It!");
}
function simpleMouse()
{
$test = new t2dStaticSprite() { sceneGraph = t2dScene; };
$test.setImageMap( tileMapImageMap );
$test.setSize( "5 5" );
$test.setPosition( "0 0" );
$test.isSelectable = true;
$test.objectName = "test box";
}
So now we're storing the mouse position and we have an object. We also added a custom property that says it is selectable to help in the object selection. We're ready to put in the code to actually select the block. Add this code to onMouseDown:
//lets get a list of all the objects at the clicked point in the t2dScene
%objList = t2dScene.pickPoint(%worldPos);
//lets get a count of how many objects in the list
%objCount = getWordCount(%objList);
//we will start looping through the list
for(%i=0;%i<%objCount;%i++)
{
//grabing the entry corresponding to the loop
%obj = getWord(%objList, %i);
//if we find an object in the list that "isSelectable = true"
if(%obj.isSelectable)
{
//we toggle a value so we know we found an object that "isSelectable"
%selected = true;
//we kick out of the loop
%i = %objCount;
}
}
//if we found an "isSelectable" object
if(%selected)
{
//we then store that object as the selectedObj
%this.selectedObj = %obj;
}
This is a lot of code to digest... the comments explain it pretty thoroughly. We do these steps:
function sceneWindow2D::onMouseDown( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Down");
//lets get a list of all the objects at the clicked point in the t2dScene
%objList = t2dScene.pickPoint(%worldPos);
//lets get a count of how many objects in the list
%objCount = getWordCount(%objList);
//we will start looping through the list
for(%i=0;%i<%objCount;%i++)
{
//grabing the entry corresponding to the loop
%obj = getWord(%objList, %i);
//if we find an object in the list that "isSelectable = true"
if(%obj.isSelectable)
{
//we toggle a value so we know we found an object that "isSelectable"
%selected = true;
//we kick out of the loop
%i = %objCount;
}
}
//if we found an "isSelectable" object
if(%selected)
{
//we then store that object as the selectedObj
%this.selectedObj = %obj;
if($debugMsg::mouse::selection)
echo("You have selected:" SPC %obj SPC "with the name:" SPC %obj.objectName);
}
}
Fire up T2D and type this in the console: $debugMsg::mouse::selection = true; Now click on the box and bring up the console... you should see this:
function sceneWindow2D::onMouseDown( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Down");
//lets get a list of all the objects at the clicked point in the t2dScene
%objList = t2dScene.pickPoint(%worldPos);
//lets get a count of how many objects in the list
%objCount = getWordCount(%objList);
//we will start looping through the list
for(%i=0;%i<%objCount;%i++)
{
//grabing the entry corresponding to the loop
%obj = getWord(%objList, %i);
//if we find an object in the list that "isSelectable = true"
if(%obj.isSelectable)
{
//we toggle a value so we know we found an object that "isSelectable"
%selected = true;
//we kick out of the loop
%i = %objCount;
}
}
//if we found an "isSelectable" object
if(%selected)
{
//we then store that object as the selectedObj
%this.selectedObj = %obj;
if($debugMsg::mouse::selection)
echo("You have selected:" SPC %obj SPC "with the name:" SPC %obj.objectName);
%this.objectSelected = true;
}
}
Now we'll create a new function. Add it to the end of the file:
function t2dSceneWindow::objectFollowCheck()
{
}
The first thing we want it to do is check if an object is selected, so add this:
if(%this.objectSelected)
{
}
If something is selected then we want to update its position to the mouse position, so we grab the value we stored the object in (%this.selectedObj) and we set that object's position. Like so:
%obj = %this.selectedObj;
%mousePos = %this.mousePos;
%obj.setPosition(%mousePos);
So the whole objectFollowCheck function should look like this:
function t2dSceneWindow::objectFollowCheck(%this)
{
if(%this.objectSelected)
{
%obj = %this.selectedObj;
%mousePos = %this.mousePos;
%obj.setPosition(%mousePos);
}
}
Now add a call to this function in the onMove and onDrag functions like this:
function t2dSceneWindow::onMouseMove( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Moving");
//lets store the mouses position
%this.mousePos = %worldPos;
%this.objectFollowCheck();
}
function t2dSceneWindow::onMouseDragged( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Dragging");
//lets store the mouses position
%this.mousePos = %worldPos;
%this.objectFollowCheck();
}
To keep our debug messages consistent let's add a debug message like this:
function t2dSceneWindow::objectFollowCheck(%this)
{
if(%this.objectSelected)
{
%obj = %this.selectedObj;
%mousePos = %this.mousePos;
%obj.setPosition(%mousePos);
if($debugMsg::mouse::follow)
echo("this object:" SPC %obj SPC "is following the mouse at this position:" SPC %mousePos);
}
}
Fire up T2D and give this a whirl... click on the box and move... very cool, it moves around!
function sceneWindow2D::onMouseMove( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Moving");
//lets store the mouses position
%this.mousePos = %worldPos;
%this.objectFollowCheck();
}
function sceneWindow2D::onMouseDragged( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Dragging");
//lets store the mouses position
%this.mousePos = %worldPos;
%this.objectFollowCheck();
}
function sceneWindow2D::onMouseDown( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Down");
//lets get a list of all the objects at the clicked point in the t2dScene
%objList = t2dScene.pickPoint(%worldPos);
//lets get a count of how many objects in the list
%objCount = getWordCount(%objList);
//we will start looping through the list
for(%i=0;%i<%objCount;%i++)
{
//grabing the entry corresponding to the loop
%obj = getWord(%objList, %i);
//if we find an object in the list that "isSelectable = true"
if(%obj.isSelectable)
{
//we toggle a value so we know we found an object that "isSelectable"
%selected = true;
//we kick out of the loop
%i = %objCount;
}
}
//if we found an "isSelectable" object
if(%selected)
{
//we then store that object as the selectedObj
%this.selectedObj = %obj;
if($debugMsg::mouse::selection)
echo("You have selected:" SPC %obj SPC "with the name:" SPC %obj.objectName);
%this.objectSelected = true;
}
}
function sceneWindow2D::onMouseUp( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Up");
}
function sceneWindow2D::onMouseEnter( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Entered... Knew it would come crawling back");
}
function sceneWindow2D::onMouseLeave( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Left... Go Get It!");
}
function simpleMouse()
{
$test = new t2dStaticSprite() { sceneGraph = t2dScene; };
$test.setImageMap( tileMapImageMap );
$test.setSize( "5 5" );
$test.setPosition( "0 0" );
$test.isSelectable = true;
$test.objectName = "test box";
}
function t2dSceneWindow::objectFollowCheck(%this)
{
if(%this.objectSelected)
{
%obj = %this.selectedObj;
%mousePos = %this.mousePos;
%obj.setPosition(%mousePos);
if($debugMsg::mouse::follow)
echo("this object:" SPC %obj SPC "is following the mouse at this position:" SPC %mousePos);
}
}
Well, that worked, but now that we got it to moving we need to get it to stop moving. It gets a little annoying with a little box stuck to your mouse. To fix this we will simply edit the onMouseDown function a little. In fact we can make our code a little more efficient if we do this right... when we click again we want it to stop following the mouse, and when we do this we don't need to be searching for objects to select. So let's encompass most of this functionality in an if statement, like this:
function sceneWindow2D::onMouseDown( %this, %mod, %worldPos, %mouseClicks )
{
if($debugMsg::mouse::callBacks)
echo("Mouse Down");
//check to see if we have an object already selected, if so we don't want to do anything expect set it to false so
// it doesn't follow anymore
if(%this.objectSelected)
{
if($debugMsg::mouse::selection)
echo("unselecting");
%this.objectSelected = false;
} else
{
//lets get a list of all the objects at the clicked point in the t2dScene
%objList = t2dScene.pickPoint(%worldPos);
//lets get a count of how many objects in the list
%objCount = getWordCount(%objList);
//we will start looping through the list
for(%i=0;%i<%objCount;%i++)
{
//grabing the entry corresponding to the loop
%obj = getWord(%objList, %i);
//if we find an object in the list that "isSelectable = true"
if(%obj.isSelectable)
{
//we toggle a value so we know we found an object that "isSelectable"
%selected = true;
//we kick out of the loop
%i = %objCount;
}
}
//if we found an "isSelectable" object
if(%selected)
{
//we then store that object as the selectedObj
%this.selectedObj = %obj;
if($debugMsg::mouse::selection)
echo("You have selected:" SPC %obj SPC "with the name:" SPC %obj.objectName);
%this.objectSelected = true;
}
}
}
In this method (as the comment says) the first thing we do is check if we already have something selected. If so, we simply set %this.objectSelected to false. If something isn't selected then we go through the whole process of looking for selectable objects. |









