Rotating a rocket in 2D and moving into the direction it is facing

I essentially want to rotate my rocket both clockwise and anti clock wise and have its x and y adjusted in order to move in the direction its facing when the thrust button is pressed

I’ve tried numerous ways and am getting caught up in the equations and how to implement them, see my code below (feel free to laugh if its way off the mark)

[code] local rocket = display.newSprite( rocketsheet, rocketsequencedata)
physics.addBody(rocket, { bounce = 0.5} )
rocket.x = display.contentWidth/3
rocket.y = display.contentHeight/1.5
rocket.rotation = angle
rocket:setSequence(“idle”)
rocket:play()
local inverseRotation = rocket.rotation + math.pi
local speedX = 0.000
local speedY = 0.005

speedX = speedX * math.cos(inverseRotation) + speedY * math.sin(inverseRotation)
speedY = -speedX * math.sin(inverseRotation) + speedY * math.cos(inverseRotation)

function thrust(event)

rocket:applyLinearImpulse(speedX, speedY, rocket.x, rocket.y)
rocket:setSequence(“afterburn”)
rocket:play()

end

function rotateleft(event)

speedX = speedX - 0.0005

rocket.rotation = rocket.rotation - 2

end
function rotateright(event)

speedX = speedX + 0.0005
rocket.rotation = rocket.rotation + 2

end

controlthrust:addEventListener( “touch”, thrust)
controlleft:addEventListener( “touch”, rotateleft)
controlright:addEventListener( “touch”, rotateright) [/code]

Frustration isn’t even the word I’m feeling right now :stuck_out_tongue: [import]uid: 166613 topic_id: 33023 reply_id: 333023[/import]

If you are using physics (I see that you are) you should take a look at this post:

https://developer.coronalabs.com/forum/2012/11/14/fire-bullet-rotating-object

The latest entry has a working solution which illustrates what I think you’re trying to get, albeit in a single hit. You would simply want to apply linear force while repeatedly re-calculating the angle to apply it at.

If, however, you want a physics object to actually follow a path I suggest you use a touch joint and simply pretend that it’s following a user touch.

I’ve also placed a link to my mathlib library in the code of that post. [import]uid: 8271 topic_id: 33023 reply_id: 131073[/import]

Thank you very much!.
I’m going to have a crack at it now, Ill keep you updated. [import]uid: 166613 topic_id: 33023 reply_id: 131076[/import]

@liudom,
Nobody will laugh, 2D math is always (fun) tricky if you’re not in the habit of doing it. It is especially tricky if you are thinking in one coordinate system vs. another. i.e. Cartesian vs Screen.

Fortunately, there are a few math libraries you can use in the resources.

For your particular problem, you can convert an angle to a unit-vector (in screen space) and scale that by your ‘speed’ to achieve the results you want.

Angle 2 Vector
[lua]function angle2Vector( angle, tableRet )
local screenAngle = mRad(-(angle+90))
local x = mCos(screenAngle)
local y = mSin(screenAngle)

if(tableRet == true) then
return { x=-x, y=y }
else
return -x,y
end
end[/lua]

Vector Scale
[lua]function scale( … )
if( type(arg[1]) == “number” ) then
local x,y = arg[1] * arg[3], arg[2] * arg[3]

if(arg[4]) then
return { x=x, y=y }
else
return x,y
end
else
local x,y = arg[1].x * arg[2], arg[1].y * arg[2]

if(arg[3]) then
return x,y
else
return { x=x, y=y }
end
end
end[/lua]

Applied to your problem
[lua]local impulseVal = 10 – Adjust a needed

function thrust(event)
local angle = rocket.rotation

local newVec = angle2Vector( angle, true )

local scaledVec = scale( impulseVal , newVec )

rocket:applyLinearImpulse( scaledVec.x, scaledVec.y, rocket.x, rocket.y)
rocket:setSequence(“afterburn”)
rocket:play()
end[/lua]

Notes

  • The above code is from a free library and framework (SSKCorona) I have provided to the community and am still improving. The 2D Math code is found here.

  • You may not get the response you want from applyLinearImpulse(). I suggest experimenting with applyForce() or setLinearVelocity().

  • applyForce() must be reapplied every frame so that is also tricky.

  • SSKCorona has a Wiki and these two functions are documented there: ssk.math2d.angle2Vector and ssk.math2d.scale

Good luck on your game,
Ed [import]uid: 110228 topic_id: 33023 reply_id: 131071[/import]

If you are using physics (I see that you are) you should take a look at this post:

https://developer.coronalabs.com/forum/2012/11/14/fire-bullet-rotating-object

The latest entry has a working solution which illustrates what I think you’re trying to get, albeit in a single hit. You would simply want to apply linear force while repeatedly re-calculating the angle to apply it at.

If, however, you want a physics object to actually follow a path I suggest you use a touch joint and simply pretend that it’s following a user touch.

I’ve also placed a link to my mathlib library in the code of that post. [import]uid: 8271 topic_id: 33023 reply_id: 131073[/import]

Thank you very much!.
I’m going to have a crack at it now, Ill keep you updated. [import]uid: 166613 topic_id: 33023 reply_id: 131076[/import]

@liudom,
Nobody will laugh, 2D math is always (fun) tricky if you’re not in the habit of doing it. It is especially tricky if you are thinking in one coordinate system vs. another. i.e. Cartesian vs Screen.

Fortunately, there are a few math libraries you can use in the resources.

For your particular problem, you can convert an angle to a unit-vector (in screen space) and scale that by your ‘speed’ to achieve the results you want.

Angle 2 Vector
[lua]function angle2Vector( angle, tableRet )
local screenAngle = mRad(-(angle+90))
local x = mCos(screenAngle)
local y = mSin(screenAngle)

if(tableRet == true) then
return { x=-x, y=y }
else
return -x,y
end
end[/lua]

Vector Scale
[lua]function scale( … )
if( type(arg[1]) == “number” ) then
local x,y = arg[1] * arg[3], arg[2] * arg[3]

if(arg[4]) then
return { x=x, y=y }
else
return x,y
end
else
local x,y = arg[1].x * arg[2], arg[1].y * arg[2]

if(arg[3]) then
return x,y
else
return { x=x, y=y }
end
end
end[/lua]

Applied to your problem
[lua]local impulseVal = 10 – Adjust a needed

function thrust(event)
local angle = rocket.rotation

local newVec = angle2Vector( angle, true )

local scaledVec = scale( impulseVal , newVec )

rocket:applyLinearImpulse( scaledVec.x, scaledVec.y, rocket.x, rocket.y)
rocket:setSequence(“afterburn”)
rocket:play()
end[/lua]

Notes

  • The above code is from a free library and framework (SSKCorona) I have provided to the community and am still improving. The 2D Math code is found here.

  • You may not get the response you want from applyLinearImpulse(). I suggest experimenting with applyForce() or setLinearVelocity().

  • applyForce() must be reapplied every frame so that is also tricky.

  • SSKCorona has a Wiki and these two functions are documented there: ssk.math2d.angle2Vector and ssk.math2d.scale

Good luck on your game,
Ed [import]uid: 110228 topic_id: 33023 reply_id: 131071[/import]