Writing a scroller - need HUD buttons onTouchDown to move player
by Andy Hawkins · in iTorque 2D · 10/13/2012 (7:43 pm) · 6 replies
I have a scroller I'm working on iT2D. These are the conditions so a solution could vary.
1. The buttons must stay onscreen all the time.
2. The background must scroll independent of the buttons.
3. The buttons must send events onTouchDown and onTouchUp
The problem is.
1. The buttons work onTouchUp only running the Command var.
2. I need them to work onTouchDown as well.
So for example the player moves only when I release the button. It must be when the button is down.
I would normally put the buttons onscreen, but the level is scrolling underneath. I would rather not scroll the scene items under the player; I would prefer to use the GUI if possible.
I've read through the forums a bit, but no solution seems to point to exactly this, which is why I am asking for help on this issue. Some people seems to be talking about ray picking, but I couldn't understand how to make that work. This thread for example almost seems to be right, but I didn't know how to set up MyObject - is it a Name or Class?
www.garagegames.com/community/forums/viewthread/127281
Anyway - that's beside the point.
1. The buttons must stay onscreen all the time.
2. The background must scroll independent of the buttons.
3. The buttons must send events onTouchDown and onTouchUp
The problem is.
1. The buttons work onTouchUp only running the Command var.
2. I need them to work onTouchDown as well.
So for example the player moves only when I release the button. It must be when the button is down.
I would normally put the buttons onscreen, but the level is scrolling underneath. I would rather not scroll the scene items under the player; I would prefer to use the GUI if possible.
I've read through the forums a bit, but no solution seems to point to exactly this, which is why I am asking for help on this issue. Some people seems to be talking about ray picking, but I couldn't understand how to make that work. This thread for example almost seems to be right, but I didn't know how to set up MyObject - is it a Name or Class?
www.garagegames.com/community/forums/viewthread/127281
Anyway - that's beside the point.
#2
As for the buttons, I've always just used sceneObjects for my buttons and they respond to both touchDown and touchUp. An example of code for that looks like this:
Another nice thing about using two scenes (which probably is nice about using the GUI builder, too) is that you can just pause all of scene #1 rather than having to pause individual elements. It makes pausing really easy.
10/13/2012 (11:44 pm)
(sorry, had to split into two posts)As for the buttons, I've always just used sceneObjects for my buttons and they respond to both touchDown and touchUp. An example of code for that looks like this:
function pausingButton::onLevelLoaded( %this, %scenegraph )
{
%this.setUseMouseEvents( true );
%this.myPauseGraph = sceneWindow2D.getSceneGraph();
}
function pausingButton::onTouchDown( %this, %touchID, %worldPos )
{
%this.setFrame( 1 );
}
function pausingButton::onTouchUp( %this, %touchID, %worldPos )
{
%this.setFrame( 0 );
%this.togglePause();
}
function pausingButton::onMouseLeave(%this, %modifier, %worldPosition, %clicks)
{
%this.setFrame( 0 );
}
function pausingButton::togglePause( %this )
{
if( $paused )
{
$paused = false;
}
else
{
$paused = true;
}
%this.myPauseGraph.setScenePause( $paused );
}Another nice thing about using two scenes (which probably is nice about using the GUI builder, too) is that you can just pause all of scene #1 rather than having to pause individual elements. It makes pausing really easy.
#3
10/14/2012 (5:39 am)
Thanks for that. That's perfect and really easy to understand.
#4
10/14/2012 (6:42 am)
I forgot to mention one thing. The way I have the code setup, you have to have scene #1 open when you go to use the preview. That's because the line "sceneWindow2D.loadLevel(%level);" in startGame loads whatever scene you have open. If you don't want to have to worry about that, then just change sceneWindow2D.loadLevel(%level); to sceneWindow2D.loadLevel("data/levels/actionScene.t2d"); or whatever your scene #1 filename is.
#5
So just to clarify for the readers...
1) I opened the GUI editor, loaded mainScreen.gui, hit toggle palette and dropped a t2dSceneWindow into the view, renamed to hudWindow and set the extents to 0,0,480,320 and saved.
2) Then I removed all my buttons for my main level (called level1.t2d)
3) I then created a new scene called hudScene.t2d and add all my buttons with behaviors -> made sure to add all the button graphics to the datablock.
4) I saved that, then reloaed level1.t2d so the editor would load this.
5) Then I made the code changes above and ran it. Works perfectly!
10/15/2012 (6:24 am)
Works like a charm - thanks for the last tip. That's what I didn't get.So just to clarify for the readers...
1) I opened the GUI editor, loaded mainScreen.gui, hit toggle palette and dropped a t2dSceneWindow into the view, renamed to hudWindow and set the extents to 0,0,480,320 and saved.
2) Then I removed all my buttons for my main level (called level1.t2d)
3) I then created a new scene called hudScene.t2d and add all my buttons with behaviors -> made sure to add all the button graphics to the datablock.
4) I saved that, then reloaed level1.t2d so the editor would load this.
5) Then I made the code changes above and ran it. Works perfectly!
#6
10/15/2012 (6:28 am)
Oh yeah make sure you stop the mainScene.gui to not use mouse events. See last two settings.new t2dSceneWindow(sceneWindow2D) {
canSaveDynamicFields = "0";
PlatformTarget = "UNIVERSAL";
class = "Button";
isContainer = "0";
Profile = "GuiDefaultProfile";
HorizSizing = "width";
VertSizing = "height";
Position = "0 0";
Extent = "480 320";
MinExtent = "480 320";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiDefaultProfile";
hovertime = "1000";
lockMouse = "0";
useWindowMouseEvents = "0";
useObjectMouseEvents = "0";
};And set them in the hudWindow...new t2dSceneWindow(hudWindow) {
canSaveDynamicFields = "0";
PlatformTarget = "UNIVERSAL";
isContainer = "0";
Profile = "GuiDefaultProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "0 0";
Extent = "480 320";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
hovertime = "1000";
lockMouse = "0";
useWindowMouseEvents = "1";
useObjectMouseEvents = "1";
};
Torque Owner Joe Williams
Newborn Games
This is a fairly easy thing to do and seems to have no impact on performance. All you have to do is setup your two scenes, add your second window in mainScreen.gui, and handle your second scene in game.cs.
My mainscreen.gui includes this:
//this is the second scene window new t2dSceneWindow(hudWindow) { canSaveDynamicFields = "0"; isContainer = "0"; Profile = "GuiDefaultProfile"; HorizSizing = "width"; VertSizing = "height"; Position = "0 0"; Extent = "1024 768"; MinExtent = "480 320"; canSave = "1"; Visible = "1"; tooltipprofile = "GuiDefaultProfile"; hovertime = "1000"; lockMouse = "0"; useWindowMouseEvents = "1"; useObjectMouseEvents = "1"; };And the setResolution and startGame functions in my game.cs file look like this:
function setResolution() { if(isObject(mainScreenGui) && isObject(sceneWindow2D)) { if($pref::iOS::ScreenOrientation == 1) //portrait { if(($pref::iOS::DeviceType != $iOS::constant::iPad)) { echo(" % - MainScreen set to Portrait! 320x480"); mainScreenGui.Extent = "320 480"; sceneWindow2D.Extent = "320 480"; hudWindow.Extent = "320 480"; } else { echo(" % - MainScreen set to Portrait! 768x1024"); mainScreenGui.Extent = "768 1024"; sceneWindow2D.Extent = "768 1024"; hudWindow.Extent = "768 1024"; } } else { if(($pref::iOS::DeviceType != $iOS::constant::iPad)) { echo(" % - MainScreen set to Landscape! 480x320 "); mainScreenGui.Extent = "480 320"; sceneWindow2D.Extent = "480 320"; hudWindow.Extent = "480 320"; } else { echo(" % - MainScreen set to Landscape! 1024x768 "); mainScreenGui.Extent = "1024 768"; sceneWindow2D.Extent = "1024 768"; hudWindow.Extent = "1024 768"; } } } }Note I've added .Extent assignments for the hudWindow everywhere that the Extent was set for sceneWindow2D.
function startGame(%level) { // Push the parent GUI for the game (found in game/gui/mainScreen.gui) Canvas.setContent(mainScreenGui); // Report the time it took to load the game to this point %runTime = getRealTime() - $Debug::loadStartTime; echo(" % - Game load time : " @ %runTime @ " ms"); // Create a new ActionMap for input binding new ActionMap(moveMap); // Enable DirectInput for Windows development $enableDirectInput = true; activateDirectInput(); // Load the .t2d file for this game sceneWindow2D.loadLevel(%level); hudWindow.loadLevel("data/levels/guiScene.t2d"); //this is the second scene being loaded // Execute the following code on iOS only if($platform $= "iphone" || $platform $= "ipad" || $platform $= "iphone4") { // Bind core touch reactions to functions // Function names are completely up to you moveMap.bind(touchdevice, touchdown, "touchesDown"); moveMap.bind(touchdevice, touchmove, "touchesMove"); moveMap.bind(touchdevice, touchup, "touchesUp"); // Hide the "mouse" cursor on iOS hideCursor(); // Push the moveMap bindings moveMap.push(); } }If you've changed any code to handle the iPad 3 retina display, you may need to add handling for your second scene there as well. I personally haven't had to do that, but your situation may be different.