Game Development Community

Class implementation in TorqueScript. Base class member not accessible

by Andy Hawkins · in Torque Developer Network · 05/09/2012 (4:19 am) · 5 replies

I'm doing a tutorial on using OOP in TorqueScript and I have this example. Everything else works well except for the last example where I want the Parrot to access the mana attribute from the base class. It's doesn't - it's just blank. What's the correct way to make this happen?
new ScriptObject( Enemy )
{
   health = 100;
   hasSpecialAttack = false;
   lives = 3;
   mana = 10;
};

function Enemy::delete(%this)
{
   echo("Parent deleted");
}

function Enemy::talk(%this)
{
   echo("I am of type Enemy");
}

new ScriptObject( Enemy1 )
{
   superclass = Enemy;
   health = 20;
   hasSpecialAttack = true;
   lives = 5;

};

function Enemy1::delete()
{
   echo("Child deleted");
   parent::delete();
}

function Enemy1::talk(%this)
{
   // example of overriding
   echo("My parent is of type Enemy");
}

new ScriptObject( Parrot : Enemy1 )
{
   superclass = Enemy;
   health = 25;
};
function Parrot::talk(%this)
{
   // example of polymorphism
   echo("Wrrraarrkkk!");
}

$enemy1 = new ScriptObject( :Enemy1 ) 
{
   class = Enemy1;
};
$enemy2 = new ScriptObject( :Parrot ) 
{
   class = Parrot;
};

$enemy1.talk();
$enemy1.delete();

$enemy2.talk();
// easily modify only somethings of a new object
echo($enemy2.lives);   // parrot has same lives as Enemy1 (parent)
echo($enemy2.health);  // but has independent health
echo($enemy2.mana);    // and gets mana from base class (Enemy)  !!!!!! ONLY IT DOESN'T GET LOADED WITH ANYTHING
$enemy2.delete();

#1
05/09/2012 (6:33 am)
echo($enemy2.getSuperClassNamespace().mana);

It works but seems somewhat excessive ...
#2
05/09/2012 (8:01 am)
Yeah I was kinda hoping TorqueScript implied that instead of me having to type it. Seems a little less elegant.
#3
05/09/2012 (9:27 am)
The issue is that 'Enemy1' is a child of 'Enemy' but doesn't inherit from 'Enemy'. If you try to echo($enemy1.mana); you'll get a blank return as well.

In order for children to access parent class data fields they have to inherit them. Try changing the Enemy1 declaration to: new ScriptObject(Enemy 1 : Enemy)

Now, if you just want to access a parent class's data field in a child class Steve's method (or a simple <childClass>.superClass.<whatever>) will work.
#4
05/10/2012 (3:59 am)
I have implemented it but it doesn't like classes to be linked with t2dAnimatedSprites. So how am I supposed to have classes then?

new ScriptObject( Enemy )
{
   health = 25;
   hasSpecialAttack = false;
   mana = 100;
   lives = 1;
   x = 0;
   y = 0;
   direction = 0;
};

new t2dAnimatedSprite(Bunny3) {
      animationName = "EnemyStandAnimation";
      canSaveDynamicFields = "1";
      superclass = "Enemy";
      class = "Enemy1";
      Position = "-66.250 28.750";
      size = "12.500 12.500";
      CollisionActiveSend = "1";
      CollisionPhysicsSend = "0";
      CollisionPhysicsReceive = "0";
      CollisionGroups = "1";
      CollisionCallback = "1";
         mountID = "15";
      _behavior0 = "EnemyBehavior";
      _behavior1 = "HealthBar	offsetY	-4	background	healthRedImageMap	foreground	healthGreenImageMap";
      _behavior2 = "SetScore	score	150";
   };
Error: cannot change namespace parent linkage of Enemy from ScriptObject to t2dAnimatedSprite.
Error: cannot change namespace parent linkage of Enemy1 from Enemy to t2dAnimatedSprite.
#5
05/10/2012 (1:35 pm)
That sort of thing isn't possible in TScript. ScriptObjects aren't 'real' classes, they're more like namespaces so they have to be self-contained.

What I would do is add another field to your Enemy class(es) that holds a reference to your t2dAnimatedSprites. Something like:

new ScriptObject(Enemy)
{
    health = 25;
    hasSpecialAttack = false;
    mana = 100;
    lives = 1;
    x = 0; // may not be needed as you can access the Position field of the actual 2D object
    y = 0; // same as above
    direction = 0; // same as above?

    // ### new field ###
    animSprite = -1;
};

// create your t2dAnimatedSprite and pass in the id to this method
function Enemy::linkSprite(%this, %spriteObj)
{
    %this.animSprite = %spriteObj;
}