Domanda

I'm trying to create the base architecture for managing objects and collisions in a simple game in the Love2d framework. All of the objects are stored in a table (objects:activeObjects) and then a loop in the objects:calculateCollisions() function iterates through all of the objects. With each iteration, another nested loop checks to see if that object overlaps with any of the other objects in the same table. At the end of objects:calculateCollisions(), each object will ideally have a table containing references to all of the objects it overlaps with at the current point in time. However, the objects always have empty collision tables.

Right now there are two test objects: one which moves with your mouse, and one which always stays in the top-right corner. The two objects should, to the user, disappear simultaneously when they overlap, but, as mentioned before, the collidingObjects tables are always empty.

I have Three source files:
main.lua:
http://pastebin.com/xuGBSv2j
objects.lua (where most of the important stuff is written, and probably where the problem is):
http://pastebin.com/sahB6GF6
customObjects.lua (where the constructors for the two test objects are defined):

function objects:newCollidingObject(x, y)
    local result = self:newActiveObject(x, y, 50, 50)
    result.id = "collidingObject"
    function result:collide(other)
        if other.id == "collidingObject" then self.remove = true end
    end
    return result
end
function objects:newMovingObject(x, y)
    local result = self:newCollidingObject(x, y)
    function result:act()
        self.x = love.mouse.getX()
        self.y = love.mouse.getY()
    end
    return result
end

Sorry, I couldn't post more than two hyperlinks.

EDIT: After some more debugging, I've narrowed down the problem to the collidesWith(obj) function. It seems to always return false.
Here is the code:

function result:collidesWith(obj)
    if self.bottom < obj.top then return false end
    if self.top > obj.bottom then return false end
    if self.right < obj.left then return false end
    if self.left > obj.right then return false end
    return true
end
È stato utile?

Soluzione

Go through and trace the logic on paper with a few different test inputs. You'll quickly see that your logic is nonsensical. You're missing half of the tests, some of your comparisons are "pointing the wrong way", etc. So:

function result:collidesWith(obj)
    if self.bottom <= obj.top and self.bottom >= obj.bottom then return true end
    if self.top >= obj.bottom and self.top <= obj.top then return  true end
    if self.right >= obj.left and self.right <= obj.right then return false end
    if self.left <= obj.right and self.left >= obj.left then return false end
    return false
end

Should do the trick.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top