Ludum dare time!

Well, I’m in the ludum dare 🙂

I’ll be using flashpunk and the open source platformer game engine.

Advertisements

Point – Object Collision

After writing yesterday’s post, I noticed that I missed one big category of collisions: Point – Object collisions.  This is where a you check if a single XY pair is inside a object.  In this example I’ll use circles and squares, but you could use the algorithms that I wrote about in yesterday’s post with this method.

The technique is fairly simple.  For a square, all you have to do is check if the XY pair is inside a box.  The lua code looks like this:

function RectPoint(ax, ay, aw, ah, bx, by)
    return bx > ax and bx < ax + aw and by > ay and by < ay + ah 
end

All that this code does is checks if:

  1. the point’s X is greater then the rectangle’s X.
  2. The point’s X is less then the rectangle’s X + the rectangle’s width.
  3. the point’s Y is greater then the rectangle’s Y.
  4. the point’s Y is less then the rectangle’s Y + the rectangle’s height.

If these are all true, then it will return true, because the point is inside the rectangle.

The circle code is slightly more complex:

function CirclePoint(ax, ay, bx, by, ar)
    local dx = bx - ax
    local dy = by - ay
    local dist = math.sqrt(dx * dx + dy * dy)
    return dist < ar
end

This is essentially the same as the Distance Based Collision function that I wrote about in my previous post, except instead of taking 4 XY pairs and 2 radii, it takes 4 XY pairs and one radius, assuming that the other radius is zero.

For a example of these 2 functions in action, you can download the .love example file.  Feel free to use these functions in any way you wish.  If you want a license, use Creative Commons Zero.  If you have any questions, just comment, and I’ll try to help.

How Accurate?

Today I am going to write about something that I noticed when working on AI for a game:

Almost nothing needs to be accurate in games.  Take collision detection as a example.  Wikipedia says in regard to collision detection in video games:

Because games do not need to mimic actual physics, stability is not as much of an issue. Almost all games use a posteriori collision detection, and collisions are often resolved using very simple rules. For instance, if a character becomes embedded in a wall, he might be simply moved back to his last known good location. Some games will calculate the distance the character can move before getting embedded into a wall, and only allow him to move that far.

I find something similar:  Al least 90% of your collision detection will be (Or can be) AABB (A rectangle that cannot be rotated).  The exceptions are, of course, circles and complex shapes.
For circles, one can just check if the objects are more then the sum of their radii (Plural of radius) apart.  This is called distance based collision.

Complex shapes will usually fall in the 10% that I talked about that cannot have AABB collision detection.  But thinking about it, we can still use AABB for complex objects, to prune down the amount of checks we need to do.  All you need to do is only check collisions for the objects that are colliding with the complex object’s AABB.  The big question after that is how to find if the objects are colliding.  There are 2 methods:

  1. Use many different AABB’s and distance collisions for the same object.
  2. Splice the image of the object into a grid.  If more than, say 50% of one of the squares is non-transparent then it is solid (generally this step will be done only once, at the beginning of the program).  You then loop through all the grid squares, checking if the objects collide with them.

Both of these methods are good, but they will still use large amounts of memory when any object is inside it’s AABB.  At this point it becomes “how much more accurate can I make the collision detection without having the game be to slow?”

That brings me back to one of my first points:

There is no silver bullet.  Everything you do in programming games will be a trade off:  How much processing time will it take vs. how good does it look.

The best thing you can do for yourself is get a good collection of functions to use in all your games.  Two that seem to find their way into any game I write are a AABB function, and a distance based collision function, both written in löve2d, although they would be easy to port into any language.

Loading levels from images

Today I was working on a snippet that will allow you to load png files into löve2d, in a format accepted by YellowAfterLife’s Platformer engine (Although with minor edits, you could make it export to any format).  Without further ado, here is the code:

function imgtolvl(file, key)
    local lvl = {}
    local lvltxt = ''
    local img = love.image.newImageData(file)
    for y=1, img:getHeight(), 1 do
        for x=1, img:getWidth(), 1 do
            local r, g, b, a = img:getPixel(x-1, y-1)
            for c=1, #key, 1 do
                if key[c][1] == r..'.'..g..'.'..b then
                    lvltxt = lvltxt..key[c][2]
                end
            end
        end
    end
    table.insert(lvl, img:getWidth())
    table.insert(lvl, img:getHeight())
    table.insert(lvl, file)
    table.insert(lvl, lvltxt)
    return lvl
end

All you will need is a array (key) and a image (file)  The array should look like this:

key = {
     {'0.0.0', 'x'},
     {'0.255.0', 'g'},
     {'10.10.10', 'w'},
     {'100.100.100', 'p'},
     {'255.255.255', ' '},
 }

The numbers that you see are RGB pairs, so ‘255.255.255’ would be white.  the second string is the character that it will use in the final array.  In the engine, a space is air, so a white pixel would be air.

You will also need to update your level.next function.  Replace this:

d = level.levels[level.current]

with this:

d = imgtolvl(level.levels[level.current], level.key)

I hope that you find this snippet as useful as I do!