Greetings,
I’m curious if I am implementing this correctly. I am trying to scroll some
clouds across the screen and when they hit the edge, they will wrap back around.
I first tried blitting off screen, but I noticed it would not accept negative
values. Instead it adjusted them to positive values and then performed the
blit. I eventually got it to work by first creating an oversized surface in
memory and blitting a clipped region from that surface to the screen, after
updating and blitting the clouds on to the new surface I created in memory. The
following is a list of my code. I just want to know if this is the correct way
of doing this or if there is an easier/more efficient way of wrapping and object
back around after it goes off screen. Thank you.********************************************************************************
#include <stdlib.h>
#include <SDL/SDL.h>
//SDL global variables
SDL_Surface *screen;
SDL_Event event;
//graphics
SDL_Surface *background;
SDL_Surface *cloud;
SDL_Surface *temp;
//Timing vars
Uint32 prior;
Uint32 current;
Uint32 elapsed;
//sprite info
SDL_Rect Position1 = {200,400,384,256};
SDL_Rect Position2 = {500,100,384,256};
SDL_Rect Position3 = {800,500,384,256};
SDL_Rect screenSize = {400,0,1024,768};
//function prototypes
void render(Uint32 time);
// Entry point
int main(int argc, char *argv[])
{
// Initialize SDL’s subsystems
if ( SDL_Init(SDL_INIT_EVERYTHING) == -1 )
{
fprintf(stderr, “Unable to init SDL: %s\n”, SDL_GetError());
exit(1);
}
// Register SDL_Quit to be called at exit
atexit(SDL_Quit);
// Attempt to create a 1024x768 window with 32bit pixels, full screen and HW
accelerated.
screen = SDL_SetVideoMode(1024, 768, 32, SDL_FULLSCREEN);
//load images
background = SDL_LoadBMP("sky.bmp");
cloud = SDL_LoadBMP("cloud.bmp");
//set up a back buffer
temp = SDL_CreateRGBSurface(SDL_HWSURFACE, 1824, 768, 32, 0, 0, 0, 0);
//make cloud transparent
SDL_SetColorKey(cloud, SDL_SRCCOLORKEY, 0);
prior = SDL_GetTicks(); //get start time
// Main loop: loop forever.
while (1)
{
current = SDL_GetTicks(); //get elapsed time
//update graphics
render(elapsed = current - prior);
// Poll for events, and handle the ones we care about.
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_KEYDOWN:
break;
case SDL_KEYUP:
// If escape is pressed, return (and thus, quit)
if (event.key.keysym.sym == SDLK_ESCAPE)
return(0);
break;
case SDL_QUIT:
return(0);
}
}
}
}
void render(time)
{
//lock screen if needed
if(SDL_MUSTLOCK(temp)) {
if(SDL_LockSurface(temp) < 0)
return;
}
if(time >= 50) //update sprites
{
prior = current; //reset time
Position1.x += 1;
Position2.x += 1;
Position3.x += 1;
}
//blit the images
//blit background
SDL_BlitSurface(background, NULL, temp, &screenSize);
//blit clouds
SDL_BlitSurface(cloud, NULL, temp, &Position1);
SDL_BlitSurface(cloud, NULL, temp, &Position2);
SDL_BlitSurface(cloud, NULL, temp, &Position3);
if(SDL_MUSTLOCK(temp)) {
SDL_UnlockSurface(temp);
}
//lock screen if needed
if(SDL_MUSTLOCK(screen)) {
if(SDL_LockSurface(screen) < 0)
return;
}
//blit temp buffer to screen
SDL_BlitSurface(temp, &screenSize, screen, NULL);
if(SDL_MUSTLOCK(screen)) {
SDL_UnlockSurface(screen);
}
// Tell SDL to update the whole screen
SDL_Flip(screen);
//check if cloud position needed to be reset
if(Position1.x == 1424)
Position1.x = 16;
if(Position2.x == 1424)
Position2.x = 16;
if(Position3.x == 1424)
Position3.x = 16;
}