Collision control makes Robot want to kill

This horrible thursday was lost almost entirely to implementing collision detection/response. One would think it would not be so hard, since it's just in 2d, but I can't get it to tick. Could somebody point me to a good resource allowed by the rules on how to do this? I can detect a collision quite easily, but it is the moving-back-to-prevent-overlap part that breaks it... I guess we'll waste another day doing this.

However, I did have time to implement a nice (well, working) menu system, and Jakob made some nive HUMAN-KILL-GORE. You can see the menu as a screenshot (the thumbnail doesn't show it correctly, though).

(log in to comment)

Comments

I wrote some collision detection code a while ago for an older robot-programming game I made called Botgal. I'd give you more of a hand, but I've got my hands full with our current game right now (which incidentally, is nothing like my older Botgal game which would have been a perfect fit for this contest). All of the Botgal code is either MIT or public domain, so you are free to use it without giving credit.

--clint
er sorry -- I meant collision resolution code.
Completely agree with you j-1, collision response is almost completely overlooked and always underestimated. I based my code this time on http://www.ziggyware.com/readarticle.php?article_id=134, after trying several other suggestions on the gamedev forum that were less stable. The article still doesn't mention how to handle collisions with multiple objects simultaneously (in my case, multiple tiles in a tile map). My solution was to merge adjacent bounding boxes.

I thought I had it working quite well and stable on Sunday, but was still fixing glitches on Tuesday and Wednesday. Using a fixed time step really helped with stability a lot, besides also making glitches more consistent and so easier to debug.

Good luck!

Thank you very much, alex! That's exactly the kind of tutorial I've been looking for. And to HanClinto: Botgal looks really cool, it kind of reminds me of an old game I played when I was younger, where you programmed robots to do battle with each other.
The core of my collision detection & response code is inspired by Phil Hassey's PGU code. The core of it is basically checking against the corners of the sprite that's moving against the cells of the map to see whether any of the corner points has transitioned through the side of a cell, and to stop it doing so. Phil's code handled both cell and sprite moving, but that's left as an exercise for the reader I guess :) The code:
        # save off for later
        o_l, o_r, o_t, o_b = self.left, self.right, self.top, self.bottom

        # move left/right
        if keyboard[K_RIGHT] or keyboard[K_LEFT]:
            self.direction = keyboard[K_RIGHT] - keyboard[K_LEFT]
        dx = (keyboard[K_RIGHT] - keyboard[K_LEFT]) * 250 * dt

        # handle movement
        self.dy -= gravity * dt
        self.dy = min(300, max(-300, self.dy))
        self.y += self.dy
        self.x += dx

        # handle collision with world (inspired by PGU)
        for point in (self.bottomleft, self.bottomright, self.topleft,
                self.topright, self.midleft, self.midright, self.midbottom,
                self.midtop):
            cell = level.get(point)
            if cell is None or cell.tile is None: continue
            g = cell.tile.properties.get

            if (g('top') and o_b >= cell.top and self.bottom < cell.top):
                self.bottom = cell.top
                if self.dy < 0: self.dy = 0
            if (g('left') and o_r <= cell.left and self.right > cell.left):
                self.right = cell.left
            if (g('right') and o_l >= cell.right and self.left < cell.right):
                self.left = cell.right
            if (g('bottom') and o_t <= cell.bottom and self.top > cell.bottom):
                self.top = cell.bottom
This relies heavily on the sprite and tile map cells having full rect properties, including in the sprite's case the midpoints (the sprite is bigger than the tiles). The tile properties "top" etc are just booleans indicating whether that side of the tile is solid.
I guess I didn't make it clear - if the sprite is the same size or smaller than the tiles then you don't need to check midpoints :)
the one thing i reccomend is giving up on 'real' 2d movement and doing X first, then Y. there are a few cases where it gives slightly incorrect results, but its ultra simple, and always gives functional results. never a catastrophic failure, just a tiny difference in what you'd expect in some cases on the edge of things. its what we're doing in our tile-based platformer.