Game Development Community

Adding Buttons To A Level?

by David Taylor · in Torque Game Builder · 03/11/2007 (10:58 pm) · 10 replies

I want to add guiButtonCtrl objects to my level. I initially set up a gui with them, which works fine, except that I can't track the buttons without an onLevelLoaded() call...meaning I can't move them around if I want to. Or perhaps that's just a lack of programming knowledge?

So I've set up a level that I can use to call onLevelLoaded...but how do I now add buttons to my new level? Is this at all possible?

Failing that, how can I get a set of buttons that I can track, so as to have two buttons swap places, etc?

#1
03/12/2007 (12:10 pm)
Your question is a little confusing as you refer to the gui, but then are talking about onlevelloaded.
As far as I understand it, the canvas has no loadlevel or an onlevelloaded callback. guiObjects would never be attached to the scene. They are bound to the canvas.

The canvas and the scenewindow are separate entities and need to be addressed separately.

Having clarified that you should be able to apply a name to your GUI controls and access them from within the script just as you can any other object. i.e. button1.getposition( ) button2.setPosition(x, y)

It can be tricky dealing with the various coordinate systems. They are explained in the docs and the functions for translating between to various coordinate systems

I hope that helps.
#2
03/12/2007 (12:25 pm)
All objects, including GUI Objects (iirc) contain an 'onAdd' script callback which is called when the object is created (its more specific then that, but it can generally be used to perform an object-level constructor overload in torquescript).

As for moving buttons around, the GUI uses a 0,0 coordinate system which points to the top-left of the screen, where as the scenewindow uses a 0,0 coordinate system that points to the center of the screen ... translating the two is fairly easy ...

As far as tracking buttons, you'd have to do that through code ... where in the code you would do it is relevant to the logic required for tracking ... if the button locations are dependent on activities by the user performed in the scenewindow (ie; when the player moves to a new area and a trigger ticks off an 'onEnter') then you would control the buttons in the triggers 'onEnter' callback either directly or through the use of a secondary function that is called from the 'onEnter' ...
#3
03/14/2007 (9:54 pm)
@ David: Thanks, but the onAdd is very similar to the onLevelLoaded, and is associated to t2dSceneObjects...not Gui objects.

@ Guy: I agree. My question WAS confusing, hehe! Sorry about that.

Let me try to clarify this a bit...

In a different program I was making, I had 100 coloured blocks, represented by sprites. I needed to be able to swap blocks around, so when the level loaded, it would call the following CreateBlocks function in the game block file:

function GameBlock::createBlock(%this, %blockNumber, %blockRow, %blockColumn)
{
    $blockQuantity++;
    $GameBlock[%blockNumber] = %this;
};

It's very simple, but it allowed me to track each individual block by using a for loop:
for(%i = 1; %i < $blockQuantity - 1; %i++)
        {
            // Update block names
            $blockColourName[%i] = $GameBlock[%i].getName();
        }

That way, it was easy to swap positions, and so on.

Now I want to do the same thing with buttons. A player clicks on the first button, and then a second button, and the two buttons swap positions. But I want to be able to access them in a similar manner to what I did with the sprites above. That's why I was referring to the buttons, (which are on the canvas in the gui), being called by onLevelLoaded.

The only other way I can think of doing this is scrapping the idea of buttons and putting in sprites, instead, but it feels a bit like reinventing the wheel, as I would have to create onEnter, onMouseDown, and other functions that the buttons already have working for them.

I hope that makes sense. Is there any way to go about doing this? The result is what I'm looking for, so even if it means coding it differently, without using a for loop, I'm more than happy to do that.
#4
03/14/2007 (11:13 pm)
@David, the GuiControl class in C++ does call "onAdd" in script, however, it appears to check to see if it exists first ...

// Notify Script.
   if( isMethod("onAdd") )
      Con::executef(this, 1, "onAdd");

That is in the GuiControl::onAdd in the engines source -- you may want to take a look at it, and see how it's utilized -- I placed a break point in the onAdd and when I test played my level, nothing happened ... however, when I escaped out and went back into level builder, it was called repeatedly ... so I'm thinking perhaps it doesn't get called for some things, like the generic controls in the mainScreenGui ...
#5
03/15/2007 (2:47 pm)
@David Taylor:

You register your Scene Objects by utilizing the onLevelLoaded() callback. The corresponding thing for Gui controls (subclass of class GuiControl) is onWake().

By the way, you might want to look into using class SimSet instead of an array.
$GameBlock[%blockNumber] = %this;
creates a new global variable for each individual block. The corresponding code using SimSet would be:
$GameBlockSet.add(%this);
where $GameBlockSet is created somewhere, thus
$GameBlockSet = new SimSet() ;
#6
03/18/2007 (4:40 pm)
Thanks, guys. This has proven to be really helpful.

@Arthur:

The onWake() call is exactly what I needed. I have taken your advice regarding the SimSet. Is there any documenation on precisely what a SimSet is? This is the first time I've heard of it, and while I know what commands are available to it, I'd like to know a bit more about what it actually is - not just what it can do. ;)
#7
03/18/2007 (5:31 pm)
@David Taylor: SimSet.
Quote:This is the first time I've heard of it
There is a lot of documentation linked to from TDN's Torque Game Builder landing page. You could be studying it for hours. ;-)
#8
03/19/2007 (1:09 am)
Here's a thread with some old posts of mine going over SimSets... SimGroups... and ScriptObjects (as well as useful aspects of these). Just scroll down towards the bottom of the thread.

www.garagegames.com/mg/forums/result.thread.php?qt=34240
#9
04/16/2007 (6:28 am)
@Arthur:

I notice in the notes for SimSet that it says:

Quote:
Since a SimSet is a simple list, it is possible for an object to appear more than once within a particular SimSet. This is not the case with SimGroup.

SimObjects can belong to more than one SimSet but can not be added to the same SimSet more than once as the SimObjectList implementation checks if the object already exists in the list before adding it.

Perhaps that was what you intended to convey? Perhaps:

Quote:
Objects may be added to more than one SimSet but can only belong to one SimGroup

Or some such ;p
#10
04/16/2007 (9:38 pm)
Thanks, Neo, for helping to understand the SimSet better. I have changed the SimSet reference page accordingly, including the examples.