Problems getting "Gravity type" of controls right

I’m trying to make a simple “gravity” kind of game where I control a small ship with two thrusters. Touching the screen on the left side firest more of the left one etc.

But unfortunately it doesn’t quite work the way I want… Obviously I’m not doing it right. I’m trying to apply a force on the ship in the direction in which it points and also apply a torque based in the "truster balance (-1 to 1).

I’m fairly sure that it is the ship.x / ship.y parameters in the applyForce line that is the source of my problems, but I’m not sure how to deal with it…

Here’s the code:

local physics = require("physics") physics.start() physics.setGravity(0,4); local thrustForce = 15 local w = display.contentWidth local h = display.contentHeight -- Ship local ship = display.newImage("red\_ship.png") ship.x = w/2     ship.y = h/2 ship.myName = "red\_ship" -- Ground local earth = display.newImage("earth.png") earth.anchorX = 0.5; earth.anchorY = 0.5; earth.x = w/2; earth.y = h - earth.height/2; earth.myName = "earth" physics.addBody(ship, "dynamic", { density=2.0, friction=0.3, bounce=0.5, radius=13}) physics.addBody(earth, "static", { density=5.0, friction=0.3, bounce=0.2}) -- Ship thrusters variables local thrustPlacement=0        -- (-1.0 = left, 1.0 = right) local thrustAmount=0             local frameRedrawListener = function(e)     -- Apply thrust (if any)     local angle = math.rad(ship.rotation+90)       local xComp = math.cos(angle)       local yComp = -math.sin(angle)          -- Apply force in the direction of the ship and rotate according to thrust balance     if (thrustAmount ~= 0) then         ship:applyForce( thrustForce\*xComp, thrustForce\*yComp, ship.x, ship.y)         ship:applyTorque( -thrustPlacement )     end end local backGroundTouch = function(e) if (e.phase == "began") then    thrustAmount = thrustForce     thrustPlacement = (e.x - w/2) / (w/2)   end   if (e.phase == "moved") then    thrustAmount = thrustForce     thrustPlacement = (e.x - w/2) / (w/2)   end   if (e.phase == "ended") then    thrustAmount = 0   end     end Runtime:addEventListener( "enterFrame", frameRedrawListener ) background:addEventListener( "touch", backGroundTouch )  

Hi @runew,

Have you considered applying the force to a non-center part of the ship, and also take into account the direction it’s facing?

Brent

Hi,

Yes, I tried that first (and failed). My plan A was to define a line between the two rocket exhausts and apply a force somewhere on this line according to the user input, but that didn’t work particularly well either.

I probably screwed up with the placement of this line…

Hi @runew,

If you want something like 2 thrusters being controlled independently, I think you’d need to do this:

  1. For simplicity, assume the ship is a 100x100 square, with it’s theoretical “front” facing up.

  2. Assume that if the ship’s center point is 0,0, then the left thruster is at around -40,50.

  3. Use object:localToContent() to get that point in screen coordinates. Why? Because this takes into account the rotation of the ship, which obviously will not always be facing straight up.

  4. Now, subtract the ship’s coordinates from those coordinates to get them back in the “scope” of the ship, not the content.

  5. Use those coordinates to apply a force at that point AND with the proper vector direction, based on the ship’s rotation (just use triangular math to get this).

  6. Do the same thing with the right thruster, but of course you’ll need two separate applications of force if they’re using both the left and right thrusters at the same time.

This concept would be easier to draw than to describe, but maybe that does a decent job. :slight_smile:

Brent

Thanks a lot!

I didn’t know about the localToContent() method!

:slight_smile:

Hi @runew,

Have you considered applying the force to a non-center part of the ship, and also take into account the direction it’s facing?

Brent

Hi,

Yes, I tried that first (and failed). My plan A was to define a line between the two rocket exhausts and apply a force somewhere on this line according to the user input, but that didn’t work particularly well either.

I probably screwed up with the placement of this line…

Hi @runew,

If you want something like 2 thrusters being controlled independently, I think you’d need to do this:

  1. For simplicity, assume the ship is a 100x100 square, with it’s theoretical “front” facing up.

  2. Assume that if the ship’s center point is 0,0, then the left thruster is at around -40,50.

  3. Use object:localToContent() to get that point in screen coordinates. Why? Because this takes into account the rotation of the ship, which obviously will not always be facing straight up.

  4. Now, subtract the ship’s coordinates from those coordinates to get them back in the “scope” of the ship, not the content.

  5. Use those coordinates to apply a force at that point AND with the proper vector direction, based on the ship’s rotation (just use triangular math to get this).

  6. Do the same thing with the right thruster, but of course you’ll need two separate applications of force if they’re using both the left and right thrusters at the same time.

This concept would be easier to draw than to describe, but maybe that does a decent job. :slight_smile:

Brent

Thanks a lot!

I didn’t know about the localToContent() method!

:slight_smile: