Collision issue 2d game need help plz

Started by
12 comments, last by Napster23 17 years, 11 months ago
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]
Kewl Softwarez -Time is what you make of it.
Advertisement
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.
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
k, sorry about that lol, not usto forum listing. okay heres more info:
#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
};

//Tile Loading Snippet
///How tiles are loaded to screen
tiles = load_bitmap("tiles.bmp",NULL);
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.

Kewl Softwarez -Time is what you make of it.
Collision done by:

tile = map[Playery * Cols + playerx]

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

I answered on my own WOOT!
Thanks all
Kewl Softwarez -Time is what you make of it.
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.
Evillive2

Kada2k6 and Evillive2:

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.

Thanks in advance.
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 = 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).

This topic is closed to new replies.

Advertisement