Reptile: Tile-Based Collision for Lua

Showcase your libraries, tools and other projects that help your fellow love users.
Post Reply
User avatar
Puzzlem00n
Party member
Posts: 171
Joined: Fri Apr 06, 2012 8:49 pm
Contact:

Reptile: Tile-Based Collision for Lua

Post by Puzzlem00n »

Alright, so, here's the gist: I had started this library a few months ago, and I'd thought that I might add more features to it before showing it off, but I seem to have ignored it long enough to consider that a lost cause. Therefore, I might as well "release" it now while it's still functional!

Presenting Reptile, a library that detects and resolves collisions between a rectangular object and a square-tile grid. The (as-of-now) ultimate result of all my years of coding these collisions. Rushed example:

Code: Select all

--Requiring the library
reptile = require "reptile"

love.window.setMode(200, 200)

function love.load()
	tsize = 40
	reptile.setSize(tsize)
	map = {
		{1, 1, 1, 1, 1},
		{1, 0, 0, 0, 1},
		{1, 0, 1, 1, 1},
		{1, 0, 0, 0, 1},
		{1, 1, 1, 1, 1}
	}
	
	player = {
		l = 60, t = 60,
		w = 20, h = 20,
		vx = 0, vy = 0
	}
end

function love.update(dt)
	local speed = 180 * dt
	player.vx, player.vy = 0, 0
	if love.keyboard.isDown("left") then
		player.vx = -speed
	elseif love.keyboard.isDown("right") then
		player.vx = speed
	elseif love.keyboard.isDown("up") then
		player.vy = -speed
	elseif love.keyboard.isDown("down") then
		player.vy = speed
	end
	
	--CORE FUNCTION OF THE LIBRARY HERE
	--You must pass a table with l and t (left and top), w and h (width and height), and
	--vx and vy (velocities for each axis).
	local cols = reptile.collide(player)
	player.l, player.t = cols.l, cols.t
end

--Here you must define a function that returns true if the given grid coordinate is a tile.
function reptile.checkGrid(x, y)
	local check = map[x + 1][y + 1]
	if check == 1 then
		return true
	end
end

function love.draw()
	love.graphics.translate(-40, -40)
	--Draw Map
	for y = 1, #map do
		for x = 1, #map[y] do
			if map[y][x] == 1 then
				love.graphics.setColor(255,255,255)
				love.graphics.rectangle("fill", x * tsize, y * tsize, tsize, tsize)
			end
		end
	end
	
	love.graphics.translate(40, 40)
	--Draw Player
	love.graphics.setColor(100,100,255)
	love.graphics.rectangle("line", player.l, player.t, player.w, player.h)
end
Why would I use this? bump.lua handles collisions between rectangles already, doesn't it?
Right you are. But using bump forces you to define every tile in the grid as a separate collision object, which I find unnecessarily complicated for rectangle-to-tile collision.

Known Issues:
  • The colliding object can NOT be more than two times the tile size in either with or height. This is intended to be more dynamic in the future.
  • If you press two arrow keys and move diagonally into a wall, assuming the implementation of a top-down style game, you will slow down in trying to rub against it. I've personally never found this to be to big a problem, but you might not like it.
I hope someone can find a use for this! If anyone has any questions or complaints, let me know.
I LÖVE, therefore I am.
LXDominik
Prole
Posts: 26
Joined: Wed Oct 01, 2014 9:05 am

Re: Reptile: Tile-Based Collision for Lua

Post by LXDominik »

Hi! i have a question. If i have map table like this :

Code: Select all

map = {
      1, 1, 1, 1, 1,
      1, 0, 0, 0, 1,
      1, 0, 1, 1, 1,
      1, 0, 0, 0, 1,
      1, 1, 1, 1, 1
   }
What should i call in reptile.checkGrid?
Also what about different collisions? player vs enemy, collectable, etc?
User avatar
Positive07
Party member
Posts: 1014
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Reptile: Tile-Based Collision for Lua

Post by Positive07 »

reptile.checkGrid is called by reptile itself with the arguments x and y being the position in the grid so if you have your map like the one you posted above you can use the function in the example posted by Puzzlem00n and it should work wonderfully (I hope)

Take into account the reptile.setSize because that defines the position of your tiles, if this is not the same as your tile size it wont work

Reptile doesnt handle object collisions but for those things you can use AABB or the Bounding box algorithm that checks collisions between two rectangles.

A feature request: I would love if you could add object detection to reptile. This way I can know which tile I collided with and which type of tile it was, you just need to return the indexes of the collision I guess (x and y?). This would be helpful for grid based pickups, power-ups and such)
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests