Sign in to follow this  
Deamonslayer

Collision issue 2d game need help plz

Recommended Posts

Deamonslayer    112
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 this post


Link to post
Share on other sites
Ezbez    1164
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 this post


Link to post
Share on other sites
jdarling    232
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 this post


Link to post
Share on other sites
Deamonslayer    112
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.

Share this post


Link to post
Share on other sites
Kada2k6    108
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

Share this post


Link to post
evillive2    779
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 it
for ( int x = 0; x < width; x++ )
delete [] array[x];

delete [] array


// as opposed to a single array - array[x+y*width]
// create the array
int *array = new int[width*height];
// delete the array
delete [] 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 this post


Link to post
Share on other sites
jb_lav    122

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.

Share this post


Link to post
Share on other sites
Kada2k6    108
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!

Share this post


Link to post
PaulCesar    524
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 create

map[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 this post


Link to post
Share on other sites
evillive2    779
Quote:
Original post by PaulCesar
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 create

map[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.

Now, the OP asked:
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 this post


Link to post
Share on other sites
Kada2k6    108
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....

Share this post


Link to post
simon10k    220
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 this post


Link to post
Share on other sites
Kada2k6    108
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

Share this post


Link to post
evillive2    779
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.

[edit]
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 this post


Link to post
Share on other sites
jb_lav    122
@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 this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Here are two rather old demos of isometric engines, but perhaps they can help you with your problem

Link to Isogames

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this