Page 1 of 1

Trouble debugging Bump

Posted: Thu Jul 23, 2015 11:28 pm
by Snowbadger
Hey everyone,

Experimenting with Bump for a few days has helped me accomplish most of what I'm wanting to do, but I seem to be having a weird issue.

I've got my player and collision objects set up and they seem to be working as expected. For further testing purposes, I'm wanting to make the hitboxes/collision boundaries visible.

This in love.draw() works just as expected and shows the rectangle around the player:

Code: Select all

love.graphics.setColor(255,0,0)
love.graphics.rectangle('line', world:getRect(p))
However, when I try to do the same to show where the level's walls are collidable, I get this error:
Item nil must be added to the world before getting its rectangle. Use world:add (item, x, y, w, h) to add it first.
Again, the collision IS actually working with the walls and I added them the same way I did the player (which works and displays correctly), so any ideas why might I be getting this error when they do in fact seem added to the world?

Re: Trouble debugging Bump

Posted: Fri Jul 24, 2015 7:48 am
by kikito
Hi there,

Your problem is that you are passing 'nil' to world:getRect.

Quite literally, the value of the variable 'p' (or whatever name you used in your code for it) is nil. It is difficult to know exactly where the problem is without reading your whole code. It might be that you copy-pasted your debugging code from a place where the variable was called p, but on this new place it should be called something else.

Re: Trouble debugging Bump

Posted: Fri Jul 24, 2015 10:11 am
by Snowbadger
kikito wrote:Hi there,

Your problem is that you are passing 'nil' to world:getRect.

Quite literally, the value of the variable 'p' (or whatever name you used in your code for it) is nil. It is difficult to know exactly where the problem is without reading your whole code. It might be that you copy-pasted your debugging code from a place where the variable was called p, but on this new place it should be called something else.
D'oh. I don't know how I missed it but those variables were indeed out of scope at that point. :oops: Thank you for your response and for your great libraries!

I am running into another issue, though I'm not sure if it's related to Bump. In my little test, I'm trying to offset the collision box for the character. The initial position is correct (although very messily coded at the moment), but as soon as the character moves, the hitbox snaps to the character's origin.
correct.gif
correct.gif (175.96 KiB) Viewed 2979 times
suddenlynot.gif
suddenlynot.gif (175.61 KiB) Viewed 2979 times
I suspect it's because I'm not updating something correctly with the character movement, but I don't know if it's because I should add a separate item to the Bump world or I'm just overlooking some math when moving the character... or something else?

My main.lua:

Code: Select all

local p -- player 
local spritesheet

local anim8 = require 'lib.anim8.anim8'
local bump = require 'lib.bump.bump'
local sti = require 'lib.sti'

local map
local world

function love.load()
	map = sti.new('map')
	world = bump.newWorld()

	love.graphics.setDefaultFilter('nearest', 'nearest')

	spritesheet = love.graphics.newImage('placeholderguy.png')
	local grid = anim8.newGrid(50, 48, spritesheet:getWidth(), spritesheet:getHeight())


	p = {
	spritesheet = spritesheet,
	-- set initial player position to center
		x = (love.graphics.getWidth() / 2) - 50, 
		y = (love.graphics.getHeight() / 2) - 48, 
		speed = 200,
		width = 50, -- frame width
		height = 48, -- frame height
		hitX = ((love.graphics.getWidth() / 2)  - 36), -- offset hitbox
		hitY = ((love.graphics.getHeight() / 2) - 26), 
		hitW = 22, -- hitbox width
		hitH = 19, -- hitbox height
		animations = {
			idle = anim8.newAnimation(grid(2, 1), 0.2), -- default state (single frame)
			up = anim8.newAnimation(grid('5-8', 1), 0.2), -- play the first row of columns 5-8 for 0.2
			down = anim8.newAnimation(grid('1-4', 1), 0.2), 
			left = anim8.newAnimation(grid('5-8', 2), 0.2),
			right = anim8.newAnimation(grid('1-4', 2), 0.2)
		}
	}

	p.animation = p.animations.idle -- set default to idle

	-- testing collision walls
	 box = {x = 349, y = 115, w = 41, h = 144}
	 box2 = {x = 350, y = 115, w = 288, h = 23}
	 box3 = {x = 349, y = 322, w = 37, h = 156}
	 box4 = {x = 0, y = 0, w = 219, h = 52}

	world:add(box, box.x, box.y, box.w, box.h)
	world:add(box2, box2.x, box2.y, box2.w, box2.h)
	world:add(box3, box3.x, box3.y, box3.w, box3.h)
	world:add(p, p.hitX, p.hitY, p.hitW, p.hitH)
end

function love.draw()
	map:draw()
	p.animation:draw(p.spritesheet, p.x, p.y)

	-- outline player frame
	love.graphics.setColor(0,255,0)
  love.graphics.rectangle('line', p.x, p.y, p.width, p.height)

	-- show collision rectangles for debugging
 	love.graphics.setColor(255,0,0)
  love.graphics.rectangle('line', world:getRect(p))
  love.graphics.rectangle('line', world:getRect(box))
  love.graphics.rectangle('line', world:getRect(box2))
  love.graphics.rectangle('line', world:getRect(box3))

end

function love.update(dt)
	map:update()

	-- Player movement using Bump
	if love.keyboard.isDown("a") then
		local goalX, goalY
		goalX = p.x - p.speed * dt
		goalY = p.y

		local actualX, actualY = world:move(p, goalX, goalY)
		p.x, p.y = actualX, actualY

		p.animation = p.animations.left

	elseif love.keyboard.isDown("d") then
		local goalX, goalY
		goalX = p.x + p.speed * dt
		goalY = p.y

		local actualX, actualY = world:move(p, goalX, goalY)
		p.x, p.y = actualX, actualY

		p.animation = p.animations.right

	elseif love.keyboard.isDown("w") then
		local goalX, goalY
		goalX = p.x
		goalY = p.y - p.speed *dt
		
		local actualX, actualY = world:move(p, goalX, goalY)
		p.x, p.y = actualX, actualY

		p.animation = p.animations.up

	elseif love.keyboard.isDown("s") then
		local goalX, goalY
		goalX = p.x
		goalY = p.y + p.speed *dt
		
		local actualX, actualY = world:move(p, goalX, goalY)
		p.x, p.y = actualX, actualY

		p.animation = p.animations.down
	else

		p.animation = p.animations.idle
	end
	
	-- Collision detection to keep within window
	if p.x < 0 then
		p.x = 0
	end

	if p.x > love.graphics.getWidth() - p.width then
		p.x = love.graphics.getWidth() - p.width
	end

	if p.y < 0 then
		p.y = 0
	end
	
	if p.y > love.graphics.getHeight() - p.height then
		p.y = love.graphics.getHeight() - p.height
	end	

	p.animation:update(dt)
end

Re: Trouble debugging Bump

Posted: Fri Jul 24, 2015 10:23 am
by Fenrir
I didn't looked to your code but I can assure you that your issue is not related to Bump and it's a problem in your side, I'm using quite intensively Bump and it's pretty solid, updating colliders position is working perfectly.

Re: Trouble debugging Bump

Posted: Fri Jul 24, 2015 8:03 pm
by Snowbadger
Sorry for being unclear. I'm sure it's an error on my part -- I just can't determine if the error is due to a misuse of Bump or a misuse of Simple Tiled Integration. I am pretty rusty on programming and completely new to collision logic, so this is definitely my learning project.

Re: Trouble debugging Bump

Posted: Sat Jul 25, 2015 12:37 am
by s-ol

Code: Select all

local actualX, actualY = world:move(p, goalX, goalY)
p.x, p.y = actualX, actualY
needs to be adjusted in the opposite way you adjust it when creating the box; when you create the box in the beginning, it is offset by (-14, -22), relative to the drawing position.

Code: Select all

local actualX, actualY = world:move(p, goalX, goalY)
p.x, p.y = actualX - 14, actualY - 22
should solve it, but you could also try instead modifying the drawing code so the value stored is always the one used in bump and only switches the format when you draw.

Re: Trouble debugging Bump

Posted: Mon Jul 27, 2015 9:29 pm
by Snowbadger
That does make sense, but for some reason that causes the player to snap to the window's origin. Trying any other offsets with the goalX/Y or actualX/Y does the same thing, so I'm not sure what that's about. But it did get me thinking about a different approach to working with the offsets, so I was able to rewrite it to get it working. So thanks for that! :)