Sign in to follow this  

SDL Rects disappear when taken off the screen

This topic is 3719 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have been having this problem for a while but now I need it fixed. I have a feeling that this is a frequently asked question and that I'm going to get a rating beating. But anyways, whenever an SDL rect goes off the screen and I bring it back, its not visible, I have debug value output showing that the rect is on the screen at the time and everything. Is there a way around this?

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Booger
I have been having this problem for a while but now I need it fixed. I have a feeling that this is a frequently asked question and that I'm going to get a rating beating. But anyways, whenever an SDL rect goes off the screen and I bring it back, its not visible, I have debug value output showing that the rect is on the screen at the time and everything. Is there a way around this?


Post the relevant code. Most errors come from a mismatch between what we *think* we've coded and what we've *actually* coded.

Share this post


Link to post
Share on other sites
Ok here's an example using some altered Lazy Foo's Collision Detection code (hope this is legal).


/*This source code copyrighted by Lazy Foo' Productions (2004-2007) and may not be redestributed without written permission.*/

//The headers
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <string>

//Screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

//The frame rate
const int FRAMES_PER_SECOND = 20;

//The attributes of the square
const int SQUARE_WIDTH = 20;
const int SQUARE_HEIGHT = 20;

//The surfaces
SDL_Surface *square = NULL;
SDL_Surface *screen = NULL;

//The event structure
SDL_Event event;

//The wall
SDL_Rect wall;

//The square
class Square
{
private:
//The collision box of the square
SDL_Rect box;

//The velocity of the square
int xVel, yVel;

public:
//Initializes the variables
Square();

//Takes key presses and adjusts the square's velocity
void handle_input();

//Shows the square on the screen
void show();
};

//The timer
class Timer
{
private:
//The clock time when the timer started
int startTicks;

//The ticks stored when the timer was paused
int pausedTicks;

//The timer status
bool paused;
bool started;

public:
//Initializes variables
Timer();

//The various clock actions
void start();
void stop();
void pause();
void unpause();

//Gets the timer's time
int get_ticks();

//Checks the status of the timer
bool is_started();
bool is_paused();
};

SDL_Surface *load_image( std::string filename )
{
//The image that's loaded
SDL_Surface* loadedImage = NULL;

//The optimized surface that will be used
SDL_Surface* optimizedImage = NULL;

//Load the image
loadedImage = IMG_Load( filename.c_str() );

//If the image loaded
if( loadedImage != NULL )
{
//Create an optimized surface
optimizedImage = SDL_DisplayFormat( loadedImage );

//Free the old surface
SDL_FreeSurface( loadedImage );

//If the surface was optimized
if( optimizedImage != NULL )
{
//Color key surface
SDL_SetColorKey( optimizedImage, SDL_RLEACCEL | SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ) );
}
}

//Return the optimized surface
return optimizedImage;
}

void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{
//Holds offsets
SDL_Rect offset;

//Get offsets
offset.x = x;
offset.y = y;

//Blit
SDL_BlitSurface( source, clip, destination, &offset );
}

bool check_collision( SDL_Rect &A, SDL_Rect &B )
{
//The sides of the rectangles
int leftA, leftB;
int rightA, rightB;
int topA, topB;
int bottomA, bottomB;

//Calculate the sides of rect A
leftA = A.x;
rightA = A.x + A.w;
topA = A.y;
bottomA = A.y + A.h;

//Calculate the sides of rect B
leftB = B.x;
rightB = B.x + B.w;
topB = B.y;
bottomB = B.y + B.h;

//If any of the sides from A are outside of B
if( bottomA <= topB )
{
return false;
}

if( topA >= bottomB )
{
return false;
}

if( rightA <= leftB )
{
return false;
}

if( leftA >= rightB )
{
return false;
}

//If none of the sides from A are outside B
return true;
}

bool init()
{
//Initialize all SDL subsystems
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
return false;
}

//Set up the screen
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

//If there was in error in setting up the screen
if( screen == NULL )
{
return false;
}

//Set the window caption
SDL_WM_SetCaption( "Move the Square", NULL );

//If everything initialized fine
return true;
}

bool load_files()
{
//Load the square image
square = load_image( "square.bmp" );

//If there was a problem in loading the square
if( square == NULL )
{
return false;
}

//If everything loaded fine
return true;
}

void clean_up()
{
//Free the surface
SDL_FreeSurface( square );

//Quit SDL
SDL_Quit();
}

Square::Square()
{
//Initialize the offsets
box.x = 0;
box.y = 0;

//Set the square's dimentions
box.w = SQUARE_WIDTH;
box.h = SQUARE_HEIGHT;

//Initialize the velocity
xVel = 0;
yVel = 0;
}

void Square::handle_input()
{
//If a key was pressed
if( event.type == SDL_KEYDOWN )
{
//Adjust the velocity
switch( event.key.keysym.sym )
{
case SDLK_UP: yVel -= SQUARE_HEIGHT / 2; break;
case SDLK_DOWN: yVel += SQUARE_HEIGHT / 2; break;
case SDLK_LEFT: xVel -= SQUARE_WIDTH / 2; break;
case SDLK_RIGHT: xVel += SQUARE_WIDTH / 2; break;
}
}
//If a key was released
else if( event.type == SDL_KEYUP )
{
//Adjust the velocity
switch( event.key.keysym.sym )
{
case SDLK_UP: yVel += SQUARE_HEIGHT / 2; break;
case SDLK_DOWN: yVel -= SQUARE_HEIGHT / 2; break;
case SDLK_LEFT: xVel += SQUARE_WIDTH / 2; break;
case SDLK_RIGHT: xVel -= SQUARE_WIDTH / 2; break;
}
}
}

void Square::show()
{
//Move the square left or right
box.x += xVel;

//If the square went too far to the left or right or has collided with the wall
if( ( box.x < 0 ) || ( box.x + SQUARE_WIDTH > SCREEN_WIDTH ) || ( check_collision( box, wall ) ) )
{
//Move back
box.x -= xVel;
}

//Move the square up or down
box.y += yVel;

//If the square went too far up or down or has collided with the wall
if( ( box.y < 0 ) || ( box.y + SQUARE_HEIGHT > SCREEN_HEIGHT ) || ( check_collision( box, wall ) ) )
{
//Move back
box.y -= yVel;
}

//Show the square
apply_surface( box.x, box.y, square, screen );
}

Timer::Timer()
{
//Initialize the variables
startTicks = 0;
pausedTicks = 0;
paused = false;
started = false;
}

void Timer::start()
{
//Start the timer
started = true;

//Unpause the timer
paused = false;

//Get the current clock time
startTicks = SDL_GetTicks();
}

void Timer::stop()
{
//Stop the timer
started = false;

//Unpause the timer
paused = false;
}

void Timer::pause()
{
//If the timer is running and isn't already paused
if( ( started == true ) && ( paused == false ) )
{
//Pause the timer
paused = true;

//Calculate the paused ticks
pausedTicks = SDL_GetTicks() - startTicks;
}
}

void Timer::unpause()
{
//If the timer is paused
if( paused == true )
{
//Unpause the timer
paused = false;

//Reset the starting ticks
startTicks = SDL_GetTicks() - pausedTicks;

//Reset the paused ticks
pausedTicks = 0;
}
}

int Timer::get_ticks()
{
//If the timer is running
if( started == true )
{
//If the timer is paused
if( paused == true )
{
//Return the number of ticks when the the timer was paused
return pausedTicks;
}
else
{
//Return the current time minus the start time
return SDL_GetTicks() - startTicks;
}
}

//If the timer isn't running
return 0;
}

bool Timer::is_started()
{
return started;
}

bool Timer::is_paused()
{
return paused;
}

int main( int argc, char* args[] )
{
//Quit flag
bool quit = false;

//The square
Square mySquare;

//The frame rate regulator
Timer fps;

//Initialize
if( init() == false )
{
return 1;
}

//Load the files
if( load_files() == false )
{
return 1;
}

//Set the wall
wall.x = 300;
wall.y = 40;
wall.w = 40;
wall.h = 400;

//While the user hasn't quit
while( quit == false )
{
//Start the frame timer
fps.start();

//While there's events to handle
while( SDL_PollEvent( &event ) )
{
//Handle events for the dot
mySquare.handle_input();

//If the user has Xed out the window
if( event.type == SDL_QUIT )
{
//Quit the program
quit = true;
}
}

//Fill the screen white
SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) );

//Show the wall
SDL_FillRect( screen, &wall, SDL_MapRGB( screen->format, 0x77, 0x77, 0x77 ) );

//Show the square on the screen
mySquare.show();

//Update the screen
if( SDL_Flip( screen ) == -1 )
{
return 1;
}

//Cap the frame rate
while( fps.get_ticks() < 1000 / FRAMES_PER_SECOND )
{
//wait
}
}

//Clean up
clean_up();

return 0;
}


Share this post


Link to post
Share on other sites

This topic is 3719 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this