[Love 0.8] Detecting Collision with Sensors

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.
Post Reply
User avatar
kalium
Prole
Posts: 9
Joined: Fri Jul 06, 2012 6:36 pm
Location: Rio de Janeiro

[Love 0.8] Detecting Collision with Sensors

Post by kalium »

So, hello everyone. I'm new to the Löve forums, but not new to programming.

I've been trying to make a 2D Platformer game in Löve2D, and i've started a few days ago. It's going quite well, but i've stumbled upon a problem.
I have searched the wiki and the forums, but haven't found a reasonable explanation on how to use 'sensor' type fixtures to detect collisions.
According to what I found on the wiki, you use fixture:setUserData to select the data that will be passed upon collision, right?
Where is this data sent to? How can i make, for example, a sensor to detect when the player passes through it?
User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: [Love 0.8] Detecting Collision with Sensors

Post by Boolsheet »

Fixtures that are set to sensors do not collide with anything. They don't produce pre or post collision callbacks, but they still generate begin and end callbacks when other fixtures start or stop to overlap them. There you will be notified when the player shape starts overlapping.

Fixture:setUserData can be used to give the fixture some kind of identification. You get this value back with Fixture:getUserData. The physics module does not use this value in any other way.

Here's an example where the sensor area will be colored green if the stone touches it.

Code: Select all

local rnd = function() return math.random() - 0.5 end

function beginCallback(fixture1, fixture2, contact)
	if fixture1:getUserData() == "sensor" or fixture2:getUserData() == "sensor" then
		Sensor.touching = Sensor.touching + 1
	end
end

function endCallback(fixture1, fixture2, contact)
	if fixture1:getUserData() == "sensor" or fixture2:getUserData() == "sensor" then
		Sensor.touching = Sensor.touching - 1
	end

	-- The contact handling in 0.8.0 is buggy. Do a full garbage collection to prevent some nasty crash.
	contact = nil
	collectgarbage()
end

function love.load()
	World = love.physics.newWorld(0, 100, true)
	World:setCallbacks(beginCallback, endCallback)

	local circlePoints = {}

	for i = 1, 30 do
		local angle = (i - 1) / 30 * (math.pi * 2)
		local x, y = math.cos(angle) * 250 + rnd() * 40, math.sin(angle) * 250 + rnd() * 40
		circlePoints[i * 2 - 1], circlePoints[i * 2] = x, y
	end

	Circle = {}
	Circle.body = love.physics.newBody(World, 0, 0, "kinematic")
	Circle.shape = love.physics.newChainShape(true, unpack(circlePoints))
	Circle.fixture = love.physics.newFixture(Circle.body, Circle.shape)
	Circle.body:setAngularVelocity(0.5)


	Stone = {}
	Stone.body = love.physics.newBody(World, 0, 0, "dynamic")
	Stone.shape1 = love.physics.newPolygonShape(23, 19, 46, 24,  69, 104, 14, 93, 1, 59)
	Stone.shape2 = love.physics.newPolygonShape(46, 24, 77, 0, 130, 68, 115, 90, 69, 104)
	Stone.fixture1 = love.physics.newFixture(Stone.body, Stone.shape1, 5)
	Stone.fixture2 = love.physics.newFixture(Stone.body, Stone.shape2, 5)

	Sensor = {}
	Sensor.body = love.physics.newBody(World, 0, 200, "static")
	Sensor.shape = love.physics.newRectangleShape(150, 100)
	Sensor.fixture = love.physics.newFixture(Sensor.body, Sensor.shape)
	Sensor.touching = 0
	Sensor.fixture:setSensor(true)
	Sensor.fixture:setUserData("sensor")
end

function love.update(dt)
	World:update(dt)
end

function love.draw()
	love.graphics.translate(400, 300)

	love.graphics.line(Circle.body:getWorldPoints(Circle.shape:getPoints()))

	love.graphics.polygon("line", Stone.body:getWorldPoints(Stone.shape1:getPoints()))
	love.graphics.polygon("line", Stone.body:getWorldPoints(Stone.shape2:getPoints()))

	if Sensor.touching > 0 then
		love.graphics.setColor(0, 255, 0, 100)
		love.graphics.polygon("fill", Sensor.body:getWorldPoints(Sensor.shape:getPoints()))
		love.graphics.setColor(255, 255, 255)
	end

	love.graphics.polygon("line", Sensor.body:getWorldPoints(Sensor.shape:getPoints()))
end
Shallow indentations.
User avatar
kalium
Prole
Posts: 9
Joined: Fri Jul 06, 2012 6:36 pm
Location: Rio de Janeiro

Re: [Love 0.8] Detecting Collision with Sensors

Post by kalium »

Hmmm, I think I understand it now.
Thanks a lot.
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 6 guests