gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > collisiondetecting

#509 - whodoo - Wed Jan 08, 2003 8:42 am

When I used to develop PC-games I used a "hidden screen" for collision detection. I drawed e.g. the level only black and white off screen and checked for pixelcollisions... is there anyway of doing this when making games to GBA? I wanna draw the entire screen "offscreen" with different colors and check single pixels..I cant find a better way of detecting collisions in a game..

#510 - whodoo - Wed Jan 08, 2003 8:43 am

should I just have en array like
short unsigned int offscreen[160*240], and every frame Im "filling" this with information or can I use the hardware-blitter for sprites e.g?

#519 - ampz - Wed Jan 08, 2003 10:26 am

Yes, you can do the same for GBA, but forget about using an int for every pixel... You have to use a byte array or even better, a bit-array. (otherwise it wount fit into memory)
If your colisionmap is constant, then you can put it in ROM.

#523 - whodoo - Wed Jan 08, 2003 10:51 am

how do I create a byte.array?

#532 - Splam - Wed Jan 08, 2003 2:51 pm

unsigned char offscreen[240*160] but as ampz says a bit array would be better (smaller at least) but either way is going to be wasting a lot of processor time.

It also depends on how accurate your collisions need to be, are you doing a platform game or something needing collisions against the background? if so then your tile map could include collision data for the background, if you're talking about collisions against sprites/bullets etc then a bounding box method would be better (maybe with a coarse map if you've got lots of sprites on screen).

#546 - Burre - Wed Jan 08, 2003 5:24 pm

whodoo wrote:
should I just have en array like
short unsigned int offscreen[160*240], and every frame Im "filling" this with information or can I use the hardware-blitter for sprites e.g?


I don't know if you understood why ints are true waste of space but this one way of looking at it. You're only interrested in checking two types of states right? Collision or not. When producing an array of ints every dataholder (pixel) in the array provide an precision of an int (about 65535 vatiations or 16 bits per pixel). What you instead would want to do is reducing the range of values to 2, 1 and 0 for every pixel. Making 1 represent collision and 0 not, or the other way around. Each dataholder will then use 1/16 memory of an int.
_________________
"The best optimizer is between your ears..."

#561 - coelurus - Wed Jan 08, 2003 8:43 pm

Collision-detection techniques depends on the style of game. There are loads of ways to handle it nicely, but in any case, I feel a mask-bitmap (collision-bitmap, whatever) is a little resource-consuming. You need to clear it, draw something to it and at last, it takes quite some mem. I'd prefer checking BBs, as the last poster suggested. This saves both space, probably CPU processing and you don't have to clear it every frame.

#565 - grumpycat - Wed Jan 08, 2003 9:02 pm

For my game I did the following:

For non-player entities (i.e. to see if the player's bullets hit an enemy), I use bounding boxes as they are cheap.

For the player itself, I used a bitmap check - but I don't draw the entire screen in the bitmap, instead I just keep something like a 32x32 bitmap and plot only the background and objects around the player - it saves a lot of time and uses less memory.

Bounding boxes are less accurate (especially for non-rectagular objects), but if you bias them in favor of the player, they work well enough. Generally players don't mind getting extra points even though they strictly just missed the target, but they hate NOT getting points when they just hit.

On the other hand, bounding boxes are aweful for deciding whether or not the player has been hit, and dying when you shouldn't have can really ruin a game.

If bitmap checks are still too expensive, and your player character and collision environment is not too intricate to rule out bounding boxes, you can still do a good job by using multiple bounding boxes (e.g. body, head, legs) for a single player object.

Grumpy.

#1349 - gz - Thu Jan 16, 2003 10:51 pm

i wanted to ask sth, but since it fit's here...

What I'm trying to do is exactly that except for I would like my map to be deformable in a worms style. But I have no idea how to do it!

I have a background from gfx2gba and I copy a piece of it to the videobuffer. Since it's const i can't touch it. (btw can u point me to a reference that explains why gba messes up with MY arrays only becouse they are not const?).
_________________
gz
"try not. do or do not. there is no try"

#1350 - Splam - Thu Jan 16, 2003 11:28 pm

Firstly, if your arrays aren't defined as const the compiler will presume you want to alter them at some point, in that case it will define them as being in ram, this shouldn't in itself be a problem UNLESS a) there isn't enough ram free to hold the array b) your crt0 doesn't copy initialised data to ram, some of them don't do this so you end up with the space allocated in ram but nothing gets put there. Probably easy (if you do want to alter them) to make them const then malloc some ram to store them in and copy them there yourself when you initialise. Doing it that way means when you're not using them they don't take up the space in ram.

Deformable map ala worms. I'd probably do it by using the tileset as follows. Draw your level in whatever editor, conver it to the format you want but make sure you remove any SOLID colour tiles except for 1 (eg, 8x8 all the same colour). Then you'll have your "world" to work with.
If you want more detail than a solid colour background you can do that too, just using a single colour world as an example.

You can now use these tiles for collision detection (ie the ones on top of the level which aren't solid) by checking which bytes are set. Then when you want to remove a bit of the level find out which tiles are going to change when you blow up part of the level (or whatever you're doing to it). You then need to replace any of the SOLID tiles with newly deformed ones as well as replacing the top (non solid) ones.

Hope that made sense? ;) I'ts something like this.

0=solid tile 1-6 have definition of the landscape in.

1234 56
0000000

BANG! we've blown some up right in the gap between 4 and 5, now the world would look something like this

1234 56
0000700

We've now altered the 4 and 5 tiles and removed some of the pixels from them but also had to create a new 7 tile which is no longer solid but has pixels missing too.


Using this method you get what you're after and collision detection for free.

btw, as I didn't explain the "collision for free" stuff what I mean is to check for collisions you read pixels from the tile data via the map. eg something like this
so you divide your x and y screen position by 8 to get them to tile offsets, read the tile number from the map at that position foo=map[(y*width)+x]. foo now = the tile number, then u use the bottom 3 bits of x and y as a pixel offset into that tiles definition. You can either keep the altered tiles in ram for byte access or just read the data from vram remembering you can only do 16bit reads, just means a bit more >> on the x pos and a &1 on the xpos to see which half of the word you wanted to check.

#1359 - ampz - Fri Jan 17, 2003 12:08 am

Burre wrote:
whodoo wrote:
should I just have en array like
short unsigned int offscreen[160*240], and every frame Im "filling" this with information or can I use the hardware-blitter for sprites e.g?


I don't know if you understood why ints are true waste of space but this one way of looking at it. You're only interrested in checking two types of states right? Collision or not. When producing an array of ints every dataholder (pixel) in the array provide an precision of an int (about 65535 vatiations or 16 bits per pixel). What you instead would want to do is reducing the range of values to 2, 1 and 0 for every pixel. Making 1 represent collision and 0 not, or the other way around. Each dataholder will then use 1/16 memory of an int.


Well, last time I checked, ARM7 was a 32bit CPU, that means 32bit ints, not 16bit. :)

#1362 - gz - Fri Jan 17, 2003 12:21 am

mem:
I tried to initialise sth smaller and it works. (A small array is copied fine to the display, but a 512x256 mode 4 bg isn't...)
How much mem is there to use? The tutorials that hang around the net usually don't mention it.

map:
If I understand correctly u suggest to have some tiles for the bg then others on top for collision? (The top ones of course can be smaller, meaning bitwise?)
In that case if the whole map is partially messed up then every tile is altered, and every collision tile is altered so we use twice as much space ten we would like to.. Ok not twice, but we store the deformation both in the collision tiles and in the world tiles... Then on the other hand i probably didn't understand you ;)

I think I would feel more comfy in the bitmap mode after all... (of course using tiles saves memory but if i expect to have them all modyfied at some point i might as well skip using them at all)

I like your idea with the collision tiles on top of world though (If I understand correctly). Since we can't have the whole bg in memory maybe a repeating pattern (just one tile, like in worms: dirt or rocks or whatever). And then a bitmap of the whole map in memory (just 0's and 1's). Please tell me it will fit...
_________________
gz
"try not. do or do not. there is no try"

#1363 - ampz - Fri Jan 17, 2003 12:33 am

You seem to have misunderstood. You can either use a separate array (preferably a bit-array), or you can look at the color on each pixel in the tiles on screen. Let's say that you have a BG where color 0 (transparent) means nothing to colide with, and any other color means colision. Then all you have to do is to look at the map and the colors in the tiles used in the map.

Splam also explained a way to do a worms-style graphics engine.

Yes, if you intend to modify every tile on screen, then a bitmap mode is often the prefered way to go... However, the text modes does offers some nice features that you may find useful, such as scrolling of the map in hardware, multiple BG's, very handy for menu's and stuff, and of course, the rotation/scaling backgrounds can be used to do lots of cool stuff.

#1401 - gz - Sat Jan 18, 2003 12:28 pm

Big thanks to all of you ;)

I finaly got what Splam said ;) It's just that i didn't get the ilustration. It seems very clever. Now i guess it's smart to leave alone mode 4 and try something with tiles.
_________________
gz
"try not. do or do not. there is no try"

#1429 - Burre - Sat Jan 18, 2003 5:45 pm

ampz wrote:
Burre wrote:
whodoo wrote:
should I just have en array like
short unsigned int offscreen[160*240], and every frame Im "filling" this with information or can I use the hardware-blitter for sprites e.g?


I don't know if you understood why ints are true waste of space but this one way of looking at it. You're only interrested in checking two types of states right? Collision or not. When producing an array of ints every dataholder (pixel) in the array provide an precision of an int (about 65535 vatiations or 16 bits per pixel). What you instead would want to do is reducing the range of values to 2, 1 and 0 for every pixel. Making 1 represent collision and 0 not, or the other way around. Each dataholder will then use 1/16 memory of an int.


Well, last time I checked, ARM7 was a 32bit CPU, that means 32bit ints, not 16bit. :)


True, my bad. Well even more reason then to stay away from ints.
_________________
"The best optimizer is between your ears..."