Problems with 2D Tile Engine C++ SDL

Started by
21 comments, last by Mythios 15 years, 4 months ago
Hey guys, I'm currently having a lot of problems with a tile tutorial. I've been trying to split it up into separate files - the tutorial was obtained from "http://lazyfoo.net/SDL_tutorials/lesson29/index.php". I got it compiling fine but the display is far from right. I can scroll around on mine but the dot will vanish once i move off the first tile. So I'd take it the problem is that my setup for displaying the tile map is incorrect. Here's a small snippet of code I'm using for it. main.cpp

//Show the tiles
for( int t = 0; t < TOTAL_TILES; t++ )
{
		tiles[t]->show(&camera, screen, tileSheet, clips);		
}

tile_class.cpp

void Tile::show(SDL_Rect *pCamera, SDL_Surface *pScreen, SDL_Surface *pTileSheet, SDL_Rect pClips[])
{
    if( check_collision(pCamera, &box) == true )
    {
		SDL_Rect offset;
    
		//Get offsets
		offset.x = box.x - pCamera->x;
		offset.y = box.y - pCamera->y;

		SDL_BlitSurface(pTileSheet, pClips, pScreen, &offset );
    }
}

As you can see it's not actually taking in a value for what tile to display. But even so I'm not sure how to setup the display as I'm pulling stuff from other files. I'm using VS 2005 with SDL and SDL Image - the full source code, images and map I've uploaded here "http://www.mediafire.com/?sharekey=3ce971b5802be32cd2db6fb9a8902bda" if anyone is willing to take a look at how i've gone wrong. I setup VS 2005 how Lazy Foo's first tutorial is setup. Any help would be a big thanks. I been working on this for a while now and on other forums but so far I'm not getting much luck. Thanks for your time, Scott.
Advertisement
Quote:I'd take it the problem is that my setup for displaying the tile map is incorrect.

Actually, the tile map works fine. It's displaying the dot that's the 'gotcha!'

You're using the box's position as an argument to the source rect of the surface to blit:
SDL_BlitSurface(pDot, &box, pScreen, &offset );

So, the further the user scrolls on the tile map, less and less of the dot is drawn! In fact, just 20 pixels' scroll and the dot becomes invisible.

The second argument to this function is used to adjust which specific portion of pDot is drawn. Since you want to blit the whole surface, just pass in a NULL for this argument.
If I put my 2 cents in and get a penny for my thoughts, where does my other penny go?
EDIT: Well thanks to you now i can make the dot scroll around like mad haha. Thank you. Now hopefully i'll find an answer to my other problem :D

Awesome thank you, i see that problem there and i'll try to fix it up now. Only other problem is now getting it to display the different tiles - as i can only load 1 tile type into it :(
This one is a case of the evil array.

Here's what you've got now:
void Tile::show(SDL_Rect *pCamera, SDL_Surface *pScreen, SDL_Surface *pTileSheet, SDL_Rect pClips[]){    if( check_collision(pCamera, &box) == true )    {		SDL_Rect offset;    		//Get offsets		offset.x = box.x - pCamera->x;		offset.y = box.y - pCamera->y;		SDL_BlitSurface(pTileSheet, pClips, pScreen, &offset );    }}  

pClips is an array of SDL_Rects. When you pass in pClips, the base pointer of the array, you get the first element. That first element happens to be a green tile in your case. Every tile, no matter its type, will show up as a green tile. We need to get to the appropriate place in the array, and then take a pointer to THAT element::
SDL_BlitSurface(pTileSheet, pClips, &pScreen[type], &offset );


If I put my 2 cents in and get a penny for my thoughts, where does my other penny go?
EDIT: I just relised where the other tiles are meant to be - apart from grass is all black. Can't believe i didn't register that. I think i just got to excited to not see all grass haha. Well yeah where the other tiles are meant to be its all black and as soon as the screen/camera moves they turn into retarded grass. If the player crosses over them it leaves a trail of the player

Haha "Evil Array" Damn your good though - this is working now except when i scroll - once the tiles start to scroll they start to like blend and blurr and cross over and stuff - you know goes all retarded on me lol.

Thanks so much for getting me this far though. Been a big help :D
Any more help if correcting this would be great - only thing is I'm getting up at 6am, and its currently 3am. So I'm going to catch a few hours sleep. Be back soon :D
I'm not sure what the problem is this time. It works fine on my computer with those minor changes. Can you describe it in more detail, or if you've changed the drawing code, or provide a screenshot? ;)
If I put my 2 cents in and get a penny for my thoughts, where does my other penny go?
I just replaced my blit surface with your blit surface

http://i210.photobucket.com/albums/bb317/mythios1/myGame.jpg

Should show you what it's doing
This is a dirty backbuffer. I didn't notice it because on my system those black areas are orange sandy looking tiles.

What's happening is that you draw a frame, display it, and then use the same surface as before to draw the next frame. If there are areas you don't fill in completely (which in your case is the black tile-less areas) then the second frame can show through. Then you scroll a little more and the third frame draws, has some places that aren't filled in which now shows parts of the second frame which might show parts of the first frame, and so on.

The easiest solution is simply to clear the backbuffer of any data the previous frame had and start fresh. You can do this using SDL_FillRect:
SDL_FillRect(screen, NULL, 0); // surface, dest rect, color

This will fill the surface with a specified color (black, in this case). Put that line just before you begin drawing the frame and the backbuffer will start out solid black and you won't see other frames bleeding through.
If I put my 2 cents in and get a penny for my thoughts, where does my other penny go?
Ok that fixes it so no tiles blend with each other now - but for me they are still black? It's not showing up the other tiles from the tile sheet :( - So it looks like the previous picture but they are black with no blending.

I set it up like this which I think is correct
SDL_FillRect(screen, NULL, 0);        //Show the tiles        for( int t = 0; t < TOTAL_TILES; t++ )        {			tiles[t]->show(&camera, screen, tileSheet, clips);        }


Well apart from that i know that its saying that they are different tiles as i turned back on my tile collision
bool touches_wall(SDL_Rect *pBox, Tile *tiles[]){    //Go through the tiles	    for( int t = 0; t < iTOTAL_TILES; t++ )    {        //If the tile is a wall type tile        if( ( tiles[t]->get_type() >= iTILE_CENTER ) && ( tiles[ t ]->get_type() <= iTILE_TOPLEFT ) )        {            //If the collision box touches the wall tile			if( (check_collision(pBox, &tiles[t]->get_box() ) == true ) ) // if(check_collision(pBox, tiles[t]->get_box() == true ))            {                return true;                }        }    }        //If no wall tiles were touched    return false;}


With the adjustment of adding an ampersand to tiles[t]->get_box() which i forgot to before oops. So at the least this proves those tiles are there. They are just not loading up the graphics from the tile sheet for them

This topic is closed to new replies.

Advertisement