Sprite Collision Detection

Anyone had done a function to detect the collision of two different shaped and sized Sprites?

function CollisionDetect(x1,y1,w1,h1,x2,y2,w2,h2)

end

If you’re satisfied with overlap of the bounding rectangles, it’s a snap. If you need pixel level accuracy… It’s less snappy, but doable.

No problem With a small overlap

You could do this with less code, but my usual solution is to give each item bounds, like this

Frame = class()

function Frame:init(left, bottom, right, top)
    self.left = left
    self.right = right
    self.bottom = bottom
    self.top = top
end

Then, you want to test collisions use

function Frame:overlaps(f)
    if self.left > f.right or self.right < f.left or
    self.bottom > f.top or self.top < f.bottom then
        return false
    else
        return true
    end
end

That one if statement does all the work of checking for overlap.

Does that make sense?

I’d also suggest bringing the bounding box in a few pixels so it’s just within the bounds of your sprite, that way you give the player a little leeway in deciding if a collision occurs or not.

Also if you have a big complex shape you can create a hierarchy of bounding boxes, by defining each portion of the shape as a separate box and then having a “master” bounding box that is generated from the min / max extents of all the child boxes. You can then get fairly accurate / quick detection by checking first to see if the master box collides and if it does then check each of the child boxes in turn.

Thanks guys; I used the approach posted by Mark. and also I extended a little the bounding box 5 pixels on every direction

@edwin809 Don’t know if you need anything like this anymore, but here is a program I wrote showing the collision of 2 irregular shaped objects. Just touch the white dot and move it around to move the smaller object so it collides with the larger one.


-- polygon collision

displayMode(FULLSCREEN)
supportedOrientations(PORTRAIT)

function setup()
    -- fixed points for polygons
    verts1={vec2(250,600),vec2(260,700),vec2(280,750),vec2(460,800),vec2(400,660),vec2(360,620)}
    verts2={vec2(400,400),vec2(360,500),vec2(450,450),vec2(500,400)}     
    tx=0
    ty=0  
end

function draw()
    background(40, 40, 50)
    stroke(255)
    strokeWidth(4)
    
    j=#verts1    -- draw 1st polygon at a fixed location
    for z=1,#verts1 do
        line(verts1[z].x,verts1[z].y,verts1[j].x,verts1[j].y)
        j=z
    end
    
    j=#verts2    -- draw 2nd polygon moving with touch x,y
    for z=1,#verts2 do
        line(verts2[z].x+tx,verts2[z].y+ty,verts2[j].x+tx,verts2[j].y+ty)
        j=z
    end
    
    check2()    -- check if polygons are colliding
    
    fill(255)
    text(str,350,700)  
    ellipse(400+tx,150+ty,20)              
end

function check2()    -- calculate x,y points between verticies
    j=#verts2
    for z=1,#verts2 do
        m=(verts2[j].y-verts2[z].y)/(verts2[j].x-verts2[z].x)
        b=verts2[z].y-m*verts2[z].x
        dir=1
        if verts2[j].x>verts2[z].x then
            dir=-1
        end
        str=""
        for x=verts2[j].x,verts2[z].x,dir do
            y=m*x+b
            if check(tx+x,ty+y) then
                str="collision"
                return
            end
        end
        j=z
    end
end  
        
function check(px,py)    -- check if points px,py are within polygon
    j=#verts1
    c=-1
    for i=1,#verts1 do
        a1=false
        if verts1[i].y>py then
            a1=true
        end
        a2=false
        if verts1[j].y>py then
            a2=true
        end
        b1=verts1[j].x-verts1[i].x
        b2=py-verts1[i].y
        b3=(verts1[j].y-verts1[i].y)
        if a1~=a2 and px<(b1*b2/b3+verts1[i].x) then
            c = c *-1
        end
        j=i
    end 
    if c==1 then
        return true
    else
        return false
    end
end

function touched(t)    -- used just to move 2nd polygon around
    if t.state==BEGAN then 
        sx=t.x
        sy=t.y
    elseif t.state==MOVING then
        tx=t.x-sx
        ty=t.y-sy
    elseif t.state==ENDED then
        tx=0
        ty=0
    end
end