Game Development Community

New with TorqueScript, game loop/memory management question

by Joe Bourrie · in Torque Game Builder · 10/04/2005 (8:10 pm) · 5 replies

I'm a C++/Python programmer who is brand new to TorqueScript, and I get the feeling that there is something I am missing...

What I am trying to do is draw a line between two moving objects in my scene.

I found a piece of script that draws a stretched sprite as a line:


function DrawLine(%where, %x1, %y1, %x2, %y2, %r, %g, %b, %a)
{
$line[$line_number] = new fxStaticSprite2D() {scenegraph = %where;};
$line[$line_number].setBlendColour(%r SPC %g SPC %b SPC %a);
$line[$line_number].setImageMap(PixelImageMap);
%difference = vectorSub2D(%x2 SPC %y2, %x1 SPC y1);
%sum = vectorAdd2D(%x2 SPC %y2, %x1 SPC %y1);
%midpoint = vectorScale2D(%sum, 0.5);
%angle = mRadToDeg(mAtan(getWord(%difference, 0), getWord(%difference, 1)));
$line[$line_number].setPosition(%midpoint);
$line[$line_number].setSize("0.5" SPC vectorLength2D(%difference));
$line[$line_number].setRotation(-%angle);
$line_number++;
}


which is good enough for now. In onUpdateScene(), I call this function to draw the line. The problem is that the lines never are deleted, so they just pile up on the screen.

So, in usual C++ fashion, I created another function that gets called onUpdateScene() before the lines are drawn:

function ClearLines()
{
for(%i = 0; %i < $line_number; %i++)
{
$line[%i].safeDelete();
}
$line_number = 0;
}

And now the lines don't show up at all. Is there something I am missing about safeDelete(), arrays, or something else? Or is my logic just faulty somewhere that I'm not seeing?


Thanks for any help you can give

Joe

#1
10/05/2005 (12:16 am)
This is a hard one!

My guess (and it's only a guess) is that your onUpdateScene() gets called so often (for every object possibly? per tick) that in the very next tick you are always deleting the lines that were just drawn. Since tick rate is extremely fast in human terms, the lines are getting drawn, then deleted before you can even register they exist.

My suggestion would be to move that code out of onUpdateScene, and find a more appropriate place to put it. A couple of options:

1) Make it a gui overlay
2) Do it in c++ (in an appropriate OnRender for the object itself). You could alternatively keep it in script, but make the entire line itself an object (I'd have to look a lot deeper into this myself, not sure the best strategy for doing that).
3) Search on the forums...I'm pretty sure this question has been asked/answered in the last couple of months.

From the theory perspective, your main issue is that in Torque development we don't normally do renders, we create objects that render themselves. If you look at it from the angle of "ok, I want a line to be on the screen, so I need to create an object that renders as a line", instead of "ok, I want a line to be on the screen, so I need to draw it on the screen"...the first will be persistent until you tell it to go away (because the object renders itself every frame), while the second will render for a single frame, but the next frame will go away.
#2
10/05/2005 (9:09 am)
I guess this explains why primitives aren't yet a part of the T2D API... what good is a static line?

This was just supposed to be quick hack code to prototype my game idea... I'm new at Torque and don't want to have to learn how to delve into T2D's source just to connect two points with a line.

Since it's just temporary code, I may be able to iterate over the list and update the endpoints of the lines instead of deleting them. Once I get into production on this game, I will go back and add primitives to the engine (or maybe, if I'm lucky, GG will have added it by then)

Thanks
#3
10/05/2005 (9:19 am)
What you should do is just use a single sprite then adjust it's rotation and scale based on the location of the two objects you want to link. I did it myself for a quick test of a laser beam several months ago.

function updateBeam()
{
	%difference = vectorSub2D($target.getPosition(), $player.getPosition());
	%sum = vectorAdd2D($target.getPosition(), $player.getPosition());
	%midpoint = vectorScale2D(%sum, 0.5);
	%angle = mRadToDeg(mAtan(getWord(%difference, 0), getWord(%difference, 1)));
   
	$beam.setPosition(%midpoint);
	$beam.setSize("0.75" SPC vectorLength2d(%difference));
	$beam.setRotation(-%angle);
	
	schedule(20, 0, "updateBeam");
}

It's the quick hack of a function I used for that test, you should be able to use something similar for what you are planning on doing.
#4
10/05/2005 (9:59 am)
Thanks, that should do what I need it to do. I think your post about the laser is the one that I got the DrawLine() function from originally :)
#5
10/05/2005 (10:04 am)
Hehe, your welcome. I'm not a great coder, but it's nice to be able to help every now and then.