Game Development Community

FxStaticSprite2D - small reference only

by Andy Hawkins · in Torque Game Builder · 12/26/2006 (12:43 am) · 9 replies

Why is there only one reference to fxStaticSprite2D in TDN and none in the latest TGB manual?

There appears to be no documentation on it, but I believe it's the standard way to make sprites on the fily.

Why is it different to the level description of a sprite?

From code...

%test = new t2dAnimatedSprite2D() { sceneGraph = t2dSceneGraph; };


...and from Level data....


new t2dAnimatedSprite() {
      animationName = "TileSet1Animation6";
      canSaveDynamicFields = "1";
      position = "56.098 -14.677";
      size = "12.000 12.000";
         mountID = "8";
   };

#1
12/26/2006 (3:08 am)
I think you may be barking up the wrong tree? :p The fx methods were taken out and replaced with t2d functions:

t2dStaticSprite
#2
02/03/2007 (4:29 pm)
@Andy, if your question is why the level builder adds so much extra 'data' ... it's because it stores all the relevant information about the sprite --

the two code snippets you showed, are identical, with the exception of the following;

1) snippet one assigns the 'id' value of the newly created sprite to a local scope variable
2) snippet two assigns values to the more common dynamic fields, and retains information required for the object to be in a 'level' (these values are also set by snippet one, however, snippet one is not assigning size/position so it defaults to (iirc) 1,1 for size and 0,0 for position.
3) snippet one assigns the object to a scenegraph explicitly
4) snippet two within a level script, so the objects created are automatically attached to the scenegraph that is loading the level (sceneWindow2D.loadLevel contains a SceneGraph of its own)


the difference between 'fx' and 't2d' is negligible as Teck mentioned, 'fx' was the old T2D (TGB Alpha/Beta) naming scheme, and 't2d' is the new 'TGB' naming scheme (odd, eh?)

#3
02/03/2007 (5:24 pm)
@David - thanks for the explanation, that clears a few things up.

While I was scripting last night I found I had to explicitely add my new sprites to the scenegraph whereas in WhackAMole they do not - can you explain why?

My code (WhackAMole below)
// My Level respawn spots
exec("./Respawn_Points.cs");

$Total_Men = 0;


 function MyLevel::CreateMan(%sceneGraph)
{
   cancel($SpawnMan);
 
   if ($Total_Men > 8) return;
     
   %man[$Total_Men] = new t2dAnimatedSprite() {
      animationName = "Man1_FallingAnimation";
      canSaveDynamicFields = "1";
      position = "0 0";
      size = "16.000 16.000";
         mountID = "9";
   };
   
   %sceneGraph.addToScene(%man[$Total_Men]);
   
   //pick a random spot  from the list of respawn points
   %cnt = 10;  // try 10 times or quit
   for (%i = 0; %i < %cnt; %i ++)
   {
      %randSpot = getRandom(0,$TotalRespawn_Points);
      if ($RespawnPoint_used[%randSpot] == false)
      {
         %man[$Total_Men].setPosition($RespawnPoint_x[%randSpot],$RespawnPoint_y[%randSpot]);
         $RespawnPoint_used[%randSpot] = true;

         // call this again to spawn a new man in 1 second
         $SpawnMan = schedule(1000,0,MyLevel::CreateMan(%sceneGraph));
         $Total_Men ++;
         return;
      }
   }
   
  // or delete if there are no more spots 
   %sceneGraph.removeFromScene(%man[$Total_Men]);
   
}

WhackAMole code...
function moleLevel::spawnMole(%this)
{
   // find a spawn point
   %respawnPointIndex = getRandom( %this.respawnPointSet.getCount()-1 );
   %respawnPoint = %this.respawnPointSet.getObject( %respawnPointIndex );

   // select a color for the mole
   %color = getRandom(2);
   if( %color == 0 )
      %color = "red";
   if( %color == 1 )
      %color = "green";
   if( %color == 2 )
      %color = "lilac";


   // create a new Mole
   %mole = new t2dAnimatedSprite()
   {
      sceneGraph = %this;
      class = "mole";
      layer = 4;
      size = "9 16";
   };

   // play right animation according to the color
   %mole.playAnimation("animMoleComeOut" @ %color);


   // save the selected color as dynamic field
   %mole.moleColor = %color;

   // set the position of the mole to the position
   // of the respawn point
   %mole.setPosition( %respawnPoint.getPosition() );
}
#4
02/03/2007 (5:32 pm)
@Andy, if you look at the creation of the t2dAnimatedSprite in the WhackAMole code, you'll notice that the 'sceneGraph' is explicitly set in the 'new t2dAnimated() { };' block ... the scene in mention is '%this', as 'moveLevel' is the class name of the 'scenegraph' in the level.

I've not read the WhackAMole tutorial, but if they do this, I would think they identified that in the tutorial, did they not?

That or they are calling the spawnMole method as a 'static' method, ie; refering to it as "moleLevel::respawnMole(%sceneGraphReferencePassedHere)" and just misrepresenting it by naming it "%this" (the standard name of the first parameter in every class function)
#5
02/03/2007 (7:09 pm)
Well maybe - but I didn't see it. Mind you, I read it, and others, from the reference of trying to find code that created a sprite and added it to the sceneGraph so in all fairness I didn't read the tute or do it, from start to finish. So I could have quite easily missed something.

What you say makes sense though, but the context in which %this is valid, eludes me. As you say, it would seem they are using %this incorrectly. As far a I knew it, %this is always passed to any function as an obligatory first parameter, and in this case they are overriding it.
#6
02/03/2007 (7:20 pm)
I just did quick ammendment to my code as it works as you say. The animated sprite has member data that passes it to 2d window I assume in the form on the sceneGraph member... I commented out the explicit call to add it to the scene graph and it works. Thanks again for the explanation - this is what is happening in WhackAMole as well.

function MyLevel::CreateMan(%sceneGraph)
{
...
    %man[$Total_Men] = new t2dAnimatedSprite() {
      sceneGraph = %sceneGraph;                                // <- passed into function
      animationName = "Man1_FallingAnimation";
      canSaveDynamicFields = "1";
      position = "0 0";
      size = "16.000 16.000";
         mountID = "9";
   };

   //%sceneGraph.addToScene(%man[$Total_Men]);   // <- commented out

...
}
#7
02/03/2007 (7:32 pm)
Further to this I found that schedule calls this function again immediately, when it should be called after 1 second...is there an error in my scheduling function (getting a bit off topic now I think...)

$SpawnMan = schedule(1000,0,MyLevel::CreateMan(%sceneGraph));
#8
02/03/2007 (7:56 pm)
Meh! Fixed it...

SpawnMan = schedule(1000,0,"MyLevel::CreateMan",%sceneGraph);

I made the mistake of trying to pass the %sceneGraph var as you would in a normal function called. schedule prefers to delineate params with commas. Also the class needed quotes to compile without error - though I don't know why.
#9
02/03/2007 (9:22 pm)
@Andy, the reason for the schedule mishap is simple:

schedule() takes in four parameters, the first is the time interval to schedule the event on, the next is the object containing the function, or nothing (in your case, you passed 0, which is also valid, most people pass 'false'), the third is the function to call, which, if the second parameter is passed, is called as such "object.function()", the four are the parameters to pass -- can't remember off hand if schedule accepts any number of parameters after the function, or expects them all to be in a string (ie; %param1 SPC %param2 SPC %param3).

The reason schedule works in this manner is because it compiles the function call "on the fly", much like this:

function schedule(%interval, %object, %function, %params)
{
  %cmd = %object @ "." %function @ "(" @ replace(%params, " ", ",") @ ");";
  eval(%cmd);
}


Now, mind you, it does -NOT- actually work that way, but that's a quick and dirty intro to the internals of "schedule" and how it operates -- it basically creates the script call "on the fly".

Hope that helps clear things up.