Game Development Community

cloneWithBehaviors purpose

by rennie moffat · in Torque Game Builder · 09/11/2009 (4:07 pm) · 5 replies

Hi, I am just going over some code, specifically the timerShootsBehavior. I have come across a portion which uses "cloneWithBehaviors". I am simply wondering exactly what this is for. I am assuming that it is used in this case, since my gun will be fring many bullets, that all "bullets" will have the same properties. Am I correct?


line of code..
%projectile = %this.projectile.cloneWithBehaviors();



full script of function
function TimerShootsBehavior::fire(%this)
{
   if (!isObject(%this.projectile))
      return;
   
   %projectile = %this.projectile.cloneWithBehaviors();
   
   %projectile.setPosition(%this.owner.position);
   %projectile.setRotation(%this.owner.rotation);
   %projectile.setLinearVelocityPolar(%this.owner.rotation, %this.projectileSpeed);
   
   %min = (%this.fireRate - %this.fireRateVariance) * 1000;
   %max = (%this.fireRate + %this.fireRateVariance) * 1000;
   %random = getRandom(%min, %max);
   %this.schedule(%random, "fire");
}

About the author

My thanks to Garage Games and the Garage Games Community combined with owned determination I got one game up, Temple Racer and I am looking to build more interesting, fun games for the mass market of the iOS app store.


#1
09/11/2009 (4:23 pm)
Rennie,

I just replied to your 'owner' question and you should read that before reading this reply...

OK, assuming you read my other reply, let's extend the discussion of behaviors started in that reply.

In TGB, we can attach multiple 'behavior' instances to game objects, making it easy to create complex game objects while re-using small bits of code.

In the original TGB (before behaviors), there was a function called clone(). This function would create a carbon copy of the current game object.

Then, a few years ago, the TGB feature set was extended and the behaviors feature was added.

We still had the clone() function, and you might think that it could just be extended to also include any behaviors in the cloning process. Fortunately, Melv May and the GG staff are savvy programmers, because merely adding more functionality to an existing function would be BAD. i.e. It might break peoples code and games.

So, without blathering on too much longer, Melv (or someone on the GG staff) added cloneWithBehaviors(). Now, when you want to clone a game object and you want to make copies of all the behaviors too, you simply use this function.

I hope this clears up your question for you.
#2
09/11/2009 (4:30 pm)
yes and no.

why and what would I be cloning?

for instance, I have objectX with ZBehavior. Where does it go from there? anytime objectX appears again? a little shakey here.
#3
09/11/2009 (5:09 pm)
Rennie,

I've looked at the code above and I can see why this is probably confusing.


function TimerShootsBehavior::fire(%this)


The above function is associated with a behavior (TimerShootsBehavior). In all likelihood, if you look at the file where this function is defined, you will find a call to moveMap.bind() which binds a key or button to the 'fire()' function, or to another function that will call fire().

When the key or button is pressed, the engine will cause 'fire()' to be called.

As soon as 'fire()' executes it will check to see if the behavior instance (%this) has a valid object ID in a field named 'projectile'. If it fails to find a valid ID, the function will exit.
if (!isObject(%this.projectile)) return;

If a valid is found, then by examining the names used I can make the assumption that %this.projectile is meant to contain the ID of a game object representing a bullet or some other projectile. Furthermore, I can ascertain that this game object probably has one or more behaviors attached to it. (Remember, behaviors are used to add attributes, features, and behaviors to game object.)

Further down in the fire() function, a cloned copy of the existing projectile is created and it is created with new instances of all behaviors that were attached to the original game object (projectile whose ID we found in %this.projectile).
%projectile = %this.projectile.cloneWithBehaviors();
   
   %projectile.setPosition(%this.owner.position);
   %projectile.setRotation(%this.owner.rotation);
   %projectile.setLinearVelocityPolar(%this.owner.rotation, %this.projectileSpeed);

Finally, the code does some calculations to determine a time range (min-max) in which to call the fire() function again. Then it schedules another call.
%min = (%this.fireRate - %this.fireRateVariance) * 1000;
   %max = (%this.fireRate + %this.fireRateVariance) * 1000;
   %random = getRandom(%min, %max);
   %this.schedule(%random, "fire");


I'm sorry if this is confusing, but I guess the things I hope you get out of this are:

1. There is an object in your game which has an instance of the behavior 'TimerShootsBehavior' attached to it.
Pseudo code:
GAMEOBJECT -> TimerShootsBehavior (behavior instance attached to game object)


2. At some time (before fire() is called) another game object is created to represent a projectile and that object's ID is assigned to a field named 'projectile' in the behavior instance 'TimerShootsBehavior' which is attached to the game object mentioned in #1.
Pseudo code:
%projectile = new projectile();
GAMEOBJECT -> TimerShootsBehavior.projectile = %projectile;

3. The projectile game object itself has other behavior(s) attached to it.

4. Finally, something causes fire() to be called and when that happens, fire() tries to make a carbon copy of the projectile from #2, including any behaviors the original projectile had. If fire() is successful, you will now have the original projectile, and a new projectile. This new projectile will initially be placed using the same rotation and position as the object from #1. It will then be given a initial velocity and be sent on its way.
#4
09/18/2009 (11:19 pm)
Off topic a bit: Looking back on that code (I wrote it quite a while back now, wow!), I should have commented it all better. I had mistakenly assumed that the functions were simple enough to not need documentation, but without the context of the behavior shooter and plenty of TGB background, behaviors can be very confusing. A big problem is that the connections between templated objects are very hard to view.

In any case, Rennie, I'd recommend making sure you completely understand the couple of behavior demos before diving into using behaviors. Getting a grasp on how to template and link objects using behaviors can be painful task.
#5
09/19/2009 (12:12 am)
My overall logic and what is possible and why, and how to see it, as I read a preprogrammed piece is pretty sound, however, my trouble and where I go from here (in learning) is being able to write it.










While not a pressing issue the "cloneWithBehaviors" is somewhat puzzling to me in it's use.