Game Development Community

T2dScene or t2dscene object

by Eric Robinson · in Torque Game Builder · 07/12/2006 (5:49 pm) · 12 replies

I'm trying to follow the unfinished T2D Platformer tutorial. In the jumping portion of the second 'chapter' the following appears:

// FROM http://tdn.garagegames.com/wiki/Torque_2D/GenreTutorials/PlatformerMovement
function t2dSceneGraph::onUpdateScene(%this)
{
   if (%this != t2dscene.getID())
      return;

   updatePlayer();
   $runSurface = -1;
}

The thing warns that this will throw repeating warnings in the editor (which it does). However, this continues to throw the same errors when the game is running. The t2dscene object simply doesn't appear to exist. Has this been changed in the latest TGB? Is there something I'm missing from the setup?

#1
07/12/2006 (8:11 pm)
Try using sceneWindow2D.getSceneGraph() for the scengraph or just sceneWindow2D if it's the scene you need.
#2
07/12/2006 (11:57 pm)
It's not working... this:

function t2dSceneGraph::onUpdateScene(%this)
{

echo("sceneWindow2D.getID(): ", sceneWindow2D.getID());
echo("sceneWindow2D.getSceneGraph().getID()", getSceneGraph().getID());
echo("%this.getID(): ", %this.getID());

	if(%this != sceneWindow2D.getID())
		return;
	
	updatePlayer();
	$runSurface = -1;
}

prints the following to the console repeatedly:

//------------------------------------REPEATING-----------------------------------------//
sceneWindow2D.getID(): 2225
Proto1/gameScripts/game.cs (58): Unable to find function getSceneGraph
Proto1/gameScripts/game.cs (58): Unable to find object: '' attempting to call function 'getId'
sceneWindow2D.getSceneGraph().getID()
%this.getID(): 2406
sceneWindow2D.getID(): 2225
Proto1/gameScripts/game.cs (58): Unable to find function getSceneGraph
Proto1/gameScripts/game.cs (58): Unable to find object: '' attempting to call function 'getId'
sceneWindow2D.getSceneGraph().getID()
%this.getID(): 2417
sceneWindow2D.getID(): 2225
Proto1/gameScripts/game.cs (58): Unable to find function getSceneGraph
Proto1/gameScripts/game.cs (58): Unable to find object: '' attempting to call function 'getId'
sceneWindow2D.getSceneGraph().getID()
%this.getID(): 2424
sceneWindow2D.getID(): 2225
Proto1/gameScripts/game.cs (58): Unable to find function getSceneGraph
Proto1/gameScripts/game.cs (58): Unable to find object: '' attempting to call function 'getId'
sceneWindow2D.getSceneGraph().getID()
%this.getID(): 2431
sceneWindow2D.getID(): 2225
Proto1/gameScripts/game.cs (58): Unable to find function getSceneGraph
Proto1/gameScripts/game.cs (58): Unable to find object: '' attempting to call function 'getId'
sceneWindow2D.getSceneGraph().getID()
%this.getID(): 2433
sceneWindow2D.getID(): 2225
Proto1/gameScripts/game.cs (58): Unable to find function getSceneGraph
Proto1/gameScripts/game.cs (58): Unable to find object: '' attempting to call function 'getId'
sceneWindow2D.getSceneGraph().getID()
%this.getID(): 1992
sceneWindow2D.getID(): 2225
Proto1/gameScripts/game.cs (58): Unable to find function getSceneGraph
Proto1/gameScripts/game.cs (58): Unable to find object: '' attempting to call function 'getId'
sceneWindow2D.getSceneGraph().getID()
%this.getID(): 2379
sceneWindow2D.getID(): 2225
Proto1/gameScripts/game.cs (58): Unable to find function getSceneGraph
Proto1/gameScripts/game.cs (58): Unable to find object: '' attempting to call function 'getId'
sceneWindow2D.getSceneGraph().getID()
%this.getID(): 2404
//------------------------------------!REPEATING-----------------------------------------//


Any thoughts?
#3
07/13/2006 (2:20 am)
This code:

function t2dSceneGraph::onUpdateScene(%this)
{
   if (%this != t2dscene.getID())
      return;
   $camera.update();
}

Works fine for me. Have you declared this anywhere:

// Set up the scenegraph
new t2dSceneGraph(t2dScene);
// Associate the new scene graph with the scene window.
sceneWindow2D.setSceneGraph(t2dScene);

Edit - If your scenegraph is called --> T2dScene --> then you will get an error due to case sensativity.

Edit 2 - You should use getSceneGraph() like this:

%currentscenegraph = sceneWindow2D.getSceneGraph();
echo %currentscenegraph.getID();
#4
07/13/2006 (3:58 am)
That function doesn't make sense in general. Basically it's defined as a callback for all t2dSceneGraph's and then it checks to see if it's t2dScene and if it is it calls updatePlayer. I'm assuming this was done to make sure updatePlayer is called once and only once per frame. I guess that tutorial might have been created before namespaces were completely functional (though I haven't personally looked through it). The thing you have to realize is that the code you're looking at is fairly old and not optimized to work with the current version of TGB/T2D. I've been thinking about doing up-to-date platformer and RTS framework resources and tutorials but I haven't run it past the guys at the office yet and there are a few things I would need to get done before I could start on them. Either way, here is a faster and cleaner version of that function:

function t2dScene::onUpdateScene(%this)
{
   updatePlayer();
   $runSurface = -1;
}

Just replace that function with this one and it should resolve that console spam. Note that this assumes, just as the original one does, that there is a t2dSceneGraph named "t2dScene".

Also, TorqueScript is not case senstitive at all.
#5
07/13/2006 (4:04 am)
By the way, %something.getID() is exactly the same as %something. The object ID is what %something stores.
#6
07/13/2006 (4:53 pm)
Thanks for the help everyone. I'm going to give those pieces of code a shot.

The platformer tutorial is extremely dated. It's also extremely incomplete and looks to be left in somewhat of a hacked state. There's a seemingly random reference to putting "$jump = %val;" or somesuch inside of the jump call in "actionMap.cs". This is mentioned nowhere in the the tutorial otherwise. Further, they never mention defining "t2dScene" which made me think that it was something predefined for T2D levels. And, to my knowledge, it very well could have been... only to have been changed in recent builds.

There's even bugs in the code provided. For instance: if you hit a ramp while holding left and right then player movement stops. This is unique to ramps and breaks consistency in movement.

It's a good learning experience, though, in trying to hack the thing into something that works.

@Thomas: The onUpdateScene is what you say it is: a hack job. I will give the namespace idea a shot as I believe it is *much* cleaner and less computationally taxing.

Real quick question on namespaces: if I call a variable t2dScene (as in the second code block that Glenn offered), does it belong to the namespace of the same title, such that calling t2dScene::updateMe() would only affect the t2dScene variable? How would I ensure that that variable was a member of the t2dScene namespace otherwise?

I'm currently trying to implement a 'working prototype' of a platformer so that I can contextually prototype audio and visual systems/effects. I currently only need something quick and dirty. I would not go into final code without overhauling everything.
#7
07/13/2006 (4:59 pm)
@Glenn: Where exactly in the code flow should I put this:
// Set up the scenegraph
new t2dSceneGraph(t2dScene);
// Associate the new scene graph with the scene window.
sceneWindow2D.setSceneGraph(t2dScene);

In game.cs? In main.cs?
#8
07/13/2006 (11:04 pm)
So I figured out how to enable jumping without touching the t2dScene. I think I also figured out how to grab the t2dScene reference with the generic files you get when you set up a new project from the builder.

In game.cs is the following code in a clean project:
function startGame(%level)
{
   // Set The GUI.
   Canvas.setContent(mainScreenGui);
   Canvas.setCursor(DefaultCursor);
   
   moveMap.push();

   if( isFile( %level ) || isFile( %level @ ".dso"))
	{
		// Associate the new scene graph with the scene window.
		sceneWindow2D.loadLevel(%level);
	}
}
Apparently, the loadLevel function returns the t2dSceneGraph that was loaded from the level. Setting the following did not result in an error console-side when I tested the level:
function startGame(%level)
{
   // Set The GUI.
   Canvas.setContent(mainScreenGui);
   Canvas.setCursor(DefaultCursor);
   
   moveMap.push();

   if( isFile( %level ) || isFile( %level @ ".dso"))
	{
		// Associate the new scene graph with the scene window.
		[b]$t2dScene =[/b] sceneWindow2D.loadLevel(%level);
	}
}

Am I wrong in assuming that this is essentially what we wanted? I'm only working with a single level at the moment and don't have a level management system or even 'main menu' setup yet.

Fortunately I got jumping to work without any scenegraph junk. The onUpdateScene function in the Platforming tutorial is entirely superfluous. $player.runSurface is updated upon contact with another sceneObject already. Just check that value in the playerJump function you call when the player hits the jump button (set with the moveMap). There's no need to check on every frame.
#9
07/14/2006 (5:51 am)
You're mostly right. You're assigning the scenegraph object to a global variable rather than giving it a global name. You've got the right object though. The scenegraph is created in the level file itself, so you would have to edit that to change it's name (it's not named by default) or give it a name somewhere else, such as your startGame function, by calling [scenegraph].setName([name]). If you can get the same results more efficiently without using an onUpdateScene callback, then you're on the right track. As I stated above, that code was designed for an earlier version of the engine, so there will probably be several things that either don't make sense for the current version or just plain don't work anymore. It's most definitely not reccomended that you use that as a starting point or any sort of reference for learning to use TGB, and especially not for creating a game. The basic concepts still apply and it was well written, but the engine has changed a whole lot in the time since.
#10
07/14/2006 (7:14 pm)
Okay, thanks. I'm using it in conjunction with the TGB Reference files, prior [limited] experience, and general programming knowledge to get a better grasp of how the engine works. Finding bugs / issues with the old code is good practice and actually quite revealing. I've run through a couple other tutorials (shipped with the engine) so I'm fairly comfortable with the basics. There's just a lot of stuff that seems to not have been updated. This makes it difficult to find something even when I'm not following the tutorial.

Quick question: does [Object].setName([name]) change the name of that specific object or does it make it a member of the namespace [name]? I'm trying to figure out what the difference between global variable and global name is (global name == namespace?). Or does changing the name mean that I can skip out on using the $,% symbols...?
#11
07/16/2006 (11:49 pm)
So how does one translate the tutorials? For instance, there's a line in the mouse selection tutorial that goes like this:
%objList = t2dScene.pickPoint(%worldPos);
Now, I was able to get by one use of "t2dScene" by using "sceneWindow2D.getSceneGraph();". However, in the above line, I can't substitute t2dScene for that. How would one perform an action with the SceneGraph without using the t2dScene method that is no longer recommended?
#12
07/17/2006 (3:42 am)
Namespace is kinda hard to grasp at first. When you run your game TGB links all your objects to namespaces based on their name, class, superclass, and datablock fields. They are checked in that order for function calls and variables (although their C++ class always takes precedence, so you can't override functions like 'delete' via script). Name is a useful case because names are unique (only one object can have a given name), but you can also define functions on the name level. So, for example:

Create a scene window named "MyWindow":
new t2dSceneWindow(MyWindow)
{
.... (blah blah scene window stuff)
};

Then call a function on that specific window without the need of a variable
...
MyWindow.setUseObjectMouseEvents(true);
...

Or define a function for that specific window:
function MyWindow::onAdd(%this)
{
   echo("My scene window is loaded.. hooray!");
}

Namespaces are basically what allow TorqueScript to simulate an object oriented environment. I hope this was helpful.