Originally Posted by
dwks
You could try speeding up the rendering a little bit; perhaps the lag won't matter so much if you have a faster frame rate. In terms of the SDL, if you create your video surface with the SDL_HWSURFACE video flag (to try to put the surface in hardware memory), you may get better performance. Double-buffering is quite simple, I believe you just have to initialize it and call SDL_Flip() when you want to swap the double buffers. Also make sure your bitmaps are the right format (using SDL_DisplayFormat or SDL_DisplayFormatAlpha) to match the screen; otherwise the SDL will be converting surfaces on the fly to the right depth-per-pixel, which is very slow!
You can play around with updating only those rects that have changed; I tried this in one project (atlantis, see signature), and it really was more trouble than it's worth in my opinion. If you use double-buffering and a couple of coarse checks so that you don't do silly things like painting six maps on top of each other or painting all one-hundred offscreen sprites simultaneously, computers are fast enough these days that you can redraw the entire screen. As VirtualAce (whom I still think of as Bubba . . .) says, you can create some layers to render say the map to a surface and then blit that surface all at once whenever you need to redraw the screen. Give it a shot, see what happens.
Thanks for the advice!
I tried to increase the desired frame rate in the code, but what happens is that the frame rate seems to drop to around 10-20 FPS no matter how high I set it.
I've tried both SDL_HWSURFACE and SDL_SWSURFACE in the SDL_SetVideoMode, but it makes no visible difference when it comes to performance and frame rate.
I tried using SDL_DisplayFormat, but it made all the transparent parts in my png sprites white, so I removed it. I know that you can create transparency in the code by making a specific color transparent, but I haven't done that. Is it worth doing, or is there another way?
I'm not entirely sure about all the programming terms, but I think that I am double-buffering. I'll post some of the code if you want to look at it yourself. Starting with the loop for the game itself (it's not really finished yet as you can see)
Code:
while(!quit())
{
blitMap();
charMove();
charShow();
SDL_Flip( screen );
SDL_Delay(1000/FPS);
}
bool quit()
{
if(SDL_PollEvent( &event ))
{
if(event.type == SDL_QUIT)
{
return true;
}
}
return false;
}
void blitMap()
{
for( int a = 0; a < (SCREEN_HEIGHT/16); a++)
{
for( int b = 0; b < (SCREEN_WIDTH/16); b++)
{
offset.x = (b)*16;
offset.y = (a)*16;
SDL_BlitSurface( tiles, &clip[ map[a][b] ], screen, &offset );
}
}
}
void charMove()
{
checkCharDirection();
if( charDirection == 1 ) charPosition.y -= speed;
else if( charDirection == 0 ) charPosition.y += speed;
else if( charDirection == 3 ) charPosition.x -= speed;
else if( charDirection == 2 ) charPosition.x += speed;
if( collision( charPosition.x, charPosition.y ) )
{
if( charDirection == 1 ) charPosition.y += speed;
else if( charDirection == 0 ) charPosition.y -= speed;
else if( charDirection == 3 ) charPosition.x += speed;
else if( charDirection == 2 ) charPosition.x -= speed;
}
}
void checkCharDirection()
{
keystate = SDL_GetKeyState(NULL);
if( keystate[SDLK_w] || keystate[SDLK_UP] ) charDirection = 1;
else if( keystate[SDLK_s] || keystate[SDLK_DOWN] ) charDirection = 0;
else if( keystate[SDLK_a] || keystate[SDLK_LEFT] ) charDirection = 3;
else if( keystate[SDLK_d] || keystate[SDLK_RIGHT] ) charDirection = 2;
}
bool collision(int x, int y)
{
int xTile = x/16;
int yTile = y/16;
int xTileEnd = ( x+16 )/16;
int yTileEnd = ( y+16 )/16;
if( walkable[yTile][xTile] == false ) return true;
else if( walkable[yTile][xTileEnd] == false ) return true;
else if( walkable[yTileEnd][xTile] == false ) return true;
else if( walkable[yTileEnd][xTileEnd] == false ) return true;
else return false;
}
void charShow()
{
charAnimation();
SDL_BlitSurface( character, &clipChar[(charDirection*3)+status], screen, &charPosition );
}
void charAnimation()
{
timer++;
if( timer == ANIMATION_DELAY )
{
timer = 0;
if(status < 2) status = 2;
else if(status == 2) status = 1;
}
}