Sign in to follow this  
kingpinzs

how to make tiles walkable or not

Recommended Posts

Probably you have your tilemap stored in a bidimensional array. Just make a second array of bytes and in each byte set an 1 or a 0. 1 meaning you can pass, 0 means you cant.

Also, you can use the values in the byte to give the terrain a difficulty or a type. So you may set the byte to 4 and that means water, 8 means void, 13 means a door, and so on.

Luck!
Guimo

Share this post


Link to post
Share on other sites
The basic idea would be via your tile map you should have some sort of tile IDs that make up your world.

Tilemap
1,1,1,1,1,1,1,
1,0,0,1,0,0,1,
1,0,0,1,0,0,1,
1,0,0,0,0,0,1,
1,1,1,1,1,1,1

Check the player current x,y position in the world and find out which tile ID on the map the character is on top of. Above 0 would be walkable and 1 is a wall. If the character moves in the direction off of a walkable tile towards a wall, dont allow the player to move that direction.

Share this post


Link to post
Share on other sites
so here is my map

char map[world_sizey][world_sizex] = {
{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2},
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2},
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2},

ans 2 is the walls.


this draws my tiles
void draw_tiles(void)
{
int tile;
int x;
int y;
RECT tile_src;

for(y=0; y<Screen_sizey; y++)
{for(x=0; x<Screen_sizex; x++)
{ tile = map[y][x];

scroll_x =(world_camerax/Tile_size);
scroll_y =(world_cameray/Tile_size);

offset_x = scroll_x & (Tile_size - 1);
offset_y = scroll_y & (Tile_size - 1);

tile_src.left =(tile - 1) *Tile_size;
tile_src.top = 0;
tile_src.right= tile * Tile_size;
tile_src.bottom=Tile_size;

dstr.left= (x*Tile_size) - offset_x;
dstr.top= (y*Tile_size) - offset_y ;
dstr.right = (x*Tile_size) - offset_x + tile_src.right ;
dstr.bottom = (y*Tile_size) - offset_y + tile_src.bottom ;

lpBackBuffer->Blt(&dstr,g_pddTile,&tile_src,DDBLT_WAIT,NULL);

} }}




this draws the player
Players[P].width = 64;
Players[P].hight = 64;
//the bug
r.left = Players[P].cl;
r.top = Players[P].ct;
r.right = Players[P].cr;
r.bottom = Players[P].cb;

dstr.left= Players[P].x;
dstr.top= Players[P].y;
dstr.right=Players[P].x + (r.right - r.left);
dstr.bottom = Players[P].y + (r.bottom - r.top);

lpBackBuffer->Blt(&dstr,g_pddbug,&r,DDBLT_WAIT|DDBLT_KEYSRC ,NULL);



so how do I find out what tile they are on or going onto?

Share this post


Link to post
Share on other sites
i did domething like this

struct Tile
{
int x;
int y;
int w;
int h;
};

std:vector<Tile> SolidTiles;

//Use a text file to say if the tile is walkable or not if it is //not add it to SolidTiles. . .

bool WalkAble(int x, int y)
{
for(int i(0); i < SolidTiles.size; i++)
{
if(x >= SolidTiles[i].x && x <= SolidTiles[i].x + SolidTiles[i].w && y >= SolidTiles[i].y && y <= SolidTiles[i].y + SolidTiles[i].h)
return false;
}
return true;
}

//Then if you want a player to move go like this. . .
cPlayer = new cPlayer();
if(WalkAble(Player->X + 3, Player->Y)) Player->X += 3;

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Lets say the player wants to move up in your world, check if he can move to the up-most square before you move him, simple as that really. Just remember to check before you move him. Capture the key press, check then move.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I was thinking about that not so long ago, so I'll just throw in my little and regrettably unexperienced advice...

I thought about doing a tile class that had an array
char canCome[4] = { u, l, d, r};
each representing a direction from which you can try to come into the tile.

So, quickly written, if the player press DOWN, you check if canCome[0] of the tile under the current position is 1, and you walk if it's true.

Now, my apprehension is that it uses a lot of memory to use a class like this... But I also thought about heritage, so it's easy to make a Poison Tile or an Action Tile with this concept. I guess you have to decide what's gonna be the most useful for you.

Did any of this make sense? Hope so! :D

Share this post


Link to post
Share on other sites
I prefer this way:

struct Tile
{
int x;
int y;
bool walkable;
... // more here
};


And set it based on its type during the initialization of your map. Then you can have a 2D array of tiles.

Tile game_map[16][16];
if ( game_map[x][y].walkable == false )
// tile not walkable

Share this post


Link to post
Share on other sites
Ok well I have been looking over everything and all the links given. And it is all over kill for what I want. All I want to do is detect if the next tile is a 2 or less. If it is a 3 I will not be able to move onto it. I figured it could read the map and find all the number 3's and make them unwakable but I can’t figure out how.

Can any one help with this?

Share this post


Link to post
Share on other sites
Take a look at this and I think it does what they were explaining above. The code is very general and shouldn't be used literally in a real game but the concept is what counts. Hope it helps.

[Edited by - evillive2 on December 3, 2004 8:06:48 PM]

Share this post


Link to post
Share on other sites
i dunno if this is where ur comin from, but if u use another array, ul burn major memory when it comes to making large, open maps. my suggestion (and what im currently implementing), is to have specific tiles having certain properties. let me explain.

i have an offscreen buffer with 256 tiles on it. each tile has an associating element in an array of elements, of type tile, like so:


class Tile
{
public:
bool UseScript;//not necessary, i could us a null script but this is faster
char scriptID;// the script to use if ur usin a script
bool walkable;// determines if this tile can be walked on
bool slowWalk // contemplate this after reading the article
};

Tile Tiles[256];



now, what we do is we keep track of two things, and know one:

A)track the players current position in pixels
b)track the tile hes standing on
c) the direction the player is heading in (mine is multiplayer, so it ties in with dead reackioning, and also the sprite engine)

d)know the characters sprite size (should be standardised for npcs & player too)

now, what we do is calculate the players position in pixels, this can be done simply by using the upper left hand corner of your screen as 0.0, then just increment this value when we move. then we can obtaintheir position by using an algorith such as this:

PlayerTilePosX = (PlayerPixelPosX - (PlayerPixelPosX%32)/32);

the brackets are used for clarification, and so is the divide (replace it with a bitshift).

now we know where the CENTER of the character is, this is important, because lets think about it:if we test our collision with the center, we will end up with our sprites halfway through walls. so what we do, is use a byte to calculate the direction the character is headed in. examine the pseudo code below:

#define NORTH 1
#define SOUTH 2
#define WEST 3
#define EAST 4


byte CharaterDirection;

calculate center X;
calculate center Y;

if up button pressed == true
{
CharaterDirection = NORTH;
}

then, when we move, adjust your front edge in that direction by adding half of your players sprite width. now, what we have is the leading edge of the character, and what direction hes heading in. now, when we move, we checkif this leading edge corresponds to the next tile in that direction (we should also check to see if by moving we will enter the next square, and adjust accordingly). if so, we check the next tiles walkable value, and if we cant walk on it, we dock our players movement to the edge of that tile, or else move.

This might sound cryptic (feel free to pm me if u need help), but its 4:56 am. im on my fifth cup of coffee, and im pretty buggered. it works, and with some snappy multithreading, u can make it work a charm. It also likns into various other elements of the game, and can be adapted to an object orientated approach. BTW, this is for free movement, not square based (i REALY hate that). i might make an article on this (with visula aids and less typos).

PS: my notation isnt normallly this sloppy, but u get the idea














Share this post


Link to post
Share on other sites
The major issue I have with a lot of tile tutorials and articles is that the term "tile" is not clearly defined. This is not because the authors of the articles/tuts do not define them for the current project, it is that it can and will be different for each type of game. The first thing that needs to be determined in a tile based game (IMHO) is what is each individual tile accountable for? Lets take a look at a classic game like Fina Fantasy 1. There is a utility you can use called ffhackster that hacks a ROM of the game and gives you access to the data that makes up the game for you to view and modify. Since it is illegal to possess a ROM of a game you don't own, and hacking it even then falls under some obscure laws, I will tell you of my criminal activity and findings to save you from incriminating yourself(I do own the original by the way, best game ever!). From what I can piece together, there is a set of images that represent each type of terrain etc. The actual tile itself is made up of movement flags and what, if any, monsters you can fight, what fighting background to use and some other stuff. The tiles are referenced by id's in the tilemap so that the same image can appear over and over but may have different attributes set to it. The closest thing I can complare this to is the structure of an 8 bit bitmap. You have your pallet of rgb values in a bitmap, and ff1 has a pallet of tiles. Each pixel in the bitmap is an index number referencing pixel data from the pallet, so the tile in the tilemap is an index number referencing tile data from a pallet of tiles. Now, the big difference here is that tile data may consist of a lot more than just image data.

For my own game, I take this another step. I have a generic tile structure that holds an image id and some other attributes like movement flags, etc. I make a few generic tiles in an editor that fills the structure up so that I have a nice pallet of generic tile data to work with.

I had stopped here before and made my tilemap from references to these tiles but realized that my tilemaps were only as unique as however many generic tiles I made. This was frustrating. In any event, the solution I came up with works for me and looks something like this. I created a tile class that holds a reference to a generic tile structure and has similar attributes to the structure. Why would I do this? Well, the tilemap is an array of tile objects in my case, and since each tile has it's own set of values, each tile value can change and go back to normal after x event or y time is up. This is mostly helpful in the map file department because I have an array of tile index values to instatiate the map, then I only have to have entries for how certain tiles might differ. This saves the problem of 3 dimensional maps and wasted/unused space.

Like I said, this works for me and I imagine your method will work for you, but it helps to put a little more time into planning what a tile needs to know and do to make your game development much smoother. BTW, the hardest part of game devlopment for me so far has been generating content such as art, decent maps/areas/levels. I suck at those things and they bore the hell out of me but the pitfall is that you can't test anything without it. oh well.

Share this post


Link to post
Share on other sites
Evillive2, i see where you are coming from, my method just works for speed, and if you have a multilayered maps, you can have a special transparent no walk tile, to allow for thsi kind of thing without having to "harden" specific tiles.

But i like ur method too, ijust suggest that by using some intelligent design in your maps these shortcomings can be worked around.

Share this post


Link to post
Share on other sites
Well, I have some pretty strange trasition tiles, so i can't just make tiles walkable or not. Like one might have half ot on the left side collidable and the tile next to it might have half of the right side collidable. Therefore I CAN walk through the middle. What I've done is make a collision map from the tiles. I make the tile and then I make the collision map. The collision map is simply a 2d array of 0's and 1's. 0 is walkable, 1 is not. Then I check my character position, find that position on my collision map, put a radius out from my character center and if my center is closer to an area with a 1 than the radius is long it doesn't allow the character to move to that position. This gives me a little bit more fine tuned control of collision detection.

Share this post


Link to post
Share on other sites
ok well im doing a tile based game now and this is how i did it:

i have a tile class that has a bool,surface,rect and another bool for multi-lvl's then i have a map class that draws each tile in rows and columns baised on numbers specifyed in a txt file and read in dynamicaly to cut back on memory. then the player class has a rect and to convert his position to tile position i divide the y value by tile high and the x value by tile width it works pretty well for me then i just check the tile that the player would be comming up to baised on his current movment and if the tile is walkable then the function returns true

hope helped[smile]

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