Skip to main content
GameDev.net gamedev.net
🔒 Locked

Multidirectional background image scrolling with SDL

Started by djc26 Jun 23, 2011 at 12:29 AM 0 replies 3k views
Original Post
djc26
djc26
Hi,

I am new to using SDL and with the help of the GFX with SDL Lesson 6: Space Shooter tutorial (http://cone3d.gamede...als/gfxsdl/tut6) I was able to write a short program where I can horizontally scroll a background image using the left and right arrow keys. I would like to add the functionality to also be able to scroll vertically. Since the code already displays on the screen the image correctly scrolled in the horizontal direction, I figured I could use the DrawIMG function with the screen as the input to scroll vertically, by making two images as was done horizontally. This doesn't quite produce the correct results since as the screen is scrolling upwards, the pattern begins to repeat since I am using the screen as the input instead of the actual image. How could I edit my approach to get the correct results or is there a better method to do this?

Edit: As in the tutorial the dimensions of the image are 3909x400

Here is my current code:


#include <cstdlib>
#include <iostream>
#include <SDL/SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

using namespace std;

SDL_Surface *screen, *back;
float scroll=0; // How much has the screen scrolled horizontally
float scroll2=0; // How much the screen has scrolled vertically

// Load in an image and convert it to the display format
// for faster blitting.
SDL_Surface * ImageLoad(char *file)
{
SDL_Surface *temp1, *temp2;
temp1 = SDL_LoadBMP(file);
temp2 = SDL_DisplayFormat(temp1);
SDL_FreeSurface(temp1);
return temp2;
}

// Blit an image on the screen surface
void DrawIMG(SDL_Surface *img, int x, int y)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_BlitSurface(img, NULL, screen, &dest);
}

// Blit a portion of an image on the screen surface
void DrawIMG(SDL_Surface *img, int x, int y,
int w, int h, int x2, int y2)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_Rect dest2;
dest2.x = x2;
dest2.y = y2;
dest2.w = w;
dest2.h = h;
SDL_BlitSurface(img, &dest2, screen, &dest);
}

// This function draws the scrolling background
void DrawScroll()
{
// We first check, if the background has scrolled more than it's
// own width. And if so,then we must draw 2 images on the screen:
// the end of one scrolling background and the start of another.
if(scroll>3909-640)
{
//DrawIMG(back, 0,60,(int)(3909-scroll),400,(int)scroll,0);
//DrawIMG(back, (int)(3909-scroll-1),60,
// (int)(640-(3909-scroll)),400,0,0);
DrawIMG(back, 0,0,(int)(3909-scroll),400,(int)scroll,0);
DrawIMG(back, (int)(3909-scroll-1),0,
(int)(640-(3909-scroll)),400,0,0);
// If not then we draw only one background
} else {
//DrawIMG(back, 0,60,640,400,(int)scroll,0);
DrawIMG(back, 0,0,640,400,(int)scroll,0);
}

// Vertical scrolling (NOT WORKING)
if(scroll2>0)
{
DrawIMG(screen, 0, 0, 3909, (int)(400-scroll2), 0, (int)scroll2);
DrawIMG(screen, 0, (int)(400-scroll2-1), (int)(640-3909), (int)(400-scroll2), 0, 0);
}
}

// Draw the scene
void DrawScene()
{
// We first fill the entire screen with black
SDL_FillRect(screen,0,0);
// Draw the scroll
DrawScroll();
SDL_Flip(screen);
}

int main(int argc, char *argv[])
{
// We store the state of keys here
Uint8* keys;

// Initalize the SDL Video, Audio and Joystick subsystems.
if(SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0)
{
printf("Unable to init SDL: %s\n", SDL_GetError());
exit(1);
}
atexit(SDL_Quit);

// Now we get ourself a 640x480x32 fullscreen surface...
//screen=SDL_SetVideoMode(640,480,32,SDL_SWSURFACE|SDL_FULLSCREEN);
screen=SDL_SetVideoMode(640,400,32,SDL_SWSURFACE);
if ( screen == NULL )
{
printf("Unable to set 640x480 video: %s\n", SDL_GetError());
exit(1);
}

// We also load in all the graphics...
back = ImageLoad("repeat.bmp");

// Loop while done equals true
int done=0;
while(done == 0)
{
// Check if we have some interesting events...
SDL_Event event;
while(SDL_PollEvent(&event))
{
// If we must quit, then do so
if(event.type == SDL_QUIT) { done = 1; }

// Has a key been pressed down?
if(event.type == SDL_KEYDOWN)
{
// If it was escape then quit
if(event.key.keysym.sym == SDLK_ESCAPE)
{
done = 1;
}
}
}
keys = SDL_GetKeyState(NULL);
if ( keys[SDLK_LEFT] ) {
// Scroll the screen by 1 units
scroll -= 1;
// If we have scrolled more than the background image then
// decrease the scrolled amount by
// the width of the background image
if(scroll<=0) scroll+=3909;
}
if ( keys[SDLK_RIGHT] ) {
// Scroll the screen by 1 units
scroll += 1;
// If we have scrolled more than the background image then
// decrease the scrolled amount by
// the width of the background image
if(scroll>=3909) scroll-=3909;
}
if ( keys[SDLK_DOWN] ) {
// Scroll the screen by 1 units
scroll2 += 1;
// If we have scrolled more than the background image then
// decrease the scrolled amount by
// the width of the background image
if(scroll2>=400) scroll2-=400;
}
if ( keys[SDLK_UP] ) {
// Scroll the screen by 1 units
scroll2 += 1;
// If we have scrolled more than the background image then
// decrease the scrolled amount by
// the width of the background image
if(scroll2<=0) scroll2+=400;
}
DrawScene();
}

return EXIT_SUCCESS;
}


Thanks
zacaj
zacaj
You only need to use DrawIMG once, if since youre only copying the image once. X and Y correspond to horizontal and vertical, so when you call DrawIMG, you can use the last argument, which you have as zero, for scroll2
This:
[color=#1C2837][font=CourierNew, monospace][size=2][color=#660066]DrawIMG[color=#666600]([color=#000000]back[color=#666600],[color=#000000] [color=#006666]0[color=#666600],[color=#006666]0[color=#666600],[color=#006666]640[color=#666600],[color=#006666]400[color=#666600],([color=#000088]int[color=#666600])[color=#000000]scroll[color=#666600],[color=#006666]0[color=#666600]);[/font]
would become this
[font=CourierNew, monospace][size=2][color=#660066]DrawIMG[color=#666600]([color=#000000]back[color=#666600],[color=#000000] [color=#006666]0[color=#666600],[color=#006666]0[color=#666600],[color=#006666]640[color=#666600],[color=#006666]400[color=#666600],([color=#000088]int[color=#666600])[color=#000000]scroll[color=#666600],[color="#006666"](int)scroll2[color=#666600]);[/font]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.