Archived

This topic is now archived and is closed to further replies.

arwez

Tile based game objects/collisions still confused :(

Recommended Posts

Tornado    122
Let's say you want monsters in your game
Make a class called CMonster (For example) that will control the monster.
You can have all of your monsters in one big linked list (Better this way) or if you need a more constant size, use a normal array
Now you would make a function, Let's call it: ControlMonsters()
The function will go through your linked list/array and see which monsters needs to be processed (Or something like that).
The function will, basically, move them and make them think (Or seem like it ).
Now you make another function: CheckCollisionMonster(int x,int y)
This function will check for collision with any of the monsters.
You can use a "regular" bounding-box collision detection (Easiest to do, very useful for side-scrollers) or some other methods.
Goodluck with your game!

EDIT: Oops, forgot about collision with the tiles
You need to have an array that will hold collision information with your tiles.
So when you do CheckCollision(int x,int y), CheckCollision() will check, according to your global position in the map, what tile your currently on and if that tile have collision "turned on".
In my editor, I did it so you can have collision information for 4 sides: Up, Down, Left and Right.
Later, in the engine, I call CheckColl() that checks my position, then figures out if I'm on the edge of a tile (Like, left edge, right edge, etc) and returns true or false if the tile has collision in that direction.
Hope I made myself clear


- Goblineye Entertainment
The road to success is always under construction

Edited by - Tornado on October 7, 2000 4:25:53 AM

Share this post


Link to post
Share on other sites
Quantum    122
to expand on what tornado said , you might have a struct for a sprite that contains attributes, width, height, state, etc..

you would just run a loop and check for collision with each of your enemies in the linked list, and if you detect collision, do something or other... make the player die, play a sound, whatever.

as for tile collision, im still implementing this myself , but its basically the same as the monster collision, you just run a loop and check if one side of the player collides with a side of the tile, and if that tiles properties are collidable for that side, stop moving the player, else move the player in the direction he wants to go

heres my collision function:

    
int CSprite::Collision(CSprite *Sprite)
{
if(this->YPos + this->Height < Sprite->YPos)
return 0; //no collision

if(this->YPos > Sprite->YPos + Sprite->Height)
return 0; //no collision


if(this->XPos + this->Width < Sprite->XPos )
return 0; //no collision

if(this->XPos > Sprite->XPos + Sprite->Width )
return 0; //no collision


return 1; //collision! (:
}

Share this post


Link to post
Share on other sites
arwez    122
THX a lot! How do I find out which tile my player''s x is on? How do I scan the tiles ahead of the player to find out if the collision info is on or off??


THX again! Code would be nice too thx!

Share this post


Link to post
Share on other sites
Tornado    122
To check which tile your on, let's assume that the tile's size is 32x32, the map's size is 64x64 (In tiles, of course )
Also, The resolution is 800x600.
Now let's assume that x and y is the current map position.
x and y ranges from 0->799,0->599
Finally (), Let's assume that m_x and m_y is where we want to check for collision (They present "local" positions - according to the current screen, not the entire map)
And now for some code:

        

// Let's define the structure that holds collision information for a tile

struct TILE
{
bool Collision_Top;
bool Collision_Bottom;
bool Collision_Left;
bool Collision_Right;
};

TILE OurTiles[64][64];

// Fill in info in OurTiles...


int posx = m_x+x-800; // We find the global position

int posy = m_y+y-600;
int tile_x = posx / 32; // let's find the tile we're standing on

int tile_y = posy / 32;
int off_x = posx & 31; // The offset of the tile we're currently on - same as posx % 32

int off_y = posy & 31;

if (off_x == 0) // we're on the edge of a tile, now we want to find if it has collision in this direction (Must be right collision of the tile on the left or left collision of the tile on the right)
{
if ((OurTiles[tile_x-1][tile_y].Collision_Right) || (OurTiles[tile_x][tile_y].Collision_Left))
return(true); // we have collision

}

if (off_y == 0) // edge of a tile, up or down, up of the bottom tile or down of the topper tile
{
if ((OurTiles[tile_x][tile_y-1].Collision_Bottom) || (OurTiles[tile_x][tile_y].Collision_Top))
return(true); // collision!

}
return(false); // otherwise, no collision



Sorry for the long message

Edited by - Tornado on October 7, 2000 1:37:42 PM

Share this post


Link to post
Share on other sites
DekuTree64    1168
Well, you have to be keeping track of your player's position or you wouldn't know where to scroll the map to^^ For the tile collision, just do like
if(mapColData[player.x + 1)][player.y] == false)
{
//move player
}

That's using an array of bools called mapColData to keep track of which tiles you can't walk on (where true=can't walk on, false=can), and assuming you're trying move right (just use player.x-1 for left, player.y+1 for down, player.y-1 for up). Or you could make an obstruction class like
class obs
{
public:
bool top;
bool bottom;
bool left;
bool right;
};
if you wanna do like Tornado and have it where you can make it so it'll only block you if you run into it from a certain direction.



-Deku-chan

DK Art (my site, which has little programming-related stuff on it, but you should go anyway^_^)

"I'm dropping like flies!" - me, playing Super Smash Bros. (and losing)
"What fun!" - me, playing Super Smash Bros. (and beating the crap out of somebody)

Edited by - DekuTree64 on October 7, 2000 1:41:59 PM

Share this post


Link to post
Share on other sites
arwez    122
int posx = m_x+x-800; // We find the global position
int posy = m_y+y-600;

What does that mean? What is the m_x and the y? can u explain carefully what the mapx globalx etc means?

Share this post


Link to post
Share on other sites
Tornado    122
Sure
The global position is like the "master" position on the screen.
Let''s say the map size is (In pixels) - 5000x6000
A global position can be 0->4999 in the X axis or 0->5999 in the Y axis.
Now, when you move your character across the screen, you have the local position.
If the resolution is 800x600, a local position can be 0->799 (X) or 0->599 (Y).
So in this code:

int posx = m_x+x-800;
int posy = m_y+y-600;

m_x and m_y is the local position on the screen (0->799, 0->599) that is passed to the function.
x and y is the current position on the map.
I forgot about one thing though, x and y, in this case, ranges from 800->4999 and 600->5999.
I took it from some code I wrote a while ago
So, maybe this code makes more sense:

int posx = m_x + x;
int posy = m_y + y;

Now x and y ranges from 0->5000-800 and 0->6000-600
Sorry for the confusion
Hope it makes more sense now

Share this post


Link to post
Share on other sites
Tornado    122
Technically, Yeah.
But since your map size is not the size of the screen (The resolution) you must figure out where is your position on the map.
Global position, that is

Share this post


Link to post
Share on other sites
DekuTree64    1168
I haven''t gotten into the tile engine of my game yet (well, I defined all the classes, but that''s all) but you could just have each sprite with 2 arrays of coords (one for position in pixels from the top left of the map, one in tiles (which would just be the pixel position / tile size, but appearently you already knew that^^)).
So like, if you''re map was 40x40 tiles, you''d have a 40x40 array of bools to tell if each tile is an obstruction. Then just check obs[player.tileX + 1][player.tileY], and if it''s true, you can''t move there^^
If you want an example of how it''s done in code, you could download the source code to Verge (an RPG maker engine) at http://members.home.net/thespeedbump. Actually, I learned the basics of how games work reading through that code. It''s made for DOS (and programmed in C), so yours''ll probably look quite a bit different, but it should give you a good idea on how to get things done.



-Deku-chan

DK Art (my site, which has little programming-related stuff on it, but you should go anyway^_^)

"I'm dropping like flies!" - me, playing Super Smash Bros. (and losing)
"What fun!" - me, playing Super Smash Bros. (and beating the crap out of somebody)

Share this post


Link to post
Share on other sites
Tornado    122
Let me try again.
The map coords are in pixels.
If the map size is 2000x1000 (In *pixels*, that is, there are 2000 pixels across the X axis) and the resolution is 800x600, x and y (The two variables that tells us where to draw the map) can range from 0->1999-800 and 0->999-600.

Remeber that x and y tell us where we start drawing our map on the left and on the top of the screen.
So if x is 500 then all tiles that are between 500<->500+800 (In pixels), will be drawn.

When you want to check for collision with a character, you would pass to a function the local position of the character on the map at that moment.
The local position can range from 0->799 and 0->599.
But our map is not 800x600, not at all , and so, you have to consider your *current* position on the map at the moment (x and y).
So you just:

int newx = local_x + x;
int newy = local_y + y;

Think about it logically.
That way you get the position of the character across your 2000x1000 map.
And to figure out the tile your currently on, you do just simple math:

int tile_x = newx / (tile_width);
int tile_y = newy / (tile_height);

Hope it makes more sense than the last post

Edited by - Tornado on October 8, 2000 6:54:31 PM

Share this post


Link to post
Share on other sites
SikCiv    122
Been there, done that, but unfortunately I just jumped into the coding and made a mess. Its probably a good idea to make a solid sprite library, and even a gfx sub-system library, and then work around them. Ive done this, and I can assure u, the latter saves ALOT of time and results in alot less debugging

I can paste my header files displaying all my function prototypes if u like, so u can get an idea...

Share this post


Link to post
Share on other sites
arwez    122
Thank you soooo much. I understand now. ok so I know which tile my player is located on, now what about figuring out the offsets?
offx = newx % 31;

How exactly does that work? I understand that the % is the remainder. so if my character is in tilex 5. I would do 5/31 and the remainder would be 0 right? that doesn''t make sense.



THX again.

Share this post


Link to post
Share on other sites
Tornado    122
No, if your tile size is 32x32 then to figure out the offset you do:

offx = newx % 32;

Or, for a little more speed, you can do:

offx = newx & 31; // Notice the binary AND

newx is in pixels, *not* tiles.
With the offset we can know if your character is on the edge of a tile or not.
Let''s say that newx is 35 (In pixels) so you do:

offx = 35 % 32 = 3

Which means were not on the edge of a tile.
But if newx is 64 then

offx = 64 % 32 = 0

Yup, we''re on the edge of a tile.
You don''t do 64 / 32, you do 64 % 32.
Again, remember that newx is in *pixels*.
When we figure out we''re on the edge of a tile, we check the collision information from the tile, Like this:

Let''s say, again, that newx is 64

offx = 64 % 32 = 0

Now, we already have tile_x (We calculated it before), so know we need to check 2 things:

1) If the tile we''re currently on has collision enabled on it''s left
OR
2) If the previous tile (tile_x-1) has collision enabled on it''s right

If any of them passes the test, we have collision.

Share this post


Link to post
Share on other sites
arwez    122
Can you draw a picture or show me with #s where the 0 is on the tile? I don''t get why 32%32 = 0 ,64%32 = 0, 128%32 = 0 etc. Why would there be so many offsets of 0s?

Share this post


Link to post
Share on other sites
Tornado    122
When you calculate the offset with:

64 % 32

You only calculate the offset on the *current tile your on*.
Let''s say one of the tiles is at 32->63 (In pixels, of course),
Then:

32 % 32 = 0
33 % 32 = 1
34 % 32 = 2
35 % 32 = 3
...
60 % 32 = 28
61 % 32 = 29
62 % 32 = 30
63 % 32 = 31

You see?
It gives us the position on the current tile.
If the size of the tile is 32x32, Then offset_x will return our position on the tile from 0->31, so does offset_y (Because the width of the tile is the same as it''s height).
Sorry, I don''t have a picture to show it to you

Share this post


Link to post
Share on other sites
Quantum    122
i had this drawn up a couple of hours ago, when my net connection suddenly died

EDIT: stupid me, i got half way through and replaced 15 for the X offset with 16
oh well, you can just imagine they're the same

anyway...


i hope this clears it up a bit.. i didn't have time to fully explain everything, but i hope it helps

Edited by - Quantum on October 10, 2000 7:05:43 AM

Share this post


Link to post
Share on other sites
arwez    122
Thank so much you all I''m totally understanding it. You guys should make tile articles, the ones out there now are way too confusing!


THX AGAIN!

Share this post


Link to post
Share on other sites
Quantum    122
quote:
Original post by arwez
Thank so much you all I''m totally understanding it. You guys should make tile articles, the ones out there now are way too confusing!




hehe, i just like to help people

quote:
Original post by Tornado

Thanks arwez, your welcome!
So, What do you say Quantum?



- Goblineye Entertainment
The road to success is always under construction


well let me just say tornado, you should write articles!
a lot of the time when i''ve had a problem, you were the one to help me! and i''ve seen you help lots of people. it seems you know everything

i dont know about me though, im just a newbie

Share this post


Link to post
Share on other sites