Game Development Community

SceneGraph nesting

by Tomas Lazaro · in Torque Game Builder · 02/18/2011 (4:16 pm) · 7 replies

I'm trying to do some nesting, having a StaticSprite inside a SimSet or SimGroup. I doesn't seem doable.

I'm editing the Scene file directly so I can see the results in the editor.

Has anyone tried something like this? Does somebody edit the scene file or just add code on the onLoad method?

%levelContent = new t2dSceneGraph() {
   canSaveDynamicFields = "1";
   UseLayerSorting = "1";
   layerSortMode0 = "Normal";
   // [...] omitted
   layerSortMode31 = "Normal";
   DebugRendering = "0";
      cameraPosition = "512 384";
      cameraSize = "1024 768";

   new t2dStaticSprite () {
      imageMap = "ho_test_bg";
      frame = "0";
      useSourceRect = "0";
      sourceRect = "0 0 0 0";
      canSaveDynamicFields = "1";
      Position = "512.000 384.000";
      size = "1024.000 768.000";
      mountID = "2";
   };

   new SimObject() {
      new t2dStaticSprite () {
         imageMap = "ho_test_circle";
         frame = "1";
         useSourceRect = "0";
         sourceRect = "0 0 0 0";
         canSaveDynamicFields = "1";
         Position = "640.000 464.500";
         size = "36.000 55.000";
         mountID = "3";
      };
   };
};

#1
02/18/2011 (5:43 pm)
Why are you trying to nest it this way? If you could give us a description of what you are trying to accomplish, there might be a better way to do it in TorqueScript or the editor.
#2
02/18/2011 (5:56 pm)
I actually don't really care about about a complex hierarchy.

I'm attempting a Hidden Object engine. Not my first in general, I'm just trying to figure out how to do it in the "Torque way" since I'm moving to Torque now :)

I wanted to define "Items" in the Scene and those items will have a "State" associated. A State should have several properties including the most important, an image or animation. It is important for me to define it in the Scene file so it is shown in the TGB.

That nesting I tried felt natural and a quick way to try it out but it's not mandatory.

I don't mind hacking away a bunch of C++, I just want to be sure I'm taking the best road so I don't waste efforts.

In the end I want something like this:

new HOItem(somename) {
  somefield = ...
  states = new StateList() {
    new State (hidden) {
       sprite = new t2dStaticSprite() {
         ...
       };
       somefield = ...
    };
    new State (found) {
       sprite = new t2dStaticSprite() {
         ...
       };
       somefield = ...
    };
  };
  ...
};
#3
02/18/2011 (6:31 pm)
I'd edit the objects needed in the graphical editor. Then you can easily create behaviours to add all sorts of magic to each sprite. You can have a generic mouse control behaviour common to all, and additional ones to sort out scoring, replacement graphics, that sort of thing. The level builder creates the proper hierarchy for you, and you can give the scenegraph a unique name to use for a class you also prepare if you want more complicated setup for any reason. I've found behaviours to be the most useful for many reasons, though.

Since a hidden object game is very visual it's really counter-intuitive to use pure script ;)
#4
02/18/2011 (6:33 pm)
I would use a behavior for this type of things, have an enum declaring all the states that the behavior can be associate with.

%template   = new BehaviorTemplate(StatusBehavior);
   %state =  "None" NL "STATE_A" NL "STATE_B"; 
   %template.addBehaviorField(ObjectState, "hidden object state", Enum, "", %state );

Then in your behavior code, change the owner object accordingly to it's state.
#5
02/20/2011 (5:26 pm)
I'm trying out the Behavior approach and I must say it's really cool. Thanks for your advice.

I'm testing image replacing following examples on the behaviors playground but from the editor I can only select image datablocks that are in $managedDatablockSet (the ones manually added using the editor) and not images imported in a Resource or added in the user's datablock.cs.

Is there a workaround?
#6
02/20/2011 (6:29 pm)
Have you remembered to exec() the datablock file?
#7
02/20/2011 (7:14 pm)
I can see a bunch of Static Sprites in TGB to pick from in the Create panel. Those were imported as a Resource bundle and are defined in their resourceDatabase.cs.

Those images are not available from the image combo box menu inside a Behavior that declares a t2dImageDatablock field.

Only images manually imported into TGB (that end up in $managedDatablockSet) are selectable from that combo box.

I found this workaround: I can define the behavior field as a string instead of an image and manually write the image's name and it will work just as well. It's not as safe but it works.

------------------

That aside as I think I will just use frame numbers to change images for this simple behavior. I'm using linked image datablocks.

Is there a smarter way of knowing the current frame width and height? I have to write it by hand right now.

This is just a prototype. The State thing actually doesn't make sense as it is inevitably implicit in the code for this simple case.

if (!isObject(HOItem))
{
   %template   = new BehaviorTemplate(HOItem);
   
   %template.friendlyName = "HOItem";
   %template.behaviorType = "Items";
   %template.description  = "Basic HO item with found onClick";
    
   %template.addBehaviorField(width, "The width of the found image", float, 10);
   %template.addBehaviorField(height, "The height of the found image", float, 10);
}

function HOItem::onBehaviorAdd(%this)
{
   %this.owner.setImageMap(%this.owner.getImageMap(), 1);
   %this.owner.setUseMouseEvents(true);
}

function HOItem::onMouseUp(%this, %modifier, %worldPos, %a1, %a2, %a3)
{
   %this.owner.setUseMouseEvents(false);
   %this.owner.setImageMap(%this.owner.getImageMap(), 0);
   %this.owner.size = %this.width SPC %this.height;
}