ApplylinearImpulse stuck mid air

I am applying linearimpulse to my player while jumping from static platforms. But I am facing a problem that the player gets stuck midair after the impulse, it seems the gravity is not getting applied to it somehow.

My player setup look like this:
physics.start()
physics.setGravity(0, 15)

    hero = display.newImageRect( heroGroup, "crate.png", 90, 90)
    hero.x = 60
    hero.y = 100
    physics.addBody( hero, "dynamic", {bounce=0.0, density=0.008})
    hero.gravityScale = .8

And on touch of screen, i am applying the impulse

local function touch( event )
    if event.phase == "began" then
		hero:setLinearVelocity( 0, 0 )
		hero:applyLinearImpulse(0, -0.65, hero.x, hero.y )
	end
end

Attached is how the player looks like after I touch the screen

Any ideas what am I missing in my setup.

If the box deaccelerates it means that the gravity is working fine.
Try this line of code after the physics.start() -> physics.setDrawMode("hybrid")

I think the body representing the ground is higher than it should, so the box is not resting on the ground, instead it is inside of it.

Tried following your suggestion. This is how it looks. Not sure what is missing

When the box becomes blue, it meas it is “idle” and the physics engine stop making calculations on this.

This makes sense form the point that an object will never move or apply forces by itself without any external stimulation.

I am not used to use the Solar2D physics, so I do not know what is the best way to do what you are doing. But you have to apply a force to your box instead of your environment.

I think that moving your group to the left on each enterFrame and counteracting that by applying an horizontal force to your box to keep it moving would work.

This would be the code

local prevTime
local speed = -0.1
function scene:enterFrame(e)
  local timeElapsed = system.getTimer() - prevTime
  prevTime = prevTime + timeElapsed
  
  self.view.x =  self.view.x + speed*timeElapsed

  local vx, vy = box:getLinearVelocity()
  if vx < .1 then
    box:setLinearVelocity( .1, vy )
  end
end
1 Like

Yes !!!
Thank you this works.
And thank you for the tips, I had no idea on how to debug such kind of issues.

1 Like

Cool! :slight_smile:
And yes, visual debugging tools are a bless!

Tip: regardless of what you end up doing, you’re not using applyImpulse() in the best way.

You should always do this:

hero:applyLinearImpulse( 0 * hero.mass, -0.65 * hero.mass, hero.x, hero.y )

If you don’t take the mass into account, and later decide to make the ‘hero’ bigger or smaller, your impulse response will suddenly stop behaving the way it used to which can be a real pain.

2 Likes

thank you !

You have a lazy sleepy physics body - Box2D puts bodies to sleep to save memory when they have been idle with no physics contacts for a while.

Use isSleepingAllowed to keep it awake

3 Likes