Difference between revisions of "Tutorial:PhysicsCollisionCallbacks"
(Created a tutorial for using world:setCallbacks) |
m (Linked to contact functions) |
||
Line 116: | Line 116: | ||
Say we want to print to screen whenever a callback is called. All we have to do is create a variable to store the strings and then append to the string everytime a collision action happens. | Say we want to print to screen whenever a callback is called. All we have to do is create a variable to store the strings and then append to the string everytime a collision action happens. | ||
+ | |||
+ | A list of functions you can use on contacts can be found at the [[Contact]] page. | ||
<source lang="lua"> | <source lang="lua"> |
Revision as of 19:12, 27 February 2010
Preface
If you do not have a good grasp on love.physics, you should first check out this physics tutorial.
In this tutorial we will create a collision between two objects that calls certain callbacks set by World:setCallbacks.
main.lua setup
I usually start every main.lua with 3 love functions: love.load, love.update, and love.draw
function love.load()
end
function love.update(dt)
end
function love.draw()
end
World setup
Now that we have a framework setup, let's setup a physics world in love.load with newWorld.
Also we will use World:setGravity and World:update.
function love.load()
--Store the new world in a variable such as "world"
world = love.physics.newWorld(800,600)
--Gravity is being set to 0 in the x direction and 20 in the y direction.
world:setGravity(0,20)
end
function love.update(dt)
--Never forget to update your world every frame.
world:update(dt)
end
Now we want to create a ball and a ground. To do this we will need newBody, newCircleShape, and newRectangleShape.
function love.load()
--Store the new world in a variable such as "world"
world = love.physics.newWorld(800,600)
--Gravity is being set to 0 in the x direction and 20 in the y direction.
world:setGravity(0,20)
ball = {}
ball.b = love.physics.newBody(world, 400,200, 10,0)
ball.s = love.physics.newCircleShape(ball.b, 0,0, 50)
ball.s:setData("Ball")
static = {}
static.b = love.physics.newBody(world, 400,400, 0,0)
static.s = love.physics.newRectangleShape(static.b, -100,-25, 200,50, 0)
static.s:setData("Block")
end
The balls are there now, but you can't yet see them. Let's draw them. This can be a bit tricky at times to match up the origins of objects.
function love.draw()
love.graphics.circle("line", ball.b:getX(),ball.b:getY(), ball.s:getRadius())
local x1,y1, _,_, x3,y3, _,_ = static.s:getBoundingBox()
local w = x3-x1
local h = y3-y1
love.graphics.rectangle("line",
static.b:getX()-w/2,static.b:getY(),
w,h, 0)
end
Now we should see a ball fall down and hit a solid rectangle.
World Callbacks
But what if we want more information on the two objects colliding? Now we will use World:setCallbacks to further dissect their collision(s).
First thing we do is set the world callbacks with World:setCallbacks. There are four callbacks for a collision: add, persist, remove, and result.
- Add is the callback for every new collision.
- Persist is the callback for every collision that is continuing from last frame.
- Remove is the callback for any collision that stopped happening since last frame.
- Result is the callback for ???.
function love.load()
--Store the new world in a variable such as "world"
world = love.physics.newWorld(800,600)
--Gravity is being set to 0 in the x direction and 20 in the y direction.
world:setGravity(0,20)
--Can be almost any function names you want.
world:setCallbacks(add, persist, rem, result)
ball = {}
ball.b = love.physics.newBody(world, 400,200, 10,0)
ball.s = love.physics.newCircleShape(ball.b, 0,0, 50)
ball.s:setData("Ball")
static = {}
static.b = love.physics.newBody(world, 400,400, 0,0)
static.s = love.physics.newRectangleShape(static.b, -100,-25, 200,50, 0)
static.s:setData("Block")
end
Now define each function you just named.
function add(a, b, coll)
end
function persist(a, b, coll)
end
function rem(a, b, coll)
end
function result(a, b, coll)
end
These functions are called everytime one of the collision actions happen.
Say we want to print to screen whenever a callback is called. All we have to do is create a variable to store the strings and then append to the string everytime a collision action happens.
A list of functions you can use on contacts can be found at the Contact page.
text = ""
function add(a, b, coll)
text = text..a.." collding with "..b.." at an angle of "..coll:getNormal().."\n"
end
function persist(a, b, coll)
text = text..a.." touching "..b.."\n"
end
function rem(a, b, coll)
text = text..a.." uncolliding "..b.."\n"
end
function result(a, b, coll)
text = text..a.." hit "..b.."resulting with "..coll:getNormal().."\n"
end
And now you know how to use world callbacks!
Entire Thing
function love.load()
world = love.physics.newWorld(800,600)
world:setGravity(0,20)
world:setCallbacks(add, persist, rem, result)
ball = {}
ball.b = love.physics.newBody(world, 400,200, 10,0)
ball.s = love.physics.newCircleShape(ball.b, 0,0, 50)
ball.s:setData("Ball")
static = {}
static.b = love.physics.newBody(world, 400,400, 0,0)
static.s = love.physics.newRectangleShape(static.b, -100,-25, 200,50, 0)
static.s:setData("Block")
end
function love.update(dt)
world:update(dt)
end
function love.draw()
love.graphics.circle("line", ball.b:getX(),ball.b:getY(), ball.s:getRadius())
local x1,y1, _,_, x3,y3, _,_ = static.s:getBoundingBox()
local w = x3-x1
local h = y3-y1
love.graphics.rectangle("line",
static.b:getX()-w/2,static.b:getY(),
w,h, 0)
love.graphics.print(text,0,12)
end
--Refer to http://love2d.org/wiki/Contact for more information on collision objects
--'coll' is an object created by the collision
--'a' is the first object in the collision and 'b' is the second
text = ""
function add(a, b, coll)
text = text..a.." collding with "..b.." at an angle of "..coll:getNormal().."\n"
end
function persist(a, b, coll)
text = text..a.." touching "..b.."\n"
end
function rem(a, b, coll)
text = text..a.." uncolliding "..b.."\n"
end
function result(a, b, coll)
text = text..a.." hit "..b.."resulting with "..coll:getNormal().."\n"
end