Physics, applyImpulse, dt and other things

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
counterfactual_jones
Prole
Posts: 24
Joined: Mon Feb 09, 2009 10:14 am

Re: Physics, applyImpulse, dt and other things

Post by counterfactual_jones »

Jumping off the direction of the surface sounds like a very interesting mechanic. Makes me think of N.

As for a top speed, I believe body:setDamping(n) and body:setAngularDamping(n) are what you're looking for. I haven't played with them yet, but it's on my list.
Broncheabones
Prole
Posts: 15
Joined: Wed Feb 04, 2009 5:25 am

Re: Physics, applyImpulse, dt and other things

Post by Broncheabones »

Hey, I noticed you are still trying to adapt it to K and that is my fault. I took a suggestion to change it to the delta time function so this is what my code looks like now:

EDIT: I've edited the code and now I'm faced with a new problem. Now I check if there is no (minimal actually) vertical force, then it can jump. The problem is, at the peak of it's jump it can jump again due to the lack of vertical force. What should I do now to make it jump only once?

Code: Select all

function update(dt)

x, y = body:getVelocity()

if love.keyboard.isDown(love.key_d) then
      body:applyImpulse(400000*dt, 0)
   elseif love.keyboard.isDown(love.key_a) then
	  body:applyImpulse(-400000*dt, 0)
   end 
   
   if love.keyboard.isDown(love.key_w) and y > -1 and y < 1 then
   		body:applyImpulse(0, -800000)
   end

   world:update(dt)
end
User avatar
counterfactual_jones
Prole
Posts: 24
Joined: Mon Feb 09, 2009 10:14 am

Re: Physics, applyImpulse, dt and other things

Post by counterfactual_jones »

Set a flag when you collide and unset it when the velocity changes. All this can be done inside update(dt) and collision handling.

Code: Select all

function update(dt)
    for i,v in pairs(objects) do
        if v.velocity.y < 0 then
            v.isFalling = true
        end
    end
end

function handleCollision(a, b, contact)
    local cx, cy = contact:getPosition()
    local a = objects[a:getData()] -- store the object list key in each shape
    local b = objects[b:getData()]
    if a.object.isFalling == true and a.y < cy then
        a.object.isFalling = false
    end
    if b.object.isFalling == true and b.y < cy then
        b.object.isFalling = false
    end
end
Broncheabones
Prole
Posts: 15
Joined: Wed Feb 04, 2009 5:25 am

Re: Physics, applyImpulse, dt and other things

Post by Broncheabones »

Hmm, what are these 'pairs'? when I put in the code it spits this back out at me:

ERROR!
Stack traceback:
[C]: in function 'pairs'
main.lua.48: in function <main.lua:47>
Here's what my code became after you posted that piece and I put it in mine, just in case I did anything wrong.

Code: Select all

function update(dt)
 for i,v in pairs(objects) do
        if v.velocity.y < 0 then
            v.isFalling = true
        end
	end

x, y = body:getVelocity()

if love.keyboard.isDown(love.key_d) then
      body:applyImpulse(400000*dt, 0)
   elseif love.keyboard.isDown(love.key_a) then
	  body:applyImpulse(-400000*dt, 0)
   end 
   
   if love.keyboard.isDown(love.key_w) and y > -1 and y < 1 then
   		body:applyImpulse(0, -800000)
   end

   world:update(dt)
end
User avatar
counterfactual_jones
Prole
Posts: 24
Joined: Mon Feb 09, 2009 10:14 am

Re: Physics, applyImpulse, dt and other things

Post by counterfactual_jones »

Broncheabones wrote:Hmm, what are these 'pairs'?
Sorry I assumed you'd alter it for your stuff. I keep lots of stuff in tables, pairs(table) used in that for loop allows you to iterate over every object in the table.

Here's the code I ended up writing, it's not so clean, but I was in a hurry :)

Code: Select all

function load()
   local width = love.graphics.getWidth()
   local height = love.graphics.getHeight()

   world = love.physics.newWorld(width, height)
   world:setGravity(0, 20)
   body = love.physics.newBody(world, 50, 250)

   world:setCallback(handle_collision)

   shape = love.physics.newCircleShape(body, 30)
   shape:setData("player")
   body:setMassFromShapes()

   terrain = love.physics.newBody(world, 0, 0)

   terrain_shapes = {
--      love.physics.newCircleShape(terrain, 120, 120, 50),
      love.physics.newRectangleShape(terrain, 200, 120, 50, 40),
      love.physics.newRectangleShape(terrain, width / 2, height - 20, width, 40)
   }

   terrain:setMass(0, 0, 0, 0)

   isFalling = true -- We start in the air
end

function update(dt)
   local x, y = body:getVelocity()


   if love.keyboard.isDown(love.key_d) then
      body:applyImpulse(100000*dt, 0)
   elseif love.keyboard.isDown(love.key_a) then
      body:applyImpulse(-100000*dt, 0)
   end
   
   if love.keyboard.isDown(love.key_w) and isFalling == false then
      body:applyImpulse(0, -200000)
      isFalling = true -- ableToJump might a more accurate name
   end

   world:update(dt)
end

function draw()
   local x, y = body:getPosition()
   for i,v in pairs(terrain_shapes) do
      love.graphics.polygon(0, v:getPoints())
   end

   love.graphics.circle(0, x, y, 30)
end

function handle_collision(shapedata1, shapedata2, contact)
   local x, y = body:getPosition()
   local cx, cy = contact:getPosition()
   print(x.."x"..y.." cx: "..cx.." cy: "..cy)
   if shapedata1 == "player" and y < cy then
      isFalling = false
   end
   if shapedata2 == "player" and y < cy then
      isFalling = false
   end
end
Last edited by counterfactual_jones on Tue Feb 10, 2009 6:39 am, edited 1 time in total.
Broncheabones
Prole
Posts: 15
Joined: Wed Feb 04, 2009 5:25 am

Re: Physics, applyImpulse, dt and other things

Post by Broncheabones »

counterfactual_jones wrote:
Broncheabones wrote:Hmm, what are these 'pairs'?
Sorry I assumed you'd alter it for your stuff. I keep lots of stuff in tables, pairs(table) used in that for loop allows you to iterate over every object in the table.
Like I said, I'm extremely new to programming so you kind of lost me. I don't know what a "for loop" is and I'm not familiar with keeping things in tables. Sorry for my inexcusable noobedness.
User avatar
counterfactual_jones
Prole
Posts: 24
Joined: Mon Feb 09, 2009 10:14 am

Re: Physics, applyImpulse, dt and other things

Post by counterfactual_jones »

Broncheabones wrote:Like I said, I'm extremely new to programming so you kind of lost me. I don't know what a "for loop" is and I'm not familiar with keeping things in tables. Sorry for my inexcusable noobedness.
I'm new to lua as well, only it's not my first language.

You might like to experiment with timers as well, my protagonist has a 'jump' that activates after a tiny pause.
Broncheabones
Prole
Posts: 15
Joined: Wed Feb 04, 2009 5:25 am

Re: Physics, applyImpulse, dt and other things

Post by Broncheabones »

Hmm, I edited my code to fit in the function handle_collision however now my ball can jump whenever it wants. I hate to keep doing this trial and error but let me know if I screwed up somewhere along the way.

Code: Select all

function load()
 
   -- Create a world with size 2000 in every direction. 
   world = love.physics.newWorld(2000, 2000) 
   world:setGravity(0, 100) 
   world:getGravity (x, y)
 
   -- Create the ground body at (0, 0) with mass 0. 
   ground = love.physics.newBody(world, 0, 0, 0) 
    
   -- Create the ground shape at (400,500) with size (600,10). 
   ground_shape = love.physics.newRectangleShape(ground, 400, 400, 600, 10)
   ground_shape2 = love.physics.newRectangleShape(ground, 275, 250, 600, 10)
   ground_shape3 = love.physics.newRectangleShape(ground, 400, 100, 600, 10)
   wall_shape = love.physics.newRectangleShape(ground, 710, 300, 10, 410)
   wall_shape2 = love.physics.newRectangleShape(ground, 800, 300, 10, 600)
   wall_shape3 = love.physics.newRectangleShape(ground, 400, 600, 780, 10)
   wall_shape4 = love.physics.newRectangleShape(ground, 0, 300, 10, 600)
   wall_shape5 = love.physics.newRectangleShape(ground, 400, 0, 780, 10) 
 
   -- Load the image of the ball. 
   ball = love.graphics.newImage("ball.png") 
 
   -- Create a Body for the circle. 
   body = love.physics.newBody(world, 200, 350)
    
   -- Attatch a shape to the body. 
   circle_shape = love.physics.newCircleShape(body, 28)
   circle_shape:setFriction(1.0)
   circle_shape:setData("player")
    
   -- Calculate the mass of the body based on attatched shapes. 
   -- This gives realistic simulations. 
   body:setMassFromShapes()
   
   background = love.graphics.newImage("background.png")
   
   isFalling = false
 
end

function update(dt)

if love.keyboard.isDown(love.key_d) then
      body:applyImpulse(400000*dt, 0)
   elseif love.keyboard.isDown(love.key_a) then
	  body:applyImpulse(-400000*dt, 0)
   end 
   
   if love.keyboard.isDown(love.key_w) and isFalling == false then
   		body:applyImpulse(0, -800000)
   end

   world:update(dt)
end
 
function draw()

	love.graphics.draw(background, 400, 300)
   -- Draws the ground. 
   love.graphics.polygon(love.draw_fill, ground_shape:getPoints())
   love.graphics.polygon(love.draw_fill, ground_shape2:getPoints())
   love.graphics.polygon(love.draw_fill, ground_shape3:getPoints())
   love.graphics.polygon(love.draw_fill, wall_shape:getPoints())
   love.graphics.polygon(love.draw_fill, wall_shape2:getPoints())
   love.graphics.polygon(love.draw_fill, wall_shape3:getPoints())
   love.graphics.polygon(love.draw_fill, wall_shape4:getPoints())
   love.graphics.polygon(love.draw_fill, wall_shape5:getPoints())
 
   -- Draw the circle. 
   love.graphics.draw(ball,body:getX(), body:getY(), body:getAngle())

   love.graphics.draw("Vertical Velocity: " .. y, 50, 50)

end 

function handle_collision(shapedata1, shapedata2, contact)
	x, y = body:getPosition()
    cx, cy = contact:getPosition()
   print(x.."x"..y.." cx: "..cx.." cy: "..cy)
   if shapedata1 == "player" and y < cy then
      isFalling = false
   end
   if shapedata2 == "player" and y < cy then
      isFalling = false
   end
end
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Physics, applyImpulse, dt and other things

Post by bartbes »

Change the following bit:

Code: Select all

   if love.keyboard.isDown(love.key_w) and isFalling == false then
         body:applyImpulse(0, -800000)
         isFalling = true
   end
That should do it, previously isFalling would never be set to true.
BTW you might try

Code: Select all

if love.keyboard.isDown(love.key_w) and not isFalling then
(not that it's different, but it's good to know it's possible)
Broncheabones
Prole
Posts: 15
Joined: Wed Feb 04, 2009 5:25 am

Re: Physics, applyImpulse, dt and other things

Post by Broncheabones »

Thanks bartbes, I'm such an idiot for forgetting that.

However, my problem now is that I can't jump after my first jump.
Post Reply

Who is online

Users browsing this forum: keharriso and 79 guests