Just need a little help (SDL)

Started by
10 comments, last by dustydoodoo 15 years, 9 months ago
I'm creating a tile based game. I've got a lot of different aspects of it done, now I am on the scrolling part. First I tried moving each tile by adding a camera variable to the drawing loop. but it seemed to be a little jagged. So now i am going to try drawing the tiles I want visible to a different surface, and just moving that surface along the screen surface. I am not doing it exactly like that, because I am making it so that it doesn't display unnecessary tiles outside of the screen area. But all i need help with is drawing one surface to another surface. this is what I've done: 1: draw tiles to surface called "slide" 2: draw surface "slide" to the "screen" surface But for some reason the tiles that I want to be drawn to the slide surface just don't show up on the screen! I'm sure that its just something small that I've done wrong with drawing one surface to another that isn't the screen surface. Is there something special I have to do? EDIT: Is drawing the tiles to a separate surface the right thing to do?
Sure i will write my signature, just gimme a piece of paper
Advertisement
So basically, you're trying to draw just a part of the game-world onto the screen? You'll need to post the drawing functions. It will probably be very inefficient to draw the entire world on a surface, and then draw a small portion of that onto the screen. We'll also want to know some specifics on how the world is organized, and possibly how the graphics for each tile are handled.
No I do not want to draw the whole map to the slide surface, I want to draw the visible part of the map (plus an extra tile or 2 for smooth scrolling purposes) and then move that whole surface along the screen surface, and then edit the slide surface to contain different tiles, depending on how far the player has scrolled.

Here are clips of code

...drawImage(tiles[t], slide, j*TILEW, i*TILEH);...void drawScene(){drawBack();drawTiles();drawImage(slide, screen, xCamP, yCamP)drawImage(man, screen, xpos, ypos);SDL_Flip(screen);}...


The first line of code is from the tile drawing loop. I took out the part that is used for scrolling, because for some reason the plus sign wasn't showing up.

the second is of course the function that draws everything to the screen
I think it may have something to do with the format of the slide surface. I'm not sure though.

EDIT: I just have to make it clear that all I'm asking about is drawing a bitmap to a surface, and then drawing that surface to the screen surface. Because I think I know how to do the scrolling.

I will simplify it just so its clear what i need help with
0:      SDL_Surface *temp, *tile, *slide;I create the surfaces.1: 	temp    = SDL_LoadBMP("tile.bmp");	tile   = SDL_DisplayFormat(temp);I load a bmp into a surface.2:      drawImage(tile, slide, x, y);I then draw that surface onto another surface.3:      drawImage(slide, screen, x, y);I draw that surface onto the screen surface, but it doesn't show up



That is how I am doing it, do you see something wrong with it? I'm kinda nervous posting how I am going about it, because I am scared someone will see what I'm doing, and be like "HOLY POO! you are so stupid!!" I know that no one would really do that, but thats just the extreme of it.

[Edited by - dustydoodoo on June 26, 2008 9:12:03 PM]
Sure i will write my signature, just gimme a piece of paper
That tiny clip of code isn't very illuminating. If you're sure that the problem is "just something small that I've done wrong", you're going to have to post small details of your code! :) As for that whole plus-sign thing, IIRC it is removed by the previewer but shows up in the post. Don't be afraid to post those big ugly nested loops that generate the coordinates of the tiles to draw!

Also, you need to comment what you post, so I know what each function actually does, what data it already has access to, etc.

I use a system where each tile is an object, and has a Tile::draw(SDL_Surface* screen, int screenXpos, int screenYpos), where screen X and Y pos are the coordinates from the top of the screen irrespective of its position in the world. Then in my main draw function, I use a set of nested loops to draw just the few tiles that are visible directly onto the screen. I don't bother with smooth scrolling. I'll try to post the actual code later if circumstances warrant.

EDIT: oops, you edited yours while I was posting mine! I take it drawImage() is a wrapper for SDL_BlitSurface()? It seems that what you're doing should work, and that's why I still think you should post some more code. Also, try checking the error returns of any SDL calls. Or try writing a tiny program that does nothing except exactly what you wrote in your pseudo-code; just those three surfaces (don't forget to free temp!), and make sure it works.
Have you read my edit yet? Because I'm not really asking about scrolling, I'm asking about... what I put in my edit of my second post.
Sure i will write my signature, just gimme a piece of paper
Ok i will try that, thanks :)
Sure i will write my signature, just gimme a piece of paper
Well I tried it and it doesn't work. So i guess i must be doing something wrong with the whole drawing one surface to another. Is there something that i have to do in order to set the slide surface to the same format as the screen, or something along the lines of that?
Sure i will write my signature, just gimme a piece of paper
Quote:Original post by dustydoodoo
Well I tried it and it doesn't work. So i guess i must be doing something wrong with the whole drawing one surface to another. Is there something that i have to do in order to set the slide surface to the same format as the screen, or something along the lines of that?


You mean you tried a tiny test? Seriously, post the whole thing, as long as it's not too much longer than 150 lines or so.

SDL is supposed to convert surfaces if they are different formats. It would be a little weird if that was the problem. There may be something wrong with your drawImage() function. I am suspicious of the lack of width parameters. That may be causing problems. If the width of whatever you are using for a source rect has width or height 0, it won't draw (it's only in the dest rect that they are ignored). You might try using raw SDL_BlitSurface calls. Check those returns!

Also, something in the code that is (supposed to be) scrolling the screen, may have side effects that affect the drawing and make it fail. I have seen some way weirder bugs, something like that would not surprise me in the least. I don't mean to be cruel, but you may just not actually know how to scroll. It's a very tricky task, and apparently you don't even have any effective drawing code to see if you have it right so far. The first time I tried it, it was a disaster! I'm pretty sure it seg-faulted.
For the test I just made another surface for the player, then drew the original player to the new one, then tried to display it on the screen. I made sure it wasn't displaying it because of a negative parameter, and i know it scrolls correctly (like i said in my first post) Also the drawImage function is only missing the parameter for cutting out a part of an image. Have you quickly tried drawing a surface loaded with an image onto another surface, then drawing the latter surface to the screen? Maybe you will find something out if it doesn't work , and if it does work you can tell me the exact source code. Also I tried doing this a while ago, when I had nothing about scrolling in the code, and it still didn't work.
Sure i will write my signature, just gimme a piece of paper
Actually my current framework relies rather fundamentally on blitting to intermediate surfaces. I just use raw SDL_BlitSurface calls, rects and all. They are spread between several disparate functions, but it's nothing magical. I use a macro to check error returns. The point is, blitting to an intermediate surface works, so that's not the problem. Until you give me some more to work with, either some code (I really want to see drawImage in full) or at least some error messages from SDL (Are you checking your error returns? there's no excuse not to), there's nothing I can do to help you except wild speculation (all of which, so far, has been dismissed).

SDL_Surface *tileimg, *temp, *intermediate, *screen;//create screenscreen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 24, FLAG_STUFF);//forgot flags, haven't done this in a while, is that even the right function?if(!screen){    cout << "failed to set display mode" << endl;    return 0;}//load tiletemp = SDL_LoadBMP("tileimg.bmp");if(!temp){cout << "failed to load tileimg.bmp" << endl; return 0;}tileimg = SDL_DisplayFormat(temp);if(!tileimg){cout << "failed to convert tileimg"<< endl; return 0;}SDL_FreeSurface(temp); //prevent memory leaks//create the middleman surfaceintermediate = SDL_CreateRGBSurface(/*I forgot all the right parameters*/);// you can reuse temp if you want to make sure temp is the same format as the display//create rectsSDL_Rect srcrect, destrect;srcrect.x = srcrect.y = 0;//top left cornersrcrect.w = TILE_WIDTH;srcrect.h = TIEL_HEIGHT;destrect.x = 0;//or whereverdestrect.y = 0;//ditto//width and height are ignored in destination rect//draw tile on intermediateint return_val = SDL_BlitSurface(tileimg, &srcrect, intermediate, &destrect);if(return_val == -1){    cout << "drawing to intermediate failed" << endl;    return 0;}//you can change destrect to anything that will fit on the screen//draw intermediate surface on screenreturn_val = SDL_BlitSurface(intermediate, &srcrect, screen, &destrect);if(return_val==-1){    cout << "drawing to screen failed" << endl;    return 0;}


This is obviously oversimplified, but it should work. Blitting is a pretty generic process. I strongly suspect your drawImage function, the more I think about it. Please, please post it. Even if it's perfect, knowing that will at least narrow things down.

This topic is closed to new replies.

Advertisement