Archived

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

Nazrix

Syntax Question for Tile-Based Engine

Recommended Posts

I have a question about a tile-based game I'm working on. Actually it's the tile engine in Tricks of The Windows Game Programming Gurus. It's really a syntax question more than anything else. He initializes the world with this code.
    
char *world[21]=
{
"111111111111111111111111111111",
"100000000000000000000000000001",
"100002222220000000000000077701",
"100002222223333333333000077701",
"100002222227777777773000070001",
"100002222227777777773000070001",
"100000000377777777773000070001",
"107777700377777777773000070001",
"177777770377777777773000770001",
"107777700377777777773007700001",
"100777770377777777773777000001",
"100000707377777777773000000001",
"100007777377777777773000000001",
"100000000302222777773000000001",
"100000000332222777773000000001",
"100000000002222333333000000001",
"100000666666666666666666600001",
"100000800000000000000000800001",
"100000800000000000000000800001",
"100000000000000000000000000001",
"111111111111111111111111111111",
};
    
I was wondering how I would change the world later on in the code...like if you walk off of this map and I want to load the next set of tiles. I can't get the syntax right. I'm a little rusty on pointers. So, I just want to do something like world[21]={212121212...}; to load the new set of tiles. Just not sure about syntax... Thanks in advance...
Edited by - Nazrix on 4/18/00 1:03:07 PM Edited by - Nazrix on 6/6/00 12:19:15 PM

Share this post


Link to post
Share on other sites
It's better to load the tilemap from a file, but if you insist...


//Init the tilemap (this only works if world is a globabl var)

char *world[21]=
{
"111111111111111111111111111111",
"100000000000000000000000000001",
"100002222220000000000000077701",
"100002222223333333333000077701",
"100002222227777777773000070001",
"100002222227777777773000070001",
"100000000377777777773000070001",
"107777700377777777773000070001",
"177777770377777777773000770001",
"107777700377777777773007700001",
"100777770377777777773777000001",
"100000707377777777773000000001",
"100007777377777777773000000001",
"100000000302222777773000000001",
"100000000332222777773000000001",
"100000000002222333333000000001",
"100000666666666666666666600001",
"100000800000000000000000800001",
"100000800000000000000000800001",
"100000000000000000000000000001",
"111111111111111111111111111111",
};

//If you want to change the tilemap later on, just call the function change_tile_map() to change it.

void change_tile_map(void)
{
world[0] = "111161511111111811111711111111";
world[1] = "2221615111111642311111711111111";
world[2] = "100000800000000000000000800001";

// and so on...
}



/. Muzzafarath

Edited by - Muzzafarath on 4/5/00 1:43:46 PM

Share this post


Link to post
Share on other sites
of course, the best way is to not have world data hard-coded like that, but as long as ''worlds'' are same dimensions you can do:

world[21] = "212232...

which should work the same way.
again, you should really look into some other method as this is only useful for screwing around in a small world. anything larger than a few screens and you''re likely to have problems.

crazy166

some people think i'm crazy, some people know it

Share this post


Link to post
Share on other sites
I don''t mind two posts at the same time. Two answers are better than one.

Thanks, that really helped a lot. Why exactly is it a better idea to do it from a file. Will it run out of memory or something? Also, do people generally make a file for each set of tiles?

Thanks again

Share this post


Link to post
Share on other sites
Storing your maps in files is generally a good idea for two reasons. One, it cuts down on your executable size. That''ll help for cacheing and stuff like that(I think). And two, having maps in seperate files means you can change maps without having to re-compile. That also means you can use tools to create your maps. That helps out a bit too.

Jonathan

Share this post


Link to post
Share on other sites


If you need several maps and they are bigger than 100 x 100, then you really need an editor. But it is alot of work to make one. Maybe some can be found for free on the net.


-- There IS something rotten in the state of Denmark --

Share this post


Link to post
Share on other sites
Well, I think I've done my share of messing around with the tiles hard-coded in the program. Could someone give me a little code to get me started in loading a program with the tile info in it. I know I use fopen and so forth, but I'm not sure exactly how to do it.

Thanks

Edited by - Nazrix on 4/10/00 9:42:54 AM

Share this post


Link to post
Share on other sites
Here's a way it can be done (which could pretty easily be adjusted to suit your own format):

boolean read_level_file(const char* filename)
{
int rows = 0, cols = 0;
FILE *fp = NULL;

if((fp = fopen(filename, "rt")) == NULL) return FALSE;

else
{
fscanf(fp, "%d", &pacman.direction);

for(rows = 0; rows < (TILE_ROWS); ++rows) {
for(cols = 0; cols < (TILE_COLUMNS); ++cols) {

fscanf(fp, "%d", (int*)¤t_level.tile[rows][cols].type);

}
}
}

fclose(fp);
return TRUE;
}



It looks much nicer with indents, but the forum removes them

/. Muzzafarath

Edited by - Muzzafarath on 4/10/00 11:28:31 AM

Share this post


Link to post
Share on other sites
excuse my ignorance but I'm not sure if I understand what
&pacman.direction is...

and I don't totally understand this line:
fscanf(fp, "%d", (int*)¤t_level.tile[rows][cols].type);

Thanks for any info....







Edited by - Nazrix on 4/15/00 8:41:11 PM

Share this post


Link to post
Share on other sites
Pacman is my main character in my game. I store all of his information in this struct:

struct sprite
{
unsigned int score;
unsigned int level;

unsigned int x;
unsigned int y;

unsigned int direction;

char name[50];
}pacman;


So Pacman is a sprite structure, and direction is just an integer in the sprite struct that tells which way he is facing. Whenever I load a level, I read what way he should be facing.

fscanf(fp, "%d", (int*)current_level.tile[rows][cols].type);


fscanf() is a function that takes a printf() like format string and read what you wanted it from a file. "current_level.tile[rows][cols].type" refers to my level structure. I cast it to an int* so I won''t get a stupid warning... So what I do is that the line will read an integer from a file and store it in current_level.tile[rows][cols].type.

/. Muzzafarath

Share this post


Link to post
Share on other sites
Okay, I figured that was what pacman was

I tried this code, and it didn't seem to work..but am I at all on the right track?

FILE *fp = NULL;
fopen("map10-9.map", "rt");
for (int j=0; j<=21; j++){fscanf(fp,"%d", world [j];}



I tried %s and %c instead of %d in the fscanf function but to no avail.

It said that fscanf was null a few times...and it locked up a few times too.

Thanks for your help



Edited by - Nazrix on 4/18/00 1:04:36 PM

Share this post


Link to post
Share on other sites
I'm not sure what kind of variable world[j] is supposed to be, but you need to pass a pointer to fscanf.

Like so:
int myNumber;
FILE *someFile;
fscanf(someFile, "%d", &myNumber);
(Don't forget the '&' in front of the variable.)

Of course, you need to open the file before you read from it, but I'm guessing that part's already working for you.

Edited by - Jesse Chounard on 4/16/00 2:32:58 PM

Share this post


Link to post
Share on other sites
well I initialize world like this
char *world[21]=
{"11111111111111111",
"11111111111122333",
and so on until there's 21 lines...

So, I wanted to have a file that had the 21 rows of numbers and read them into the world arrays world[0] through world[21]...

yes, I believe it's opening it okay...

So perhaps if I made it
for (int j=0; j<=21; j++){fscanf(fp,"%d", &world [j]);}
by added the '&'

I'm at work so I cannot try it yet

Thanks again






Edited by - Nazrix on 4/16/00 5:57:27 PM

Edited by - Nazrix on 4/16/00 6:20:00 PM

Share this post


Link to post
Share on other sites
Say your file looks like this:

111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111

To read it you can do this:


FILE *fp = NULL;
fp = fopen("map10-9.map", "rt");
if(fp == NULL) exit(1); //File didn't open correctly

for (int j=0; j<=21; j++) { fscanf(fp, "%s", world [j]; } //Read one line from the text file


Since world[] is a pointer, there's no need to put the & infront of it when you call fscanf() since it already contains an address to a char.

That should clear things up.

/. Muzzafarath

Edited by - Muzzafarath on 4/17/00 9:43:59 AM

Share this post


Link to post
Share on other sites
Yes, that helps to clear things up.
That code makes perfect sense, however I tried it and it's not able to open the file. I checked the filename and it is correct. I even tried entering the exact path to the filename. I tried opening it with a "r" for reading and tried "r+" also. I'm not too sure what I'm doing wrong this time. As soon as I call the function to load the file it just exits the program. Sorry to keep bother you guys.

Edited by - Nazrix on 4/17/00 5:46:01 PM

Share this post


Link to post
Share on other sites
------------ Nazrix -------------

char *world[21]=
{
"111111111111111111111111111111",
"100000000000000000000000000001",
"100002222220000000000000077701",
"100002222223333333333000077701",
"100002222227777777773000070001",
"100002222227777777773000070001",
"100000000377777777773000070001",
"107777700377777777773000070001",
"177777770377777777773000770001",
"107777700377777777773007700001",
"100777770377777777773777000001",
"100000707377777777773000000001",
"100007777377777777773000000001",
"100000000302222777773000000001",
"100000000332222777773000000001",
"100000000002222333333000000001",
"100000666666666666666666600001",
"100000800000000000000000800001",
"100000800000000000000000800001",
"100000000000000000000000000001",
"111111111111111111111111111111",
};

----------- END ----------------

Ok, I see that none of these guys answered the question right. First of all, this is just a 2 dimensionnal array. It can be accessed as world[1][1]="1";// change the first character or world[1]="111111111111111111111111111111";// Change the first line. This is the way to access these types of variable....



Cyberdrek
Headhunter Soft
DLC Multimedia
Two Guys Soft

Share this post


Link to post
Share on other sites
Yeah, I agree. I think my biggest problems are with the file i/o part. I have a book on file i/o, and seems that what I''m doing is okay. I''m not sure what I''m doing wrong.

Share this post


Link to post
Share on other sites
Muzzafarath, I think your code might be slightly off:

FILE *fp = NULL;
fp = fopen("map10-9.map", "rt");
if(fp == NULL) exit(1); //File didn''t open correctly

for (int j=0; j<=21; j++) { fscanf(fp, "%s", world [j]; } //Read one line from the text file


Which causes a problem in the reading in...
the reason being that world[j] is a ptr, but it is initially pointing to a constant string...

what would be safer is:
char world[21][31];

instead of
char *world[21] = { "34343...", ..., "....334" };
or
char *world[21];
since the latter two will pass in a read-only location of memory.

fscanf is writing the string to the buffer pointed to by
world, but if there is no allocated buffer than it will be a run-time error.

[if this is not clear let me know and I''ll repost to clarify... I use C++ a lot and have forgotten most of this non-stream, FILE stuff...]

(also, if you guys are so interested in an I/O article, post to the ''request for posts'' forum...)

Good luck wit it...


Dark Lord Pi

Share this post


Link to post
Share on other sites
Download this and see for yourselves that my code works I''ve even compiled it for you (with DJGPP it it matters). Sometimes it doesn''t work if you doubleclick on it from Windows, so you have to start it from the DOS prompt.

But it DOES work (at least for me).

/. Muzzafarath

Share this post


Link to post
Share on other sites
I downloaded the code, and again, Muzzafarath, it made sense. I tried to do the same thing in my game and it does not work. I am positive that it is crashing at the point of opening the file. I remarked out the part where it reads in world[j] with the for loop, and left the opening of the file and the hard-coded world declaration
(where I set
world[0]=11111"
world[1]=11111"
and so on)

It just bombed out when it got to opening. Are there any special things to consider when doing file i/o in VC++? I imagine there is not. I am giving it the exact path to map.txt, and still to no avail.

Thanks again for all of your help

Share this post


Link to post
Share on other sites