Help with applyForce

Hello guys, I am starting a new game, a work in progress. I am trying to make a player that always moves. It starts moving right continuously and if you press the left button it switches to going to the left continuously. And then you can press the right key to make it go to the right continuously.

However if you press either arrow key multiple times it “boosts” the player, making it go extra fast. Then when you press the other arrow you don’t move the other way, instead you just stop moving or in more drastic cases, continue to move in the SAME direction.

Here is my code.

player = display.newCircle(550,600,50) player:setFillColor(10,90,230) physics.addBody( player, { density = 1.0, friction = 0, bounce = 0, radius = 50 } ) local function goLeft (event) player:applyForce( -500, 0, player.x, player.y ) end local function goRight(event) player:applyForce( 500, 0, player.x, player.y ) end left:addEventListener("touch",goLeft) right:addEventListener("touch",goRight) goRight()

All help is appreciated.

Regards Summit Tech

Hi there,

What exactly is the problem you’re seeing?  I haven’t tried running your code, but on quick glance it looks fine to me for accomplishing what you described you wanted to do.

  • Andrew

If you double tap the same arrow key then the player boosts forward, going very quickly. Then after I pressed the same arrow key multiple time In order for me to go the other way you have to press the other arrow key multiple times.

Yup, that’s what I thought you were trying to do.  And that’s happening because you’re applying the same magnitude force (500) on each tap.  What do you want to happen instead?

  • Andrew
  1. The force required to move an object varies proportionally to the object w * h * density.  

  2. You should probably only use the “began”, or “ended” phase of the touches.

  3.  Better yet, try this:

    player = display.newCircle(550,600,50) player:setFillColor(10,90,230) physics.addBody( player, { density = 1.0, friction = 0, bounce = 0, radius = 50 } ) player.inputX = 0 player.thrustForce = 10 – Try adjusting till you like the result player.enterFrame = function( self, event )    local x = self.inputX * self.thrustForce    local y = 0    self:applyForce( x, y, self.x, self.y) end local function goLeft (event)    if(event.phase == “began”) then       player.inputX = player.inputX - 1    elseif(event.phase == “ended”) then       player.inputX = player.inputX + 1    end    return true end local function goRight(event)    if(event.phase == “began”) then       player.inputX = player.inputX + 1    elseif(event.phase == “ended”) then       player.inputX = player.inputX - 1    end    return true end Runtime:addEventListener( “enterFrame”, player ) left:addEventListener(“touch”,goLeft) right:addEventListener(“touch”,goRight) 

I think what you are looking for is setLinearVelocity(), no matter how many times you hit the right or left arrow it won’t boost, it will stay at the same velocity unless you tell it otherwise.

Hi there,

What exactly is the problem you’re seeing?  I haven’t tried running your code, but on quick glance it looks fine to me for accomplishing what you described you wanted to do.

  • Andrew

If you double tap the same arrow key then the player boosts forward, going very quickly. Then after I pressed the same arrow key multiple time In order for me to go the other way you have to press the other arrow key multiple times.

Yup, that’s what I thought you were trying to do.  And that’s happening because you’re applying the same magnitude force (500) on each tap.  What do you want to happen instead?

  • Andrew
  1. The force required to move an object varies proportionally to the object w * h * density.  

  2. You should probably only use the “began”, or “ended” phase of the touches.

  3.  Better yet, try this:

    player = display.newCircle(550,600,50) player:setFillColor(10,90,230) physics.addBody( player, { density = 1.0, friction = 0, bounce = 0, radius = 50 } ) player.inputX = 0 player.thrustForce = 10 – Try adjusting till you like the result player.enterFrame = function( self, event )    local x = self.inputX * self.thrustForce    local y = 0    self:applyForce( x, y, self.x, self.y) end local function goLeft (event)    if(event.phase == “began”) then       player.inputX = player.inputX - 1    elseif(event.phase == “ended”) then       player.inputX = player.inputX + 1    end    return true end local function goRight(event)    if(event.phase == “began”) then       player.inputX = player.inputX + 1    elseif(event.phase == “ended”) then       player.inputX = player.inputX - 1    end    return true end Runtime:addEventListener( “enterFrame”, player ) left:addEventListener(“touch”,goLeft) right:addEventListener(“touch”,goRight) 

I think what you are looking for is setLinearVelocity(), no matter how many times you hit the right or left arrow it won’t boost, it will stay at the same velocity unless you tell it otherwise.