I have a collision module
local M = {}
local collision_bits = {
PLAYER = 1, -- (2^0)
GROUND = 2, -- (2^1)
}
local tile_width = 16
local tile_height = 16
function M.init()
M.static_group = daabbcc.new_group(daabbcc.UPDATE_INCREMENTAL)
M.dynamic_group = daabbcc.new_group(daabbcc.UPDATE_FULLREBUILD)
M.player_aabb_id = nil
M.ground_data = {}
end
function M.add_tilemap(tilemap_url, layer)
local x, y, w, h = tilemap.get_bounds(tilemap_url)
for row = y, y + h - 1 do
for col = x, x + w - 1 do
local tile_index = tilemap.get_tile(tilemap_url, layer, col, row)
if tile_index == 17 then -- ground tile hard coded?
local tile_x = (col - 1) * tile_width
local tile_y = (row + 0.22) * tile_height -- these modifiers are what got the debug lines drawn in the correct place (shrug)
local aabb_id = daabbcc.insert_aabb(M.static_group, tile_x, tile_y, tile_width, tile_height, collision_bits.GROUND)
M.ground_data[aabb_id] = { type = "GROUND", x = tile_x, y = tile_y, width = tile_width, height = tile_height }
end
end
end
end
function M.add_player(player_url, player_width, player_height)
M.player_aabb_id = daabbcc.insert_gameobject(M.dynamic_group, player_url, player_width, player_height, collision_bits.PLAYER)
end
local function debug_draw_aabb(aabb_data, color)
for _, data in pairs(aabb_data) do
local x, y = data.x, data.y
local width, height = data.width, data.height
msg.post("@render:", "draw_line", { start_point = vmath.vector3(x, y, 0), end_point = vmath.vector3(x + width, y, 0), color = color })
msg.post("@render:", "draw_line", { start_point = vmath.vector3(x, y, 0), end_point = vmath.vector3(x, y + height, 0), color = color })
msg.post("@render:", "draw_line", { start_point = vmath.vector3(x + width, y, 0), end_point = vmath.vector3(x + width, y + height, 0), color = color })
msg.post("@render:", "draw_line", { start_point = vmath.vector3(x, y + height, 0), end_point = vmath.vector3(x + width, y + height, 0), color = color })
end
end
function M.debug_draw(player_pos)
debug_draw_aabb(M.ground_data, vmath.vector4(1, 0, 0, 1))
debug_draw_aabb({ { x = player_pos.x - 46 / 2, y = player_pos.y - 54 / 2, width = 46, height = 54 } }, vmath.vector4(0, 1, 0, 1))
end
function M.query_player()
local result, count = daabbcc.query_id(M.static_group, M.player_aabb_id, collision_bits.GROUND)
return result, count
end
return M
You can visualize what’s going on here.
I found it really strange that the only way I could get the debug lines drawn in the correct place was if I added random 0.22
here
local tile_y = (row + 0.22) * tile_height
And it’s unfortunate that the player assets has a lot of extra space because I don’t think I can draw a more precise collision box using insert_gameobject
, but these really are secondary issues.
The bigger issue is that collisions are being detected regardless of where the player is on the map. For instance in the picture, even though he is in the air, he has ground contact.
function check_collisions(self)
local query_result, result_count = collision.query_player()
if query_result then
for i = 1, result_count do
local aabb_id = query_result[i]
local data = collision.ground_data[aabb_id]
if data then
print(string.format("Collision with %s at (%d, %d)", data.type, data.x, data.y))
if data.type == "GROUND" then
self.velocity.y = 0
self.ground_contact = true
end
else
print("Unknown collision!")
end
end
end
end
It detects three collisions, even though the player is in the air. As far as I can tell it detects collision no matter where the player is on the map.
DEBUG:SCRIPT: Collision with GROUND at (0, 35)
DEBUG:SCRIPT: Collision with GROUND at (16, 35)
DEBUG:SCRIPT: Collision with GROUND at (16, 19)
I know that this is probably an error on my part. But I’m not sure what could be going on.
I’d appreciate any insight from someone with more experience on this library.