Game Development Community

Stop sprite after destination reached

by Jean-Fran · in Torque Game Builder · 07/24/2005 (2:14 pm) · 6 replies

Good day,

I'm a new T2D user, and I'm very impressed by it so far!

I'm wondering if there's any easy way to tell a sprite to stop it's movement (velocity) after it has reached a given point. The only way I can see right now is to use setWorldLimits. Is there a better way?

In a related question, if I have to use setWorldLimit, is there a convenient way to 'grow' rectangles, so that the world limits encompasses the start position+sprite size to the end position+sprite size?

Thanks in advance!

J-F

#1
07/24/2005 (2:18 pm)
You could set a variable such as sprite.atdest and set it to true when it gets to where it's going. Just run a schedule to check the sprites position at regular intervals.

Checkout King Tuts Move To tutorials as it covers exactly this.
#2
07/24/2005 (5:17 pm)
I had a similiar problem. I had to start it in motion, and stop it when it reached it's destination - with the knowledge of how long it would take (linear path, no interruption). I just scheduled an "endmove" call after the time had elapsed.

I initially tried something similiar/based off of the King Tuts tutorial, but if you set the speed to high, it wobbles back and forth for a while before settling. Not quite the behavior desired in my case. It's a great method if your velocities are reasonable.

On a side note, this is probably an important enough feature that it is either being worked on, planned to be worked on, or should be worked on as embedded support in the FxSceneObject support as a callback. Or...

Now... An off the top of my head possible solution that should have some more accuracy than either of these methods:
Try putting a special invisible "Collision" object in your game area. Then, when the poly of your sprite hits it, you get a nice callback. I haven't actually played around much with the physics engine, so this comes with no promises :) But I would think that the physics engine would give far better accuracy than scheduled calls so that you would get fewer caveats.

I would be very interested to hear if this works.
#3
07/24/2005 (7:24 pm)
Good day,

Thanks for the suggestions. King Tut's tutorial helped me pick a couple of new tricks, but nothing that I found satisfactory. I've used the setWorldLimit, and that works really well for me. If that can be useful for anyone else, here's a snippet of the code that I'm using to set the destination of a sprite, and have that sprite stop at the given destination:

// Test mouse motion.
function fxSceneWindow2D::onMouseDown(%this, %modifiers, %worldPosition, %mouseClicks)
{
    setDest($mySprite, %worldPosition);
}

function fxSceneWindow2D::onMouseUp(%this, %modifiers, %worldPosition, %mouseClicks)
{
    setDest($mySprite, $mySprite.getPosition());
}

function fxSceneWindow2D::onMouseDragged(%this, %modifiers, %worldPosition, %mouseClicks)
{
    setDest($mySprite, %worldPosition);
}

// Set sprite destination.
function setDest(%sprite, %destination)
{
    // Move prou towards the destination.
    %vector = vectorSub2D(%destination, %sprite.getPosition());
    %vector = vectorNormalise2D(%vector);
    %vector = vectorScale(%vector, 30);
    
    %sprite.setLinearVelocity(%vector);
    
    %rect = %sprite.getPosition() SPC %destination;
    
    // Note: $spriteSize should be retrieved from %sprite.getSize()
    %rect = cgGrowRect(%rect, $spriteSize);
    
    // DEBUG:
    //echo(%rect);
    
    %sprite.setWorldLimit(CLAMP, %rect);
}

function cgGrowRect(%rect, %amount)
{
    %x1 = getWord(%rect, 0); 
    %y1 = getWord(%rect, 1); 
    %x2 = getWord(%rect, 2); 
    %y2 = getWord(%rect, 3);
    
    if(%x1 > %x2)
    {
        %tmp = %x1;
        %x1 = %x2;
        %x2 = %tmp;        
    }
    
    if(%y1 > %y2)
    {
        %tmp = %y1;
        %y1 = %y2;
        %y2 = %tmp;        
    }
    
    %x1 -= %amount;
    %y1 -= %amount;
   
    %x2 += %amount;
    %y2 += %amount;
    
    return %x1 SPC %y1 SPC %x2 SPC %y2;
}

Suggestions are welcomed. Hope this can help others!

J-F
#4
07/25/2005 (9:57 am)
If you don't mind the stop/start motion of mounted objects, you can just mount an object to an "anchor" and then move the anchor to the desired position. The mounted object will follow and settle at that position. You have no control over speed this way, though. :(
#5
07/25/2005 (10:13 am)
Your right, my solution does produce a wobble at high velocities, depending on what margin of error you allow and what time you put on the schedule for onDest. You could lower the time on the schedule to help this, though might hit some performance problems with a lot of objects.

There are two ways to better garantee accuracy. One would be to do the checks in onUpdateScene() attched to the scenegraph. That way the check would happen every update... this could hit some performance problems as well with a lot of objects.

The best and most efficient solution would be to throw it on the C++ side in integrate object, much like my C++ tutorial shows you how to make an object follow the mouse.
#6
07/25/2005 (12:24 pm)
Thanks Matthew for your suggestions. I hope you don't think I blasted your tutorial, because it was actually quite useful for me.

I'm glad to learn about the onUpdateScene, but like you said, for a lot of sprites, this could get very expensive. As for the C++ solution, I'm going to wait until the T2D are stabilized before I start making changes to the code (thought I really appreciate GG giving the code with their product!)

In the mean time, please keep up the great work!

J-F