# Collision issue 2d game need help plz

This topic is 4277 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Need help in collision Detecting: -using map[MAPW*MAPH] array. how would you do collision detection? list any examples plz! thank you [Edited by - Deamonslayer on April 23, 2006 11:52:06 PM]

##### Share on other sites
You haven't exactly given a whole ton of information, but here's what I'd do.

Assuming that everything is one cell in size, then you could easily just test whether they are on the same cell. You know, if(play.x == wall.x && play.y == wall.y). Or else you could detect collision before you move there. Like so:

if(leftKeyPressed){ if(map[player.x-1][player.y]==wall) {  //Don't move } else {  //move }}

Without any more information, that's about all I can say. I don't even know what map[][] is storing! And, the above code is just pseudocode, so please don't copy and paste it.

##### Share on other sites
You need to give quite a bit more information then you already have for anyone to do you any good. Things to consider: What does your existing code look like, what type of structures are you really using (obviously an array, but what struc is in it), Are you looking for fine or rough collision, what in your struc aids/denys the required collision. Answer these and someone may be able to help you out.

- Jeremy

##### Share on other sites
#define MODE GFX_AUTODETECT_WINDOWED
#define WIDTH 640
#define HEIGHT 480
#define MAXSPEED 5
#define TILEW 32
#define TILEH 32

#define COLS 20
#define MAP_ACROSS 31
#define MAP_DOWN 33
#define MAPW MAP_ACROSS * TILEW
#define MAPH MAP_DOWN * TILEH
#define SCROLLW 480
#define SCROLLH 390

typedef struct SPRITE
{
int dir, alive;
int x,y;
int width, height;
int xspeed, yspeed;
int xdelay,ydelay;
int xcount,ycount;
int curframe, maxframe, animdir;
int framecount, framedelay;
}SPRITE;

SPRITE myhero;
SPRITE *hero;

BITMAP *hero_bmp[5][4];

//game map
extern int map[];

//double buffer
BITMAP *buffer;

//bitmap containing tiles
BITMAP *tiles;

//Virtual background buffer
BITMAP *scroll;

//vars
int gameover;
int score;
int scrollx,scrolly;
int startx,starty;
int tilex, tiley,n;

int map[MAPW*MAPH] = {

23, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 1, 1, 1, 1, 1, 1, 23, 21, 21, 21, 21, 21, 21, 21, 22, 1, 1, 1, 1 ,1,
22, 89, 89, 89, 89, 89, 89, 89, 89, 89, 22, 1, 1, 1, 1, 1, 1, 22, 95, 95, 95, 95, 95, 95, 95, 22, 1, 1, 1, 1, 1,
//ETC
};

///How tiles are loaded to screen
for(tiley=0;tiley < scroll->h; tiley+=TILEH)
{
for(tilex=0;tilex < scroll->w; tilex+=TILEW)
{
blit(grabframe(tiles, TILEW, TILEH, 0, 0, COLS, map[n++]), scroll, 0, 0, tilex, tiley, TILEW, TILEH);
}
}

//Movement Snippet
void forward()
{
hero->curframe++;
hero->dir=0;
if(scrolly >= scroll->h - SCROLLH && hero->y > 285)
{
hero->y-=5;
}
else if(scrolly <= 0)
{
hero->y-=5;
}
else
{
scrolly -=5;
}

I am using the Allegro lib.

Okay so a rough overview is its a scrolling game, with an animating hero.
my first general idea was to figure out what tile am i even stepping on.
by: tile=map[((scrollx+hero->x)/TILEW)*((scrolly+hero->y)/TILEH)];
but this doesnt even work. i spit this info by texout and end up not telling me the rite tile i am on.

I hope this helps! tell me what else u need to know to help if i missed something.

##### Share on other sites
Collision done by:

tile = map[Playery * Cols + playerx]

collision
if(tile == wall)
player != move;

I answered on my own WOOT!
Thanks all

##### Share on other sites
Hidden
This hasn't anything to do with collision, but is a little small suggestion for improving your map-structure!

Instead of Map[w * h], you should consider using something like:

struct {   int ground;   int fringe;   int wall;} Map[MAX_HEIGHT][MAX_WIDTH];

This will give you a multilayer map so you can draw ground (like grass, water), fringe above the ground (rocks, a road, flowers), and walls, which will be blocking your character's movement.

Player.xpos = 4;
Player.ypos = 7;

You want to walk south, which will be Player.ypos + 1... 8 in this case.

if (Map[Player.ypos + 1][Player.xpos].wall < 0) {   //we walk!}else {   DisplayToYourScreen("ouff!!");}

Here's a really good tutorial for programming tile-based games using Flash, but the code can be read as pseudo-code as well. This is how I learned it and it's excellent. :-) http://www.tonypa.pri.ee/tbw/index.html

Quote:
 Instead of Map[w * h], you should consider using something like:struct { int ground; int fringe; int wall;} Map[MAX_HEIGHT][MAX_WIDTH];This will give you a multilayer map so you can draw ground (like grass, water), fringe above the ground (rocks, a road, flowers), and walls, which will be blocking your character's movement.

Off topic but I thought it useful...

Actually, a few years ago I was wondering how to do all of this stuff myself. After hours of searching on-line I came accross articles explaining that C does not have support for "true" multidimensional arrays. This made me nuts. Anyway, the single dimensional array approach (IMHO) is much easier to implement when it comes to dynamic arrays.... but moving on...

The way the OP is doing it is actually how this is done internally for a multi dimensional array and in the future when dynamic multi-dimensional arrays may be needed, it is much simpler to create single dimensional arrays the same size as w*h or even w*h*layers and do the math internally as opposed to creating arrays of arrays.

// create a multi dimensional array like array[x][y]int **array = new int*[width];for ( int x = 0; x < width; x++ )    array[x] = new int[height];// then to delete itfor ( int x = 0; x < width; x++ )    delete [] array[x];delete [] array// as opposed to a single array - array[x+y*width]// create the arrayint *array = new int[width*height];// delete the arraydelete [] array;

Now, the code for the array[x][y] gets more confusing as you add more dimensions but the single dimensional array is generally the same with the exception of a little more math to find which part of the array you want. That being said, it is undeniably easier if you have a static sized map and can use array[x][y]. The main drawback being lack of flexibility.

*** at the OP ***
Congrats on figuring out your own problem.

##### Share on other sites

What are the trade-offs in speed of your differing approaches given a randomly generated 'map' of multiple layers with a pre-defined size of 200x200?

I was thinking about using vectors to accomplish this, but was concerned about speed issues mainly.

And ease of implementation, of course. :) Yes, I'm a noob. But you learn by doing (I'm just trying to shave off some of the "wasted" doing by asking this.)

Using VS C++ Express -- no .NET usage.

##### Share on other sites
Hidden
Quote:
 What are the trade-offs in speed of your differing approaches given a randomly generated 'map' of multiple layers with a pre-defined size of 200x200?

I have no idea. I'm a novice programmer, I don't even understand this sentence. :)

I should mention that I haven't done any isometric stuff, just "top-down" tile-based games. The reason I think having a multi-dimensional array is easier is because you can find a tile on your map much quicker. Let's say you want to do something with the 3rd tile from the left, 2 rows down...

... DoSomethingWith(&Map[2][3]);
(or actually it should be 1, 2 since the first tile is 0)

It's super-easy!

Quote:
Original post by evillive2
Quote:
 Instead of Map[w * h], you should consider using something like:struct { int ground; int fringe; int wall;} Map[MAX_HEIGHT][MAX_WIDTH];This will give you a multilayer map so you can draw ground (like grass, water), fringe above the ground (rocks, a road, flowers), and walls, which will be blocking your character's movement.

Off topic but I thought it useful...

Actually, a few years ago I was wondering how to do all of this stuff myself. After hours of searching on-line I came accross articles explaining that C does not have support for "true" multidimensional arrays. This made me nuts. Anyway, the single dimensional array approach (IMHO) is much easier to implement when it comes to dynamic arrays.... but moving on...

The way the OP is doing it is actually how this is done internally for a multi dimensional array and in the future when dynamic multi-dimensional arrays may be needed, it is much simpler to create single dimensional arrays the same size as w*h or even w*h*layers and do the math internally as opposed to creating arrays of arrays.

*** Source Snippet Removed ***

Now, the code for the array[x][y] gets more confusing as you add more dimensions but the single dimensional array is generally the same with the exception of a little more math to find which part of the array you want. That being said, it is undeniably easier if you have a static sized map and can use array[x][y]. The main drawback being lack of flexibility.

*** at the OP ***
Congrats on figuring out your own problem.

Wow, not unless im missing something there you have said 2 things completely wrong (actualy , said one implied the other). First off, understand that new and delete as C++ operators, and are not part of the C language. That would be free() malloc() and relloc() you would use for memory management in C. And multidimensional arrays are supported quite easily

int dog[14][32]; is valid as far as i would know, i know it works in C++, and almost positive it is part of the C spec aswell

as far as dynamic multidimensional arrays , you can do that too, keep in mind there is a malloc / free code you can use aswell for a similar scenario, but im going to use C++'s new and delete for this example

int **map;int *map = new int[25];for(int i=0; i<25; i++){    map[i] = new int[25];}this will then createmap[25][25]

using reloc in C you will be able to actualy modify the size of the arrays aswell, but remember that what you new you must delete (and cannot relloc), and what you malloc you must free (you can relloc that).

##### Share on other sites
Quote:
 Original post by PaulCesarWow, not unless im missing something there you have said 2 things completely wrong (actualy , said one implied the other). First off, understand that new and delete as C++ operators, and are not part of the C language. That would be free() malloc() and relloc() you would use for memory management in C. And multidimensional arrays are supported quite easilyint dog[14][32]; is valid as far as i would know, i know it works in C++, and almost positive it is part of the C spec aswellas far as dynamic multidimensional arrays , you can do that too, keep in mind there is a malloc / free code you can use aswell for a similar scenario, but im going to use C++'s new and delete for this exampleint **map;int *map = new int[25];for(int i=0; i<25; i++){ map[i] = new int[25];}this will then createmap[25][25]using reloc in C you will be able to actualy modify the size of the arrays aswell, but remember that what you new you must delete (and cannot relloc), and what you malloc you must free (you can relloc that).

If you look back, I wrote that C does not support "true" multidimensional arrays and I don't think I said anything about any of the above code not being valid. If you research it a little you will find that C/C++ does not in fact support "true" and I emphasize the word "TRUE" multidimensional arrays. On the other hand, I probably was not all that articulate in my last post so I will re-state what I said previously in a different way so as to press the main point of it.

Using a static array MyArray[640][480] is much easier than using a dynamic multidimensional array. However, when using dynamic arrays (multidimensional especially) it becomes increasingly easier to use a single dimensional array for the programmer and use math to figure out the subscript they want instead of allocating (using malloc, calloc, realloc, new etc.) arrays of arrays.

The reasoning behind this is simple. The code is much shorter and this being my own opinion, much more readable.

Quote:
 What are the trade-offs in speed of your differing approaches given a randomly generated 'map' of multiple layers with a pre-defined size of 200x200?I was thinking about using vectors to accomplish this, but was concerned about speed issues mainly.

The speed issue is basicly a non-issue based on using std::vector or not. The big issue here will be wasted memory over ease of use so overall I would recommend using std::vector here over doing it yourself but there are 2 sides to every story.

Take for example a static array:
MyArray[20][15][3] for 20 tiles wide x 15 tiles high with 3 layers. While how you implement the array will make a difference to how you manipulate it etc., the fact remains you are using enough space for 20*15*3 tiles. This example may not seem like much but consider this next option. Try doubling the width and height of the map to 40 x 30 and the size increases by 4X, triple it and it is 9x.

Using a layered map in this way will make it easier for you to render layers in a simple loop but much of the space after the first layer tends to be empty space depending on the type of map you are doing and will end up not being used but still allocated.

As an alternative, you could have a vector or list of layer tiles on each tile that could optionally be empty saving you quite a bit of memory but at the cost of (again design specific) having to check each tile multiple times for different rendering passes for extra layers.

What it comes down to is that there are many different ways to accomplish the same goal and this is especially true with game programming. What works great for some may not be what you need. Many times trial and error prove to be the best way to figure out what is best for yourself.

I hope that helps.

##### Share on other sites
Hidden
What is a "true" multi-dimensional array?

int Map[height][width];

^ this works, with no problems whatsoever. I haven't used malloc, calloc, or realloc a single time anywhere in my code... and it is now 150 kb in size.

I don't understand what the fuzz is about....

If you step into the new operator (at least with my IDE) you find that the new operator uses malloc to allocate memory. I think malloc is shunned because it involves casting, which violates the C++ type system.

If you know the size of your map, you might as well use static multi-dimesion arrays.

int map[32][32];

I think what evillive2 means about not supporting true multi-dimesion arrays is that a multi-dimesional array in C/C++ is an array of arrays.

##### Share on other sites
Hidden
Quote:
 I think what evillive2 means about not supporting true multi-dimesion arrays is that a multi-dimesional array in C/C++ is an array of arrays.

What else would it be? And does it matter, is it a problem? :D

Quote:
 What else would it be? And does it matter, is it a problem? :D

Nope. No problem at all. [smile] I was only pointing out that writing a static array as array[x][y] is handled internally the same way as array[x*y] and that when the OP eventually wants to move to a dynamic array (static arrays just don't cut it after a while) sticking to the format of array[x*y] poses much less of a problem and will require less re-writing than the suggestion of using array[x][y].

And just to clarify, I never said there was anything wrong with using a static array in that fashion. I was merely passing some information along that I found very useful to myself as I progressed past games with static arrays and needed dynamic multi-dimensional arrays. Not only is the syntax for creating them greatly simplified by keeping it 1 dimensional and doing the math yourself but passing arrays to functions becomes much easier as well. Actually, the syntax for passing multi-dimensional arrays to functions becomes quite a pain as you will quickly find out.

Quote:
 What are the trade-offs in speed of your differing approaches given a randomly generated 'map' of multiple layers with a pre-defined size of 200x200?I was thinking about using vectors to accomplish this, but was concerned about speed issues mainly.And ease of implementation, of course. :) Yes, I'm a noob. But you learn by doing (I'm just trying to shave off some of the "wasted" doing by asking this.)

Actually, the above statement about the complexities of passing arrays to functions is another reason to use std::vector over your own.

##### Share on other sites
@Evillive2

I think that I'll use your suggestion and stick with a vector of one dimension. I had thought about using a 3 dim. array and using subscripting, but with a little extra math work -- I can see your point.

Thanks all.

[Edited by - jb_lav on May 1, 2006 7:37:26 PM]

##### Share on other sites
Here are two rather old demos of isometric engines, but perhaps they can help you with your problem