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.