BUG: wrong level loaded
by Pedro Vicente · in iTorque 2D · 08/14/2011 (12:52 pm) · 10 replies
Build: iTorque 1.4.1
Platform: Tried in Windows only; complete project attached.
Issue:
While trying to extend this resource to work with 3 levels I found some unexpected behavior. At this moment I am not sure if it is an engine bug or some incorrect use of the function loadSceneGraph, shown in the resource
Torque Minimal Template -- Part 5. Levels and sound
In this post I present the complete source code for a project that reproduces the issue.
The project has 3 levels:
Main menu: shows 2 buttons; each button loads a level
Level_01: shows a button to return to main menu
Level_02: shows a button to return to main menu
Issue is that pressing the buttons on the levels, loads the other level instead of loading the main menu level; this happens only at a second pressing of the buttons; running the Torsion debugger shows that the OnMouseDown event is triggered, but it somehow loads the level_02 instead of the main menu level.
Loading the project this level shows up:

Pressing one button loads this level:

Pressing the other button loads this level:

Issue is that after some level switching the level_01 button (that should load the main menu level) starts loading the level_02
This is the code for the button class that loads the main menu level
Download complete project from here
Platform: Tried in Windows only; complete project attached.
Issue:
While trying to extend this resource to work with 3 levels I found some unexpected behavior. At this moment I am not sure if it is an engine bug or some incorrect use of the function loadSceneGraph, shown in the resource
Torque Minimal Template -- Part 5. Levels and sound
In this post I present the complete source code for a project that reproduces the issue.
The project has 3 levels:
Main menu: shows 2 buttons; each button loads a level
Level_01: shows a button to return to main menu
Level_02: shows a button to return to main menu
Issue is that pressing the buttons on the levels, loads the other level instead of loading the main menu level; this happens only at a second pressing of the buttons; running the Torsion debugger shows that the OnMouseDown event is triggered, but it somehow loads the level_02 instead of the main menu level.
Loading the project this level shows up:

Pressing one button loads this level:

Pressing the other button loads this level:

Issue is that after some level switching the level_01 button (that should load the main menu level) starts loading the level_02
This is the code for the button class that loads the main menu level
function ButtonHome::onMouseDown( %this, %modifier, %worldPosition, %clicks )
{
loadSceneGraph( MainMenuSceneGraph );
}Download complete project from here
#2
08/14/2011 (1:12 pm)
file level_01.cs//---------------------------------------------------------------------------------------------
// level_01.cs
//---------------------------------------------------------------------------------------------
// .....................................................................................
function SceneGraphLevel_01::OnAdd(%this)
{
createButton( %this, "ButtonHome", "ButtonHomeImageMap", 0, 0, 128, 128);
%this.CreateBackground();
makeTextObject( %this, "I am in Level 1");
}
// .....................................................................................
function SceneGraphLevel_01::CreateBackground( %this )
{
%obj = new t2dStaticSprite()
{
scenegraph = %this;
};
%obj.setVisible( true );
%obj.setLayer( 20 );
%obj.setImageMap( "BackgroundImageMap" );
%obj.setSize( 768, 1024 );
}
#3
08/14/2011 (1:14 pm)
file level_02.cs//---------------------------------------------------------------------------------------------
// level_02.cs
//---------------------------------------------------------------------------------------------
// .....................................................................................
function SceneGraphLevel_02::OnAdd(%this)
{
%this.CreateBackground();
createButton( %this, "ButtonHome", "ButtonHomeImageMap", 0, 0, 128, 128);
makeTextObject( %this, "I am in Level 2");
}
// .....................................................................................
function SceneGraphLevel_02::CreateBackground( %this )
{
%obj = new t2dStaticSprite()
{
scenegraph = %this;
};
%obj.setVisible( true );
%obj.setLayer( 20 );
%obj.setImageMap( "BackgroundImageMap" );
%obj.setSize( 768, 1024 );
}
#4
08/14/2011 (1:15 pm)
file main.cs PART1// main.cs
// (c) Pedro Vicente
// iTorque2D, Torque2D minimal template
// Notes: folders are
// /data/images -- where we store images
// /data/fonts -- store fonts
// /scripts -- game script code
function createButton( %scenegraph_obj, %class, %image_map, %xpos, %ypos, %xsize, %ysize )
{
%obj = new t2dStaticSprite()
{
scenegraph = %scenegraph_obj;
class = %class;
useMouseEvents = "1";
};
%obj.setVisible( true );
%obj.setImageMap( %image_map );
%obj.setPosition( %xpos, %ypos );
%obj.setSize( %xsize, %ysize );
}
// .......................................................................................
function makeTextObject( %scenegraph_obj, %text)
{
%obj = new t2dTextObject()
{
scenegraph = %scenegraph_obj;
text = "";
textAlign = "Center";
font = "Times New Roman Bold";
hideOverflow = false;
autoSize = true;
Visible = true;
blendIgnoreTextureAlpha = "0";
wordWrap = "0";
hideOverflow = "0";
aspectRatio = "1";
lineSpacing = "0";
characterSpacing = "0";
autoSize = "1";
filter = "1";
integerPrecision = "1";
noUnicode = "0";
hideOverlap = "0";
};
%fontsize = 48;
%obj.removeAllFontSizes();
%obj.addFontSize( %fontsize );
%obj.LineHeight = %fontsize + 10;
%obj.setBlendColor( 0.0, 0.0, 0.0, 1.0 );
%obj.setSize( 40 );
%obj.setLayer( 5 );
%obj.setVisible( true );
%obj.setPosition( 0, -200 );
%obj.text = %text;
return %obj;
}
function setScreenModeWindows()
{
if( $platform $= "windows" )
{
if ( $pref::iDevice::ScreenOrientation == $iDevice::constant::Landscape )
{
if( $platform_simul $= "ipad" )
setScreenMode( 1024, 768, 32, false );
else
setScreenMode( 960, 640, 32, false );
}
if ( $pref::iDevice::ScreenOrientation == $iDevice::constant::Portrait )
{
if( $platform_simul $= "ipad" )
setScreenMode( 768, 1024, 32, false );
else
setScreenMode( 640, 960, 32, false );
}
}
}
function initCanvas(%name)
{
if (!createCanvas(%name))
{
quit();
return;
}
}
function resetCanvas()
{
if (isObject(Canvas))
{
Canvas.repaint();
}
}
dbgSetParameters( 6060, "password", false );
setRandomSeed();
$pref::Video::displayDevice = "OpenGL";
$Gui::fontCacheDirectory = expandFilename("data/fonts");
$iDevice::constant::iPhone = 0;
$iDevice::constant::iPad = 1;
$iDevice::constant::iPhone4 = 2;
$iDevice::constant::Landscape = 0;
$iDevice::constant::Portrait = 1;
$pref::iDevice::iAdOnTop = 1;
$pref::iDevice::ScreenOrientation = $iDevice::constant::Portrait;
$platform_simul = "iphone";
$musicStreamHandle = 0;
$Game::UsesAudio = 1;
$is_iDevice = false;
$debug_mode = true;
///
/// Audio
///
$pref::Audio::driver = "OpenAL";
$pref::Audio::forceMaxDistanceUpdate = 0;
$pref::Audio::environmentEnabled = 0;
$pref::Audio::masterVolume = 0.8;
exec("scripts/audio.cs");
if( $platform $= "iphone" )
{
$pref::iDevice::DeviceType = $iDevice::constant::iPhone;
}
else if( $platform $= "iphone4" )
{
$pref::iDevice::DeviceType = $iDevice::constant::iPhone4;
}
else if( $platform $= "ipad" )
{
$pref::iDevice::DeviceType = $iDevice::constant::iPad;
}
new GuiCursor(DefaultCursor)
{
hotSpot = "4 4";
renderOffset = "0 0";
bitmapName = "data/images/cursor";
};
initCanvas("Game");
// Start up the audio system.
if( $Game::UsesAudio )
initializeOpenAL();
// Set a default cursor.
Canvas.setCursor(DefaultCursor);
Canvas.showCursor();
#5
08/14/2011 (1:17 pm)
file main.cs PART2//---------------------------------------------------------------------------------------------
// GuiDefaultProfile is a special profile that all other profiles inherit defaults from. It
// must exist.
//---------------------------------------------------------------------------------------------
new GuiControlProfile (GuiDefaultProfile)
{
tab = false;
canKeyFocus = false;
hasBitmapArray = false;
mouseOverSelected = false;
// fill color
opaque = true;
fillColor = "0 0 0";
fillColorHL = "244 244 244";
fillColorNA = "244 244 244";
// border color
border = 1;
borderColor = "40 40 40 100";
borderColorHL = "128 128 128";
borderColorNA = "64 64 64";
// font
fontType = "Arial";
fontSize = 14;
fontColor = "0 0 0";
fontColorHL = "32 100 100";
fontColorNA = "0 0 0";
fontColorSEL= "80 80 80";
// bitmap information
bitmap = "";
bitmapBase = "";
textOffset = "0 0";
// used by guiTextControl
modal = true;
justify = "left";
autoSizeWidth = false;
autoSizeHeight = false;
returnTab = false;
numbersOnly = false;
cursorColor = "0 0 0 255";
// sounds
soundButtonDown = "";
soundButtonOver = "";
};
new GuiControl(mainScreenGui)
{
canSaveDynamicFields = "0";
isContainer = "1";
Profile = "GuiDefaultProfile";
HorizSizing = "width";
VertSizing = "height";
Position = "0 0";
canSave = "1";
Visible = "1";
hovertime = "1000";
new t2dSceneWindow(sceneWindow2D)
{
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiDefaultProfile";
HorizSizing = "width";
VertSizing = "height";
Position = "0 0";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiDefaultProfile";
hovertime = "1000";
lockMouse = "0";
useWindowMouseEvents = "1";
useObjectMouseEvents = "1";
};
};
//landscape
if ( $pref::iDevice::ScreenOrientation == $iDevice::constant::Landscape )
{
if( $platform $= "iphone" || $platform_simul $= "iphone")
{
mainScreenGui.Extent = "480 320";
sceneWindow2D.Extent = "480 320";
}
else if( $platform $= "ipad" || $platform_simul $= "ipad")
{
mainScreenGui.Extent = "1024 768";
sceneWindow2D.Extent = "1024 768";
}
else if( $platform $= "iphone4" || $platform_simul $= "iphone4")
{
mainScreenGui.Extent = "960 640";
sceneWindow2D.Extent = "960 640";
}
}
//portrait
else if ( $pref::iDevice::ScreenOrientation == $iDevice::constant::Portrait )
{
if( $platform $= "iphone" || $platform_simul $= "iphone")
{
mainScreenGui.Extent = "320 480";
sceneWindow2D.Extent = "320 480";
}
if( $platform $= "ipad" || $platform_simul $= "ipad")
{
mainScreenGui.Extent = "768 1024";
sceneWindow2D.Extent = "768 1024";
}
else if( $platform $= "iphone4" || $platform_simul $= "iphone4")
{
mainScreenGui.Extent = "640 960";
sceneWindow2D.Extent = "640 960";
}
}
Canvas.setContent(mainScreenGui);
setScreenModeWindows();
exec("scripts/datablocks.cs");
exec("scripts/level_01.cs");
exec("scripts/level_02.cs");
exec("scripts/menu.cs");
#6
08/14/2011 (1:23 pm)
file main.cs PART3function loadSceneGraph( %scenegraph_name )
{
%scenegraph = sceneWindow2D.getSceneGraph();
if (isObject(%scenegraph))
{
%sceneObjectList = %sceneGraph.getSceneObjectList();
// And finally, notify all the objects that they were loaded.
for (%i = 0; %i < getWordCount(%sceneObjectList); %i++)
{
%sceneObject = getWord(%sceneObjectList, %i);
if( %sceneObject.isMethod( "onLevelEnded" ) )
%sceneObject.onLevelEnded(%sceneGraph);
}
// Notify the scenegraph that the level ended.
if( %sceneGraph.isMethod( "onLevelEnded" ) )
%sceneGraph.onLevelEnded();
%scenegraph.clearScene(true);
}
if (isObject(%scenegraph))
{
if( isObject( %scenegraph.getGlobalTileMap() ) )
%scenegraph.getGlobalTileMap().delete();
%scenegraph.delete();
}
if ( $pref::iDevice::ScreenOrientation == $iDevice::constant::Landscape )
{
if( $platform $= "ipad" || $platform_simul $= "ipad")
{
%scenegraph = new t2dSceneGraph( %scenegraph_name )
{
cameraPosition = "0 0";
cameraSize = "1024 768";
};
}
else
{
%scenegraph = new t2dSceneGraph( %scenegraph_name )
{
cameraPosition = "0 0";
cameraSize = "960 640";
};
}
}
else if ( $pref::iDevice::ScreenOrientation == $iDevice::constant::Portrait )
{
if( $platform $= "ipad" || $platform_simul $= "ipad")
{
%scenegraph = new t2dSceneGraph( %scenegraph_name )
{
cameraPosition = "0 0";
cameraSize = "768 1024";
};
}
else
{
%scenegraph = new t2dSceneGraph( %scenegraph_name )
{
cameraPosition = "0 0";
cameraSize = "640 960";
};
}
}
sceneWindow2D.setSceneGraph(%scenegraph);
%scenegraph.performPostInit();
%cameraPosition = sceneWindow2D.getCurrentCameraPosition();
%cameraSize = t2dVectorSub(getWords(sceneWindow2D.getCurrentCameraArea(), 2, 3),
getWords(sceneWindow2D.getCurrentCameraArea(), 0, 1));
if (%scenegraph.cameraPosition !$= "")
%cameraPosition = %scenegraph.cameraPosition;
if (%scenegraph.cameraSize !$= "")
%cameraSize = %scenegraph.cameraSize;
sceneWindow2D.setCurrentCameraPosition(%cameraPosition, %cameraSize);
}
loadSceneGraph( MainMenuSceneGraph );
//---------------------------------------------------------------------------------------------
// onExit
// Called when the engine is shutting down.
//---------------------------------------------------------------------------------------------
function onExit()
{
%scenegraph = sceneWindow2D.getSceneGraph();
%scenegraph.getGlobalTileMap().delete();
%scenegraph.delete();
}
#7
08/14/2011 (4:40 pm)
file datablocks.csnew t2dImageMapDatablock(BackgroundImageMap)
{
imageName = "data/images/bk_menu.png";
imageMode = "FULL";
};
//---------------------------------------------------------------------------------------------
// buttons
//---------------------------------------------------------------------------------------------
new t2dImageMapDatablock(ButtonHomeImageMap)
{
imageName = "data/images/button_home.png";
imageMode = "FULL";
};
new t2dImageMapDatablock(ButtonPlayImageMap)
{
imageName = "data/images/button_play.png";
imageMode = "FULL";
};
new t2dImageMapDatablock(ButtonLevelImageMap)
{
imageName = "data/images/button_level.png";
imageMode = "FULL";
};
//---------------------------------------------------------------------------------------------
// audio
//---------------------------------------------------------------------------------------------
new AudioDescription(SoundOnce)
{
volume = 1.0;
type = 0;
isLooping = false;
is3D = false;
};
new AudioProfile(beepSound)
{
filename = "data/audio/beep.wav";
description = "SoundOnce";
preload = true;
};
//---------------------------------------------------------------------------------------------
// button classes
//---------------------------------------------------------------------------------------------
// .......................................................................................
function ButtonHome::onMouseDown( %this, %modifier, %worldPosition, %clicks )
{
loadSceneGraph( MainMenuSceneGraph );
alxPlay("beepSound");
}
// .......................................................................................
function Level_01_Button::onMouseDown( %this, %modifier, %worldPosition, %clicks )
{
loadSceneGraph( SceneGraphLevel_01 );
alxPlay("beepSound");
}
// .......................................................................................
function Level_02_Button::onMouseDown( %this, %modifier, %worldPosition, %clicks )
{
loadSceneGraph( SceneGraphLevel_02 );
alxPlay("beepSound");
}
#8
But the issue is that the code below is *also* called, the code for the button that loads the level_02. Question is: why is this function being called ?
08/14/2011 (7:26 pm)
a little bit of Torsion debugging shows that the issue is when the "home" button is pressed, this code here is executed, which is OK// .......................................................................................
function ButtonHome::onMouseDown( %this, %modifier, %worldPosition, %clicks )
{
loadSceneGraph( MainMenuSceneGraph );
alxPlay("beepSound");
}But the issue is that the code below is *also* called, the code for the button that loads the level_02. Question is: why is this function being called ?
function Level_02_Button::onMouseDown( %this, %modifier, %worldPosition, %clicks )
{
loadSceneGraph( SceneGraphLevel_02 );
alxPlay("beepSound");
}
#9
08/15/2011 (6:21 am)
Too much for me to debug here in the forum. I'll download the project to see if anything shows up in my debugging. I'm debugging two other users' projects right now, so I probably would not get to this today. If I do see something unusual from the forum, I will let you know.
#10
A solution that avoids this behavior was posted here
www.garagegames.com/community/forums/viewthread/127309/2#comment-814121
Many thanks to Daniel Liverance
08/15/2011 (8:48 am)
Thanks Michael.A solution that avoids this behavior was posted here
www.garagegames.com/community/forums/viewthread/127309/2#comment-814121
Many thanks to Daniel Liverance
Torque 3D Owner Pedro Vicente
Space Research Software LLC
//--------------------------------------------------------------------------------------------- // menu.cs //--------------------------------------------------------------------------------------------- // ..................................................................................... function MainMenuSceneGraph::OnAdd(%this) { createButton( %this, "Level_01_Button", "ButtonPlayImageMap", 0, 0, 128, 128); createButton( %this, "Level_02_Button", "ButtonLevelImageMap", 0, 300, 128, 128); %this.CreateBackground(); makeTextObject( %this, "I am in the Main menu"); } // ..................................................................................... function MainMenuSceneGraph::CreateBackground( %this ) { %obj = new t2dStaticSprite() { scenegraph = %this; }; %obj.setVisible( true ); %obj.setLayer( 20 ); %obj.setImageMap( "BackgroundImageMap" ); %obj.setSize( 768, 1024 ); }