Page 1 of 1

Help with layers xD

Posted: Sat Jan 03, 2009 10:15 am
by KuramaYoko10
Hey there guys,

I am back here needing help =D
I am doing this "Ninja game" similar to Mario but with my ninja character, and I am having problems when loading the map I created in my level editor in different layers.
**The game is in C and SDL.

In my level editor, I create the map and save the different layers in three files (one for each layer)... one example of the file is this:

Code: Select all

22  09  08  1
06  13  07  0
08  13  07  0
10  13  07  0
12  13  07  0
14  13  07  0
16  13  07  0
18  13  07  0
19  13  07  0
//Where the first number is the "x" position (multiplied by 32, the tile width, will give the right value for the position on the screen)
//Where the second number is the "y" position (same)
//Where the third number is the tile type (the code of the tile)
//And where the last number represents if the tile is collideable or not (0 = no / 1 = yes)
In my actual game, I read the file info in this loading function and then render in my game:render struct:

Code: Select all

SDL_Surface *loadLayer1(char filename[50])
{	 
	MAPLAYER1 = fopen(filename, "r");

	for(int b = 0; b < 19; b++)
	{
		for(int a = 0; a < 50; a++)
		{
			fgets(cellX, 5, MAPLAYER1);
			fgets(cellY, 5, MAPLAYER1);
			fgets(tileNum, 5, MAPLAYER1);
			fgets(coll, 2, MAPLAYER1);
			fgets(temp, 2, MAPLAYER1);

			//Use the atoi(char *str) to convert a string to an int
			printf("%d\n", atoi(cellX));
			printf("%d\n", atoi(cellY));
			printf("%d\n", atoi(tileNum));
			printf("%d\n", atoi(coll));

			tileX = atoi(cellX) * 32;
			tileY = atoi(cellY) * 32;

			tileType1[a][b].x = tileX;
			tileType1[a][b].y = tileY;
			tileType1[a][b].type = atoi(tileNum);
			tileType1[a][b].coll = atoi(coll);

			DrawIMG(tileType1[a][b].x, tileType1[a][b].y, tileSheet, layer1, &clips[tileType1[a][b].type]);
	
			//SDL_Flip(layer1);
		}
	}

	fclose(MAPLAYER1);

	optMap = SDL_DisplayFormat(layer1);
	SDL_FreeSurface(layer1);

	return optMap;
}

Code: Select all

Game::Game()
{
mapLayer1 = loadLayer1("Maps/map2_layer1.dat");

}

Code: Select all

void Game::render()
{
	DrawIMG(0, 0, mapLayer1, screen);

SDL_Flip(screen);
}
It loads and renders fine, however I am having problems when I try to render the other layers... when I do, it doesnt only render the layer2 for example, but also the layer1 or anything that was loaded before!
So my problem is that when I try rendering the layer that I have loaded in this function, it renders the layer plus what was loaded before this function...

I dont know if I was clear enough... but please help me on that... can you guys see any mistake on my loading function, or is there a better way of doing it??

Thanks in advance!! :)

Re: Help with layers xD

Posted: Tue Jan 06, 2009 2:45 pm
by andrew
Are you talking about rendering multiple layers at a time?

Re: Help with layers xD

Posted: Wed Jan 07, 2009 10:29 am
by KuramaYoko10
Yes.... I mean, with all I got now I can load the map i created on my level editor nicely, but I want to do it different...
I want to load the stuff in different layers so I could get some different effects!

I would render the background and the non-collideable stuff in one layer, then the floor and walls in a second layer, and the last details in a third layer... that way I could do stuff as walk in front of a tree that was rendered in the second layer and behind one that was rendered on the third layer.
  • void Game::render()
    {
    DrawIMG(0, 0, mapLayer1, screen);
    DrawIMG(0, 0, mapLayer2, screen);
    DrawIMG(ninjaP.x, ninjaP.y, ninja, screen);
    DrawIMG(0, 0, mapLayer3, screen);

    SDL_Flip(screen);
    }
The only problem that I am having is that when I try rendering the third layer *only* for example, it also renders the first and second with it (if those two were loaded before)!!

Re: Help with layers xD

Posted: Wed Jan 07, 2009 11:52 am
by andrew
Totally understand... you only want to draw what you can actually see on the screen. When you use a painter's algorithm to do this it's sort of unavoidable unless you can tell your tile engine what not to draw.

It sounds like you need some kind of hidden surface removal. I don't know how to do it, but it seems like it involves sorting by visibility. Your tiles need to have a visibility attribute so you can say which ones can be seen. They usually call it no_draw, I think. Then you go through the tiles and sort them by visibility. You'll need to use some kind of tree structure for a data structure to sort with.

I haven't actually seen it, but I know for sure they use it in 3d all the time and it's really fast.

I apologize for not being able to help more.

Re: Help with layers xD

Posted: Wed Jan 07, 2009 12:19 pm
by KuramaYoko10
Hmmm... I know what you mean I guess...

I have tried before loading a pink background between each layer and then setting SDL to make that pink color transparent, and it worked, but my problem was that it was taking a lot of memory i guess since when I did that the game would run as slow as a snail!!

I will look for more information on that and try creating an "algorythm" to solve that xD


Thanks dude for the info!!

Re: Help with layers xD

Posted: Wed Jan 07, 2009 3:20 pm
by MarauderIIC
I'm still not 100% on what exactly your code looks like, but if it looked like the above, then would

Code: Select all

void Game::render()
{
if (drawLayer1)
    DrawIMG(0, 0, mapLayer1, screen);
if (drawLayer2)
    DrawIMG(0, 0, mapLayer2, screen);
if (drawPlayer)
    DrawIMG(ninjaP.x, ninjaP.y, ninja, screen);
if (drawLayer3)
    DrawIMG(0, 0, mapLayer3, screen);

SDL_Flip(screen);
}
work?

Re: Help with layers xD

Posted: Wed Jan 14, 2009 2:46 pm
by Ginto8
Here's an idea:

Code: Select all

// a few #defines
#define MAPLAYER1 1
#define MAPLAYER2 2
#define NINJA_LAYER 3
#define MAPLAYER3 4
#define ALL 5

void Game::render( int layer )
{
   if( layer == 1 )
       DrawIMG(0, 0, mapLayer1, screen);
   else if( layer == 2 )
       DrawIMG(0, 0, mapLayer2, screen);
   else if( layer == 3 )
       DrawIMG(ninjaP.x, ninjaP.y, ninja, screen);
   else if( layer == 4 )
       DrawIMG(0, 0, mapLayer3, screen);
   else if( layer == 5 )
   {
       DrawIMG(0, 0, mapLayer1, screen);
       DrawIMG(0, 0, mapLayer2, screen);
       DrawIMG(ninjaP.x, ninjaP.y, ninja, screen);
       DrawIMG(0, 0, mapLayer3, screen);
   }
   SDL_Flip(screen);
}
What this will do is let you choose what layer(s) to render. You can do render( MAPLAYER1 ) etc. or you can do render( ALL ). You can customize it to your needs or use a switch instead of if statements; it's all up to you. :)