ApplyLinearImpulse for Specific Direction? [Solved!]
by Chase Webb · in Torque 2D Beginner · 06/29/2013 (2:35 am) · 3 replies
I think I need some math help at the moment. Here's what I understand about ApplyLinearImpulse:
At the moment I have managed to get this to move:
Basically, this only makes my object move up. However, I've got the object rotating towards where I click my mouse. What I'd like is for the object to always rotate to my mouse, but the impulse to always be applied from the center towards a fixed point behind the object. Basically, think like a bottle rocket - the jet shoots out the back no matter what direction the object is facing. Also, it can't be based on the same world point my mouse is using to rotate the object, as the object doesn't rotate instantly (purposely).
Any thoughts?
ConsoleMethod(SceneObject, applyLinearImpulse, void, 4, 6, "(worldImpulse X/Y, [worldPoint X/Y]) - Applies an impulse at a world point.n"
"This immediately modifies the linear velocity. It also modifies the angular velocity if the point of application is not the center of mass.n"
"@param worldImpulse/Y - The world impulse vector in Newtons (N-seconds) or Kg-m/s."
"@param worldPointX/Y - The world point where the force is applied. If world point is not specified, the center of mass is used."
"@return No return Value.")At the moment I have managed to get this to move:
MyModule.ThePlayerObject.applyLinearImpulse(0 SPC 500, 0 SPC 1)
Basically, this only makes my object move up. However, I've got the object rotating towards where I click my mouse. What I'd like is for the object to always rotate to my mouse, but the impulse to always be applied from the center towards a fixed point behind the object. Basically, think like a bottle rocket - the jet shoots out the back no matter what direction the object is facing. Also, it can't be based on the same world point my mouse is using to rotate the object, as the object doesn't rotate instantly (purposely).
Any thoughts?
#2
Here's what I'm looking at right now:
I cleaned it up a little bit so it wouldn't have all the irrelevent commented out stuff in this post.
06/29/2013 (6:20 pm)
I think I'm making progress, but for some reason I JUST can't get it to work right. The object only ever moves in one direction (to the right at the moment) I made a little vector shape object and attached it to the bottom of my object so I would have something to reference so that I could get the angle (it's named .nodeEngine), but I'm still not having much luck. Also, assuming x1 and x2 are supposed to be the x coordinates of the two objects, but when I tried to pull the getLocalCenter().X for the two objects it just game me an error about an incorrect number of variables. Here's what I'm looking at right now:
// Calculate the angle to the mouse.
%origin = GameCore.ThePlayerObject.getPosition();
%angle = -mRadToDeg( mAtan( %worldPosition.x-%origin.x, %worldPosition.y-%origin.y ) );
//Rotate to the touched angle.
GameCore.ThePlayerObject.RotateTo( %angle, 100 );
// Move the sight to the touched position.
//GameCore.ThePlayerObject.MoveTo( %worldPosition, 50, false, false);
//GameCore.ThePlayerObject.applyLinearImpulse(0 SPC 500, "0 0");
%vectorangle = Vector2AngleBetween( GameCore.ThePlayerObject.getLocalCenter(), GameCore.ThePlayerObject.nodeEngine.getLocalCenter() );
//This gives me the error.
//%vectorangle = Vector2AngleBetween(GameCore.ThePlayerObject.getLocalCenter().X SPC GameCore.ThePlayerObject.nodeEngine.getLocalCenter().X, GameCore.ThePlayerObject.getLocalCenter().Y SPC GameCore.ThePlayerObject.nodeEngine.getLocalCenter().Y );
%vector = Vector2Direction(%vectorangle,500);
GameCore.ThePlayerObject.applyLinearImpulse(%vector, "0 0");I cleaned it up a little bit so it wouldn't have all the irrelevent commented out stuff in this post.
#3
As you can see, I can hold down the mouse and it will continue to move in pretty little arcs to point towards the place I click or drag on. I need to polish it up a bit, as turning when you run into something is a dead end right now, but I'll figure it out.
06/30/2013 (12:36 am)
Figured it out! It turns out I didn't want Vector2AngleBetween, I wanted Vector2AngleToPoint. Here is my script for movement below. My "nodeEngine" is an invisible vector object attached to the back of the player object via a weld joint:function GameCore::MoveThePlayerCreature(%this, %touchID, %worldPosition)
{
if($MouseIsHeldDown){
// Calculate the angle to the mouse.
%origin = GameCore.ThePlayerObject.getPosition();
%angle = -mRadToDeg( mAtan( %worldPosition.x-%origin.x, %worldPosition.y-%origin.y ) );
//Rotate to the touched angle.
if(GameCore.ThePlayerObject.Class $= "TriangleJObject"){
GameCore.ThePlayerObject.RotateTo( (%angle +30), 100 , true, false);
}
if(GameCore.ThePlayerObject.Class $= "SquareJObject"){
GameCore.ThePlayerObject.RotateTo( %angle, 200 , true, false );
}
%vectorangle = Vector2AngleToPoint( GameCore.ThePlayerObject.nodeEngine.getWorldCenter(), GameCore.ThePlayerObject.getWorldCenter());
GameCore.ThePlayerObject.setLinearVelocityPolar(%vectorangle, 50);
schedule(128, 0, "GameCore::MoveThePlayerCreature", %this, %touchID, $currentWorldPosition);
}
}
function InputManager::onTouchDown(%this, %touchID, %worldPosition)
{
$MouseIsHeldDown = true;
GameCore::MoveThePlayerCreature(%this, %touchID, %worldPosition);
}
function InputManager::onTouchUp()
{
$MouseIsHeldDown = false;
}
function InputManager::onTouchDragged(%this, %touchId, %worldposition)
{
$currentWorldPosition = %worldPosition;
}As you can see, I can hold down the mouse and it will continue to move in pretty little arcs to point towards the place I click or drag on. I need to polish it up a bit, as turning when you run into something is a dead end right now, but I'll figure it out.
Associate Simon Love
First, note that the second parameter to ApplyImpulse should be "0 0" for it to coincide to the center of the object. Alternatively, you can use SceneObject.getLocalCenter(); to obtain the true center of mass.
To get the angle betwen two points, you can use Vector2AngleBetween("x1 x2", "y1 y2");
You can then calculate a valid direction with the function %vector = Vector2Direction(angle, magnitude); where magnitude is basically the force of the impulse in world units.
You may then do one of two things
1 - %object.ApplyLinearImpulse(%vector);
2 - %object.setLinearVelocityPolar(angle, speed);
Be sure to check out Vector2_Scriptbinding.h for more Vector helper functions.