Page 2 of 3

Re: Physics, applyImpulse, dt and other things

Posted: Mon Feb 09, 2009 2:24 pm
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.

Re: Physics, applyImpulse, dt and other things

Posted: Mon Feb 09, 2009 11:29 pm
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

Re: Physics, applyImpulse, dt and other things

Posted: Tue Feb 10, 2009 2:28 am
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

Re: Physics, applyImpulse, dt and other things

Posted: Tue Feb 10, 2009 4:09 am
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

Re: Physics, applyImpulse, dt and other things

Posted: Tue Feb 10, 2009 6:09 am
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

Re: Physics, applyImpulse, dt and other things

Posted: Tue Feb 10, 2009 6:26 am
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.

Re: Physics, applyImpulse, dt and other things

Posted: Tue Feb 10, 2009 6:43 am
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.

Re: Physics, applyImpulse, dt and other things

Posted: Tue Feb 10, 2009 7:09 am
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

Re: Physics, applyImpulse, dt and other things

Posted: Tue Feb 10, 2009 7:15 am
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)

Re: Physics, applyImpulse, dt and other things

Posted: Tue Feb 10, 2009 7:26 am
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.