Make GuiSpriteCtrl respond to touch/mouse? [solved]
by Joe Williams · in Torque 2D Beginner · 05/05/2013 (8:04 am) · 4 replies
I want to use my own art for touch controls for my game. I have a sprite control appearing in the game properly, but it isn't responding to the touch at all. Any ideas? Here is the relevant code.
iOSGameUI.gui.taml file:
Game create function:
Touch callbacks:
When the game starts, the frame is set to 8, so I know the control class is set properly and that it's responding to function calls. It just isn't responding to the mouse or touch at all. What am I missing?
I should mention that the GuiDirectionalUI profile is just a blank profile in guiProfiles.cs. I'm not sure if I need anything in there or not.
(Given my track record, I'll figure this out shortly after posting this.)
Update: The new SceneWindow.addInputListener( %obj ) function solved this for me. So any scene object, it appears, can be added as a listener so that the input callbacks will work with it. One thing to note is that Gui controls don't use positioning the same way, though. So comparing a Gui control's position against the %worldPosition parameter of an input callback won't work.
Further update: There is a 100 pixel difference (at 800 x 600) between where the Gui control is and where the window recognizes touch to be. Also, adding something as an input listener means it will respond any time the screen/window is touched/clicked, not just when the control is touched/clicked. All of this means the following:
1. Get the window coordinates based on world position, like this (using Sandbox as example): %windowCoords = SandboxWindow.getWindowPoint( %worldPosition )
2. Subtract 100 to the window point coordinates like this: %windowCoords = %windowCoords.x - 100 SPC %windowCoords.y - 100
3. Limit your control's callback based on the %windowCoords being within its bounds with something like this:
iOSGameUI.gui.taml file:
<GuiSpriteCtrl
Name="iOSGameUI"
Profile="GuiDirectionalUI"
HorizSizing="relative"
VertSizing="relative"
Position="200 200"
Extent="171 171"
MinExtent="60 60"
Visible="1"
Active="1"
useMouseEvents="1"
class="moveCircle"
Image="@asset=CFD:DirectionalUI"/>Game create function:
function CFD::create( %this )
{
// Activate the package.
activatePackage( CFDPackage );
exec("./gui/guiProfiles.cs");
//allow objects to interact with inputs
SandboxWindow.UseObjectInputEvents = true;
CFD.add( TamlRead("./gui/iOSGameUI.gui.taml") );
SandboxWindow.add(iOSGameUI);
iOSGameUI.onTouchUp( 0, "0 0" );
}Touch callbacks:
function moveCircle::onTouchDown( %this, %touchID, %worldPosition )
{
echo( "Move Circle Touched!" );
%this.myTouchID = %touchID;
%angleMod = mFloor( ( Vector2AngleToPoint ( %this.getPosition(), %worldPosition ) + 22.5 ) / 45 ) % 8;
%this.setImageFrame( %angleMod );
}
function moveCircle::onTouchUp( %this, %touchID, %worldPosition )
{
%this.setImageFrame( 8 );
}When the game starts, the frame is set to 8, so I know the control class is set properly and that it's responding to function calls. It just isn't responding to the mouse or touch at all. What am I missing?
I should mention that the GuiDirectionalUI profile is just a blank profile in guiProfiles.cs. I'm not sure if I need anything in there or not.
(Given my track record, I'll figure this out shortly after posting this.)
Update: The new SceneWindow.addInputListener( %obj ) function solved this for me. So any scene object, it appears, can be added as a listener so that the input callbacks will work with it. One thing to note is that Gui controls don't use positioning the same way, though. So comparing a Gui control's position against the %worldPosition parameter of an input callback won't work.
Further update: There is a 100 pixel difference (at 800 x 600) between where the Gui control is and where the window recognizes touch to be. Also, adding something as an input listener means it will respond any time the screen/window is touched/clicked, not just when the control is touched/clicked. All of this means the following:
1. Get the window coordinates based on world position, like this (using Sandbox as example): %windowCoords = SandboxWindow.getWindowPoint( %worldPosition )
2. Subtract 100 to the window point coordinates like this: %windowCoords = %windowCoords.x - 100 SPC %windowCoords.y - 100
3. Limit your control's callback based on the %windowCoords being within its bounds with something like this:
function guiControl::inRange( %this, %windowCoords ) //assumes %windowCoords already adjusted - 100
{
%xMax = %this.getPosition().x + %this.getExtent().x / 2;
%xMin = %this.getPosition().x - %this.getExtent().x / 2;
%yMax = %this.getPosition().y + %this.getExtent().y / 2;
%yMin = %this.getPosition().y - %this.getExtent().y / 2;
if( %windowCoords.x < %xMax && %windowCoords.x > %xMin && %windowCoords.y < %ymax && %windowCoords.y > %yMax )
{
return true;
{
return false;
}
function guiControl::onTouchDown( %this, %touchID, %worldPostiion )
{
%windowCoords = SandboxWindow.getWindowPoint( %worldPosition );
%windowCoords = %windowCoords.x - 100 SPC %windowCoords.y - 100;
if( %this.inRange( %windowCoords )
{
//touch response code here
}
}About the author
Recent Threads
#2
05/05/2013 (8:55 am)
Thanks for the suggestion. There isn't anything above the control in the TAML file or in the scene, and I think makeFirstResponder is just a way to ensure that the control is the first to act when clicked/touched. That isn't a problem with my current setup.
#3
%modifier will list all modifier keys being held down (Shift, ctrl, etc.)
%worldPos is the position of the mouse click
%mouseclicks determines how many clicks occured so you can easily detect double-clicks with this.
I can't test iOS functionality as I don't have an iDevice but I've looked at the code and don't see anything that seems to contradict my theory.
05/05/2013 (11:10 am)
Except for the SceneWindow, GuiControls do not respond to onTouchDown, they respond to onMouseDown.function My_GUI_Control::onMouseDown(%this, %modifier, %worldPos, %mouseClicks)
{
}%modifier will list all modifier keys being held down (Shift, ctrl, etc.)
%worldPos is the position of the mouse click
%mouseclicks determines how many clicks occured so you can easily detect double-clicks with this.
I can't test iOS functionality as I don't have an iDevice but I've looked at the code and don't see anything that seems to contradict my theory.
#4
but it still doesn't respond.
Anyone have any other ideas? I could modify the touch functions of the scene window, but I'd prefer to keep this as simple and intuitive as possible.
05/05/2013 (11:16 am)
That doesn't seem to work, either. I changed the touchdown code to thisfunction moveCircle::onMouseDown( %this, %modifier, %worldPos, %mouseClicks )
{
echo( "Move Circle Touched!" );
//%this.myTouchID = %touchID;
%angleMod = mFloor( ( Vector2AngleToPoint ( %this.getPosition(), %worldPos ) + 22.5 ) / 45 ) % 8;
%this.setImageFrame( %angleMod );
}but it still doesn't respond.
Anyone have any other ideas? I could modify the touch functions of the scene window, but I'd prefer to keep this as simple and intuitive as possible.
Torque Owner practicing01
MourningDoveSoft