Game Development Community

How to drag a sprite in a straight line?

by Matt Grosse · in Torque Game Builder · 05/19/2007 (10:35 pm) · 4 replies

In the game i'm working on i need to restrict movement to straight lines. like when its time to move, i'd like the user to be able to click on their unit and drag it within the movement range of the unit - but only straight ahead (in the direction that its facing). i think i have a way to do it that works with straight up and down or left and right movement, but it won't work when the unit is facing any angle.

i was thinking of placing a thin sprite line along the path of movement, and trying to use that to keep the sprite "snapped" to the movement line. but i'm not sure how to implement it. any ideas would be much appreciated.

#1
05/20/2007 (4:54 am)
If the unit is facing somewhere, the object has an angle. Assuming that's the angle you want to use, try this:


function Unit::move ( %this, %velocity )
{
%this.setLinearVelocityPolar ( %this.getRotation, %velocity );
}


I'm not sure I understood what you want to do... but if I did, that's the way to go.
#2
05/20/2007 (8:02 am)
Thanks, after my first post i thought of using velocity to move it (instead of trying to set position) and came across that function you mentioned in the reference. and it definitely works for moving, but getting it to coincide with the mouse is the hard part i guess. like i want to simulate click and drag movement with the sprite, but limit the movement to a straight line. so i was trying to put in some checks so that once the sprite reached a point that was the same as the mouse position, it would stop - but that wasn't working for some reason.
#3
05/20/2007 (1:45 pm)
Use simple math for this job :-)

What you need to do is to project the vector dir = object -> mousepointer onto the movement line and map the mouse there actually.

Doing so isn't hard at all, what you need is a unity vector in the direction your object is looking ( this 2D vector would be cos(angle) , sin(angle) ) and calculate the scalar product of this and above mentioned dir vector and multiply that scalar by the unity vector afterwards.

That vector now just has to be added to the object position and tada you have the projected mouse position on the movement line :)

Or in simple math (pseudo code)

dir = mousePos - objPos;
unityVec = vector2d( cos(angle), sin(angle) );
newMousePos = objPos + scalar( unityVec, dir) * unityVec;
#4
05/20/2007 (7:57 pm)
Thanks for the tips, they're much appreciated.

i got the movement part down. what i did was placed a guide sprite (like a ruler) projected from the origin on the unit sprite, pointing straight ahead. i then trapped mouse clicks, and if they were on the ruler i considered it a valid move and setPositionTarget. then used LinearVelocityPolar() to move the sprite along the proper angle.

i'm in need of some more math help though. i would like to label the ruler in 5 unit increments. so starting at the beginning of the ruler (which is placed at the center of the unit) i use a for loop to create t2dTextObjects and increment by 5, over the whole length of the ruler. i'm having trouble getting the correct (X, Y) coords to place the text objects though. for the trivial cases (0, 90, 180, 270 degrees) i have it working, but for all other angles its not.

i thought it would just be something like:

loop {
x = distanceFromStart * cos(angle)
y = distanceFromStart * sin(angle)
distanceFromStart += 5
}

but thats yielding strange results. i'm guessing the coordinate system is different than normal?