Log In  


I've been using Pico-8 for about 3 weeks and I'm loving it, but one thing I cannot figure out is hitbox collision. I can handle normal collision fine with checking flags again the map, but if I have a player that is only 6x7 instead of 8x8, then it "collides" with other objects a couple pixels early. I've spent many hours trying to create my own hitbox solution but have had no luck as of yet. I've tried looking at other people's code but it looks way too complicated for me right now, I've only been using Pico-8 for a few weeks. Is there a relatively simple way to implement custom hitboxes? Thanks :)



The map works well for maps, but an easy way to tell if two sprites are intersecting is to use bounding boxes. Basically defining a box around each sprite and then checking if those boxes intersect.

Hidden in case you want to try to solve it yourself.

If you are checking if sprite A intersects sprite B, you check if A's top is above B's bottom and if A's bottom is bellow B's top and A's left it to the left of B's right and if A's right is to the right of B's left. If all of those are true, then the two boxes are intersecting.

If you are trying to use map tiles that don't have collision for the full 8x8,

You can first check the flag, then you could use the above method in order to check the specific region of the tile.


That's what I've been trying, but it doesn't seem to work. This is my current collision code, hopefully there's some simple thing I'm doing wrong:

x1 - left most boundary of hitbox
x2 - right most boundary of hitbox
y1 - top most boundary of hitbox
y2 - bottom most boundary of hitbox

function hitbox_collide(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2)
  local c1 = ay1 >= by2
  local c2 = ay2 <= by1
  local c3 = ax1 <= bx2
  local c4 = ax2 >= bx1

  if c1 and c2 and c3 and c4 then
    return true
  else
    return false
  end
end

1

The trick is to reverse what your doing. Check to see if they don't intersect. If you reverse your greater than and less than signs, as well as the true and false results. Then change the and's to or's in the if statement it'll work.


Your inequalities for your y coordinates are backwards. You might have just forgot for a moment that y increases as you move down the screen. So y1 is actually the bottom numerically.

Here's my working debug code with your inequalities corrected at the top.

function hitbox_collide(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2)
  local c1 = ay1 <= by2
  local c2 = ay2 >= by1
  local c3 = ax1 <= bx2
  local c4 = ax2 >= bx1
		print(c1,64,1)
		print(c2,64,7)
		print(c3,64,13)
		print(c4,64,20)

  if c1 and c2 and c3 and c4 then
    return true
  else
    return false
  end
end

function _init()
	box1={20,20}
	box2={80,80}
end

function _update()
	if btn(2) then box1[2]-=1 end
	if btn(3) then box1[2]+=1 end
	if btn(0) then box1[1]-=1 end
	if btn(1) then box1[1]+=1 end
end

function _draw()
	cls()
	rect(box1[1],box1[2],box1[1]+8,box1[2]+8,10)
	rect(box2[1],box2[2],box2[1]+8,box2[2]+8,10)
	print(hitbox_collide(box1[1],box1[2],box1[1]+8,box1[2]+8,box2[1],box2[2],box2[1]+8,box2[2]+8,10),1,1,10)
end

Thanks for the demo, I tested it and it works, but I implemented the hitbox_collide function in to my game and it isn't working which makes me thing that it's not the function that's the problem. I'll change how I load my map and handle objects and see if I can get it to work :)



[Please log in to post a comment]