# Physics part 3

In the last two physics tutorials, we looked at how to create bodies, shapes and how to move them around. Generally, we told Box2D what to do. Conversely, this tutorial focuses on getting information back from Box2D using queries and contact listeners.

## Querying the world

Searching through a world is done using the "Query" function. The QueryAABB function accepts a rectangular area in the form of a b2.AABB. Box2D then finds all shapes that "potentially" intersect with the supplied rectangular area. It is important here to emphasize the word "potentially". The query may contain some shapes that do not overlap the supplied AABB. The reason why the QueryAABB function is so inconsistent is because it was designed as a quick filter used during Box2D's broad collision phase.

In the next bit of code, we are going to implement a "QueryPoint" function. This sort of function is useful in games where you want to select shapes or bodies using the mouse.

```local slop = b2.linearSlop/2
local aabb = b2.AABB()
function b2.World:QueryPoint ( pt )
-- query potential shapes
local q = {}
local qcb = b2.QueryCallback()
qcb.ReportFixture = function(qcb, f)
-- ignore shapes if the point is not inside them
if f:TestPoint(pt) then
table.insert(q, f)
end
return true
end
aabb.lowerBound:Set(pt.x - slop, pt.y - slop)
aabb.upperBound:Set(pt.x + slop, pt.y + slop)
self:QueryAABB(qcb, aabb)
return q
end```

Next, we are going to populate the Box2D world with some arbitrary shapes. Notice that we are using some Lua functions (such as "NewBody", "NewBox" and "OnCreate") that were written and explained in the previous physics tutorial.

```-- create a new world
gravity = b2.Vec2 ( 0, 0 )
world = b2.World ( gravity )

-- create a bunch of bodies and shapes
for x = -100, 100, 10 do
for y = -100, 100, 10 do
local body = world:NewBody ( "staticBody", x, y, 0, 2, 2, false, false, false, false )
local shape = body:NewBox ( 2, 2, 0.1, 0.5, 0.5, false )
body:OnCreate ( )
end
end```

Using the "QueryPoint" function, we will allow the user select one body at a time by pressing the mouse. When selecting a body, its sprite changes color to RED. The tricky part here is transforming the mouse cursor position to world coordinates. This is necessary because the mouse cursor is in a different coordinate system than the physics simulation. In other words, the bodies and shapes rendered on screen are usually transformed and often scaled.

```-- currently selected body
selected = nil

mouse.on_press = function ( mouse, button )
-- deselect the previously selected body
if selected then
selected.sprite.color = WHITE
selected = nil
end

-- make a new query at the cursor position
local pt = b2.Vec2 ( mouse.xaxis, mouse.yaxis )
pt.x, pt.y = camera:get_world_point ( pt.x, pt.y )
local q = world:QueryPoint ( pt )

-- color the selected body red
if #q > 0 then
selected = q[1]:GetBody ( )
selected.sprite.color = RED
end
end```

## Collision callbacks

In most games, you need to know when two particular objects have collided. Box2D reports these events to Lua using "contact listeners". b2.ContactListener is simply a class containing some callback functions that are evoked by Box2D. Let's look at some Lua code that creates and activates a new contact listener:

```local listener = b2.ContactListener ( )

listener.BeginContact = function ( listener, ct )
-- called when two fixtures begin to touch
end
listener.EndContact = function ( listener, ct )
-- called when two fixtures cease to touch
end
listener.PreSolve = function ( listener, ct, om )
-- called before a collision is resolved
end
listener.PostSolve = function ( listener, ct, ci )
-- called after a collision is resolved
end

world:SetContactListener ( listener )```

As you can see, b2.ContactListener has four callback functions. "PostSolve" would probably be the most useful callback in making an action game since it's called after the collision has been resolved. Notice that sensor shapes do not raise the "PreSolve" or "PostSolve" callbacks since they do not respond to collisions. I suggest looking at the Box2D documentation for the full details on the b2.Contact object.

There is a catch to using contact listeners. Box2D does not allow you to make changes to the world during a collision callback. This means that you cannot destroy or create a body or shape until the collision callback function has returned. What you usually have to do is mark the particular body or shape for deletion and destroy it later. Next, we will look at some example code which shows how this is done:

```-- set up a contact listener
listener = b2.ContactListener ( )
listener.PostSolve = function ( listener, ct, ci )
local fix1 = ct:GetFixtureA ( )
local fix2 = ct:GetFixtureB ( )
local body1 = fix1:GetBody ( )
local body2 = fix2:GetBody ( )

-- mark bodies for deletion
if (body1.type == 'player' and body2.type == 'enemy') then
elseif (body1.type == 'enemy' and body2.type == 'player') then
end
end
world:SetContactListener ( listener )```

There are several things to note at this point. First off, collision callbacks may be evoked at the moment a new shape is created (assuming that the newly created shape is initially in contact with another shape). This suggests that contact listeners should be set before any shapes have been generated. Secondly, the collision callbacks always work with shapes. b2.Contact contains the two colliding shapes, but you need to get the associated bodies yourself.

Going back to our example, we will now add some bodies to the world. After creating each body, we assign it its 'type' property (in this case a string value, either 'player' or 'enemy'). In this example, the collision callback looks up the 'type' property so it must be assigned before any of the callbacks could be evoked.

```-- create a bunch of bodies and shapes
for x = -100, 100, 10 do
for y = -100, 100, 10 do
local body = world:NewBody ( "staticBody", x, y, 0, 2, 2, false, false, false, false )
body.type = 'enemy'
local shape = body:NewBox ( 2, 2, 0.1, 0.5, 0.5, false )
body:OnCreate ( )
end
end

-- create a user-controlled body
player = world:NewBody ( "dynamicBody", 0, 0, 0, 2, 0, false, false, false, false )
player.type = 'player'
local shape = player:NewCircle ( 1, 0, 0, 0.1, 0.5, 0.5, false )
player:OnCreate ( )```

The last part of the code shouldn't come as a surprise, especially if you have read the last Box2D tutorial. A timer object is set up to continuously destroy the marked bodies, move the player and to update the world simulation. By running the script, you can see how any bodies that come in contact with our little 'player' object get destroyed.

```timer = Timer ( )
timer:start ( 16, true )
timer.on_tick = function ( timer )
-- destroy marked bodies
local body = world:GetBodyList ( )
while body do
local next = body:GetNext ( )
if body.state == 'dead' then
body:OnDestroy ( )
world:DestroyBody ( body )
end
body = next
end

-- check for player input
local position = b2.Vec2 ( )
player:GetPosition ( position )
if keyboard:is_down ( KEY_UP ) == true then
player:ApplyForce ( b2.Vec2 ( 0, 10 ), position, true )
end
if keyboard:is_down ( KEY_DOWN ) == true then
player:ApplyForce ( b2.Vec2 ( 0, -10 ), position, true )
end
if keyboard:is_down ( KEY_LEFT ) == true then
player:ApplyForce ( b2.Vec2 ( -10, 0 ), position, true )
end
if keyboard:is_down ( KEY_RIGHT ) == true then
player:ApplyForce ( b2.Vec2 ( 10, 0 ), position, true )
end

-- update the physics simulation
local seconds = timer:get_delta_ms ( ) / 1000
world:Step ( seconds, 10, 8 )

-- iterate all bodies and update their sprites
local body = world:GetBodyList ( )
while body do
body:OnUpdate ( )
body = body:GetNext ( )
end
end```