Collision Maps

Hello, i need a help to figer out how to do a Collision detectition using collision maps,

i want to do something like

 if ( collisionMaps( collisionWorldMap, actor ) == COLOR_RED ) {
   //do whatever
}

i have this maps to test , but i can’t get it
http://img201.imageshack.us/i/mascara2.png/ , the collision map
http://img88.imageshack.us/i/mascara1b.png/ // the original

If you load your collision map as a BufferedImage (using the ImageIO class) you can then call ‘getRGB( x, y )’ on it to return the colour value at that given location. This is in the form of 4 bytes packed into an int in the format of alpha, red, green and blue. To get these out you can bit-shift and then bit-and the value with 0xff; but if your not used to using bit-shifting then you can simply wrap the int inside a new Color object (which can take a single int in it’s constructor). You can then use the Color object to get out the components.

I’d imagine getRGB is simply performing a direct array lookup after jumping through a couple of functions, which should be cheap. However incase it is slow you can also get out all pixels in a giant array using the other ‘getRGB’ method and then just throw away your image. That should be something like:


    BufferedImage img = ImageIO.read( new File("my_collisions.png") );
    int[] pixels img.getRGB( 0, 0, img.getWidth(), img.getHeight(), null, 0, img.getWidth() );
    
    // some code later...
    
    // find the pixel at the collision x,y
    int pixel = pixels[x + y*img.getWidth()];
    // get out the red
    int red = (pixel >> 16) & 0xff;
    if ( red > 200 ) {
        // handle collision
    } else {
        // no collision
    }

Note that the above is untested.

Once you have the components you can state if there is a collision if red is equal to 255, otherwise there isn’t. Two tips; make sure you don’t use jpegs (as they will alter the values stored) and don’t check for exact values. For example rather then checking if red is 255, check if red is greater then 250 or 200. This makes the maps a bit easier to work with. Your already using a PNG and this is very good because it’s a format that is excellent at compressing a large blocks of the same colour.

You can also just read the image in and then throw all the data into a big boolean array. I’ve done that and it works fine, it’s also just a bit faster.

Thanks guys , it works like a charm! :smiley:

What do you mean by throwing all the data into a big boolean array?

You don’t need to hold onto the BufferedImage or the raster data if you just scan through in the first place, find what pixel is considered solid, and set those to true in a corresponding boolean array. This is what I’ve done when I didn’t want to allow logic parts of the game to access the BufferedImage.

Oh I understand. But under what circumstances would you not want other parts of the game to have the actual pixel values?

The collisionmap should be in it’s own bitmap or something shouldn’t it? Load the pixels you need into a faster form (a nice boolean array for example), and free the CPU of the actual image. :smiley:

If you ever want to modify the collision map, having it as an Image is very useful - as it gives you access to the flexibility of the Java2D api with which to perform the modifications.

So IMO you should leave it as a BufferedImage.
Ofcourse from a design perspective you might want to limit precisely what operations the game code can perform on the collision map, but that can be achieved through simple encapsulation.

Yeah I’d say it’s really a matter of what you want to accomplish. I was basically passing the image data into OpenGL and then using the constructed bool arrays just for collision in my immutable level.