Search code examples
iphonecollisioncoronasdk

Corona SDK - How to detect collision on a non-physics body?


We're using objects that do not necessarily need to leverage the physics engine, but we still need to detect collision. Here's a similar example to what we're trying to build:

In solitaire, the cards are draggable objects. When they are released over top of another stack of cards (the collision), they will "stick" to that deck. The target hotspots (the card stacks) are not always known ahead of time - they are dynamic.

What would be the best approach to this problem in Corona SDK?


Solution

  • If you do not want to use physics engine, you could code up a touch event listener to check for overlapping cards. I assume no difference in a stack of cards or a single card.

    local cards={} --a list of display objects
    cards[1]=display.newRect(100,100,100,100)
    cards[2]=display.newRect(100,210,100,100)
    cards[3]=display.newRect(100,320,100,100)
    
    local tolerance=20 --20px radius
    local cardAtPointer=0  --the index of the card stuck to user hand
    
    local function onOverlap(self,event)
        if event.phase == "began" then
            cardAtPointer=self.index    --hold one card only    
        elseif event.phase == "moved" then
            if cardAtPointer > 0 and self.index == cardAtPointer then
                self.x,self.y = event.x,event.y     --drag card around
            end
        elseif event.phase == "ended" or event.phase == "cancelled" then
            local s=self
    
            for i=1,#cards do
                local t=cards[i]
                if s.index ~= t.index then  --dont compare to self
                    if math.pow(tolerance,2) >= math.pow(t.x-s.x,2)+math.pow(t.y-s.y,2) then
                        print(s.index.." overlap with "..t.index)
                        break   --compare only 2 overlapping cards, not 3,4,5...
                    end
                end
            end
            cardAtPointer=0     --not holding any cards
        end
    end
    
    for i=1,#cards do 
        cards[i].index=i
        cards[i].touch=onOverlap
        cards[i]:addEventListener("touch",cards[i])
    end