Anybody know any Lua? You might remember Red Alert, the little shmup I’m developing for the PICO-8 fantasy console? Well, I’m getting close to actually having it in a playable state but I’m currently stuck with this one bug I can’t quite fix. You see, I built in this boss enemy that uses a laser beam and something is off with the collision detection for it. I am checking whether this beam intersects with a hitbox on the ship and it works most of the time, but there are edge cases with false positives. Here’s an example where the algorithm thinks the beam intersects with my ship:

The numbers in the screenshot are the top left and bottom right X/Y coordinates of the ship and the origin and end points (X/Y) of the laser beam. I am trying to check if the line of the beam touches the lines of the 2x2 pixel hitbox on the ship sprite. Here’s the relevant collision detection check:

local hitbox={}
hitbox.x=ship_x+2
hitbox.y=ship_y+2
hitbox.colw=2
hitbox.colh=2
if phcol(myen.phorx,myen.phory,myen.phposx,myen.phposy,hitbox) and myen.pht>0 then
function phcol(phx1,phy1,phx2,phy2,obj)
 if linecol(phx1,phy1,phx2,phy2,obj.x,obj.y,obj.x,obj.x+obj.colw) then return true end
 if linecol(phx1,phy1,phx2,phy2,obj.x+obj.colw,obj.y,obj.x+obj.colw,obj.y+obj.colh) then return true end
 if linecol(phx1,phy1,phx2,phy2,obj.x,obj.y,obj.x+obj.colw,obj.y) then return true end
 if linecol(phx1,phy1,phx2,phy2,obj.x,obj.y+obj.colh,obj.x+obj.colw,obj.y+obj.colh) then return true end
 return false
end

function linecol(x1,y1,x2,y2,x3,y3,x4,y4)
 ua=((x4-x3)*(y1-y3)-(y4-y3)*(x1-x3))/((y4-y3)*(x2-x1)-(x4-x3)*(y2-y1))
 ub=((x2-x1)*(y1-y3)- (y2-y1)*(x1-x3))/((y4-y3)*(x2-x1)-(x4-x3)*(y2-y1))
 if ua>=0 and ua<=1 and ub>=0 and ub<=1 then return true end
 return false
end

It works in most cases, but just not in some edge cases like that screenshot. If you have any pointers for me about what is going wrong or how I can fix it, please don’t hesitate to contact me! If you want to see the full code of the game, you can find it here. The relevant code starts in line 281 of the game cartridge file.