Creating Objects in Script with a Datablock
by James Nhan · in Torque Game Builder · 02/22/2011 (10:58 am) · 14 replies
How do I create an object in my script and assign it a datablock?
I've tried this:
But I get "Unable to instantiate object of class speed." errors. I've looked and looked and read and reread the documentation, but I can't figure this out :-/
I've tried this:
%speed = new Speed()
{
datablock = \"Powerup_Speed\";
};But I get "Unable to instantiate object of class speed." errors. I've looked and looked and read and reread the documentation, but I can't figure this out :-/
#2
This is my code at the moment:
datablocks.cs
powerups.cs
Ignore the eval, I was trying multiple things that I found on Google.
02/22/2011 (1:07 pm)
The Speed object I defined in the Torque Game Builder. I made an object with class "Speed". Is there another place I have to define it?This is my code at the moment:
datablocks.cs
datablock t2dSceneObjectDatablock(Powerup_Speed)
{
Layer = 8;
Size = "4 4";
class = "speed";
CollisionCallback = true;
CollisionActiveReceive = true;
CollisionActiveSend = false;
CollisionDetectionMode = "CIRCLE";
CollisionPhysicsReceive = false;
CollisionPhysicsSend = false;
factor = 2;
time = 15000;
};powerups.cs
function Speed::onCollision(%srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts)
{
if (%dstObj.class $= "playerShip")
{
%dstObj.Speed *= %srcObj.factor;
speedTxtGUI.text = "Speed: " SPC %dstObj.Speed;
%dstObj.schedule(%srcObj.time, "speedExpire", %srcObj.factor);
%srcObj.safeDelete();
}
}
function playerShip::speedExpire(%this, %factor)
{
%this.Speed /= %factor;
speedTxtGUI.text = "Speed: " SPC %this.Speed;
}
function Powerups::Spawn(%interval, %spawn)
{
%speed = 0;
eval("%speed = new Speed() { datablock = \"Powerup_Speed\"; };");
%speed.setPositionX(getRandom(-43.0, 43.0));
%speed.setPositionY(getRandom(-30.0, 30.0));
if (%spawn)
{
schedule(%interval, "PowerupsRandomSpawn", %interval, %spawn);
}
}
function Powerups::Init()
{
Powerups::Spawn(1.0, true);
}Ignore the eval, I was trying multiple things that I found on Google.
#3
In your SpeedCreate, you want to clone this object.
You'll need to give the object a Name in addition to its Class name. Then you can clone it using it's name:
You'll probably want to set other attributes on it, too (like position, speed, whatnot).
02/22/2011 (7:47 pm)
If you look in your level file where you created this object with the class "Speed", you'll see that it's really a t2dSceneObject or a t2dStaticSprite (or something along those lines).In your SpeedCreate, you want to clone this object.
You'll need to give the object a Name in addition to its Class name. Then you can clone it using it's name:
%newPowerup = SpeedPowerup.clone(); %newPowerup.actualSpeed = %speed;
You'll probably want to set other attributes on it, too (like position, speed, whatnot).
#4
However, the cloned object won't collide.
If I echo the factor attribute it's null. It seems it's not copying the datablock attributes over. However, when I try this:
The attribute displays correctly, but it won't execute the collide function on collision with my ship.
02/23/2011 (9:35 am)
Okay, this is what I have:function speed::Spawn(%this, %interval, %spawn)
{
%speed = newSpeed.clone();
%speed.setPositionX(getRandom(-43.0, 43.0));
%speed.setPositionY(getRandom(-30.0, 30.0));
if (%spawn)
{
%this.schedule(%interval, "Spawn", %interval, %spawn);
}
}However, the cloned object won't collide.
If I echo the factor attribute it's null. It seems it's not copying the datablock attributes over. However, when I try this:
function speed::Spawn(%this, %interval, %spawn)
{
%speed = newSpeed.clone();
%speed.Layer = 8;
%speed.Size = "4 4";
%speed.class = "speed";
%speed.CollisionCallback = true;
%speed.CollisionActiveReceive = true;
%speed.CollisionActiveSend = false;
%speed.CollisionDetectionMode = "CIRCLE";
%speed.CollisionPhysicsReceive = false;
%speed.CollisionPhysicsSend = false;
%speed.factor = 2;
%speed.time = 15000;
%speed.setPositionX(getRandom(-43.0, 43.0));
%speed.setPositionY(getRandom(-30.0, 30.0));
if (%spawn)
{
%this.schedule(%interval, "Spawn", %interval, %spawn);
}
}The attribute displays correctly, but it won't execute the collide function on collision with my ship.
#5
Unfortunately, I'm always playing with the CollisionActive* and CollectionPhysics* to get what I want done. I'm sad to admit that I often break down and just use triggers attached to the object.
I don't get home until very late on Wednesday's, but I'll set an alarm to remind me to post how I handle this situation.
02/23/2011 (10:22 am)
You're second example is how I often end up doing things (I, too, have had problems with clone).Unfortunately, I'm always playing with the CollisionActive* and CollectionPhysics* to get what I want done. I'm sad to admit that I often break down and just use triggers attached to the object.
I don't get home until very late on Wednesday's, but I'll set an alarm to remind me to post how I handle this situation.
#6
My player class has the following code in it's onCollision callback:
02/23/2011 (7:14 pm)
I don't know if this will help you, but this is how I handle collisions:function ArcadeMinions::buildMinion( %this )
{
%minion = new t2dParticleEffect() {
class = ArcadeMinion;
scenegraph = ArcadeScene;
effectFile = "~/data/particles/minion.eff";
useEffectCollisions = "0";
effectMode = "INFINITE";
effectTime = "0";
canSaveDynamicFields = "1";
position = "0 0";
size = "15.000 15.000";
Layer = "18";
ForwardOnly = "1";
qUpdate = true;
};
%minionCollision = new t2dSceneObject() {
scenegraph = ArcadeScene;
class = ArcadeMinionCollision;
canSaveDynamicFields = "1";
Position = %start;
size = "15.000 15.000";
GraphGroup = "17";
CollisionActiveReceive = "1";
CollisionActiveSend = "1";
CollisionPhysicsSend = "0";
CollisionPhysicsReceive = "0";
CollisionDetectionMode = "CIRCLE";
CollisionCircleSuperscribed = "0";
};
%minion.moveEffectTo( 10, 2 );
%minionCollision.mount( %minion );
return %minion;
}My player class has the following code in it's onCollision callback:
if( %dstObject.class $= "ArcadeMinionCollision" )
{
ArcadeState.modifyPlayerHealth( -0.30 );
}
#7
Is there any way I can set its datablock?
I.E. is this valid?
02/25/2011 (7:14 am)
Ah, I see. So instead of cloning, you just create a new object?Is there any way I can set its datablock?
I.E. is this valid?
function Powerups::Spawn(%interval, %spawn)
{
%speed = new t2dSceneObject() {
datablock = "Powerup_Speed";
}
%speed.setPositionX(getRandom(-43.0, 43.0));
%speed.setPositionY(getRandom(-30.0, 30.0));
if (%spawn)
{
schedule(%interval, "PowerupsRandomSpawn", %interval, %spawn);
}
}
#8
02/25/2011 (10:49 am)
I don't have the source code in front of me right now, but I can't see why that wouldn't work!
#9
02/25/2011 (11:14 am)
Thanks ^_^
#10
And the object gets created (I echo %speed), but it's nowhere to be seen on the screen. I think that it has no image map, but I can't figure out how to set its image map. Do I have to make it a particle and mount it to an object like you do? If so, how do I do that? The file isn't a .eff. It's the plasma ball in the starterArt.
02/26/2011 (1:14 pm)
Hmm. I've tried this:function speed::Spawn(%this, %interval, %spawn)
{
%speed = new t2dSceneObject()
{
datablock = "Powerup_Speed";
};
%speed.setPositionX(getRandom(-43, 43));
%speed.setPositionY(getRandom(-30, 30));
if (%spawn)
{
%this.schedule(%interval, "Spawn", %interval, %spawn);
}
}And the object gets created (I echo %speed), but it's nowhere to be seen on the screen. I think that it has no image map, but I can't figure out how to set its image map. Do I have to make it a particle and mount it to an object like you do? If so, how do I do that? The file isn't a .eff. It's the plasma ball in the starterArt.
#11
03/01/2011 (11:04 am)
Okay, I am able to make the new object now. However, I have a problem. The collision is not working. My ship collides with it, and gets Clamped, but the onCollision function is not being called on collision. Here is my script:function speed::onCollision(%srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts)
{
echo("Test");
if (%dstObj.class $= "playerShip")
{
%dstObj.Speed *= %srcObj.factor;
speedTxtGUI.text = "Speed: " SPC %dstObj.Speed;
%dstObj.schedule(%srcObj.time, "speedExpire", %srcObj.factor);
%srcObj.safeDelete();
}
}
function playerShip::speedExpire(%this, %factor)
{
%this.Speed /= %factor;
speedTxtGUI.text = "Speed: " SPC %this.Speed;
}
function speed::Spawn(%this, %interval, %spawn)
{
%speed = new t2dSceneObject()
{
scenegraph = %this.scenegraph;
Layer = 8;
Size = "4.000 4.000";
class = "speed";
CollisionCallback = true;
CollisionActiveReceive = true;
CollisionActiveSend = false;
CollisionDetectionMode = "CIRCLE";
CollisionPhysicsReceive = false;
CollisionPhysicsSend = false;
factor = 2;
time = 15000;
};
%speedSprite = new t2dStaticSprite()
{
scenegraph = %this.scenegraph;
imageMap = particle_plasmaImageMap;
Layer = 8;
Size = "4.000 4.000";
};
%speedSprite.mount(%speed);
%speed.setPositionX(getRandom(-43.0, 43.0));
%speed.setPositionY(getRandom(-30.0, 30.0));
if (%spawn)
{
%this.schedule(%interval, "Spawn", %interval, %spawn);
}
}
function speed::onLevelLoaded(%this, %scenegraph)
{
%this.scenegraph = %scenegraph;
%this.Spawn(100, true);
}
#12
03/01/2011 (12:47 pm)
In my example, I had the CollisionActiveSend and Receive to true. I don't know if this should matter, but it's something to try.
#13
Correct me if I'm wrong on this one, but I believe a datablock should be set using the name "config" when you are creating objects. Like:
At least, this is the name that is listed in the docs (and your scene file if you care to examine it).
03/30/2011 (6:06 am)
James,Correct me if I'm wrong on this one, but I believe a datablock should be set using the name "config" when you are creating objects. Like:
%newObject = new t2dStaticSprite()
{
sceneGraph = %this.owner.getSceneGraph();
canSaveDynamicFields = "1";
config = "playerBullet" @ %color @ %type @ "Datablock";
};At least, this is the name that is listed in the docs (and your scene file if you care to examine it).
#14
I was able to do what I wanted without datablocks.
03/30/2011 (1:06 pm)
Ah, I actually forgot about this thread :PI was able to do what I wanted without datablocks.
Torque Owner Chris Labombard
Premium Preferred
Assuming you just want a script object and you don't actually need a datablock, try something like this:
function SpeedCreate(%speed) { %obj = new ScriptObject(Speed) { actualSpeed = %speed; }; return %obj; } function Speed::getSpeed(%this) { return %this.actualSpeed; }