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 trying to use map tiles that don't have collision for the full 8x8,
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 |
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]