This is a simple example on how circle collision works.
All you need from this cartridge is the function:
function circ_col(c1, c2) local dx = c1.pos.x - c2.pos.x local dy = c1.pos.y - c2.pos.y local distance = sqrt(dx*dx + dy*dy) return distance <= (c1.r + c2.r) end |
If you want to check if two circles are colliding, you simply pass them as parameters c1 and c2 see an example bellow:
c1 = { pos={x=64,y=64}, r = 4 --size the radius would have to be for a 8x8 sprite } c2 = { pos={x=70,y=70}, r = 8 --size the radius would have to be for a 8x8 sprite } collides = false function _update() collides = circ_col(c1, c2) end function _draw() cls() if collides then print("colliding",4,4,11) end --draw the circles here - mind you in most projects you woudn't, usually you would have them invisible and have them --at the same position (or slightly offsetted) as your player --i would recommend drawing them anyway at the start to see that the are always where they are supposed to be circ(c1.pos.x,c2.pos.y,c1.r,11) circ(c2.pos.x,c2.pos.y,c2.r,8) end function circ_col(c1, c2) local dx = c1.pos.x - c2.pos.x local dy = c1.pos.y - c2.pos.y local distance = sqrt(dx*dx + dy*dy) return distance <= (c1.r + c2.r) end |
Simple clean code that works well for small circles.
A word of warning with semi-big cirles : the 16.16 format of pico8 numbers will easily overflow , even computing the diagonal of a 128x128 square will fail.
Thanks a lot for pointing that out o.O! Wasn't aware of that.
Because you already know the distance you want to check against (r1+r2) you can use this distance check by Mot which is efficient and safe from overflow: https://www.lexaloffle.com/bbs/?pid=130349#p
by passing in your dx,dy,(r1+r2)
@kozm0naut, interesting approach, both token and speed efficient.
My approach is different, instead of comparing d1 and d2,
I'm comparing (d1/256)^2 and (d2/256)^2
You also avoid the square root, and use every bit of the 16.16 format for precision while avoiding overflows.
function circ_col(c1, c2) local dx = (c1.pos.x - c2.pos.x)>>8 local dy = (c1.pos.y - c2.pos.y)>>8 local rsum= (c1.r + c2.r)>>8 return dx*dx+dy*dy <= rsum*rsum end |
[Please log in to post a comment]