SDL side-scroller scrolls inconsistantly

Posted by SDLFunTimes on Stack Overflow See other posts from Stack Overflow or by SDLFunTimes
Published on 2010-05-19T02:01:05Z Indexed on 2010/05/19 17:30 UTC
Read the original article Hit count: 389

Filed under:
|
|
|

So I'm working on an upgrade from my previous project (that I posted here for code review) this time implementing a repeating background (like what is used on cartoons) so that SDL doesn't have to load really big images for a level. There's a strange inconsistency in the program, however: the first time the user scrolls all the way to the right 2 less panels are shown than is specified. Going backwards (left) the correct number of panels is shown (that is the panels repeat the number of times specified in the code). After that it appears that going right again (once all the way at the left) the correct number of panels is shown and same going backwards. Here's some selected code and here's a .zip of all my code

constructor:

Game::Game(SDL_Event* event, SDL_Surface* scr, int level_w, int w, int h, int bpp) {
    this->event = event;
    this->bpp = bpp;
    level_width = level_w;
    screen = scr;
    w_width = w;
    w_height = h;

    //load images and set rects
    background = format_surface("background.jpg");
    person = format_surface("person.png");

    background_rect_left = background->clip_rect;
    background_rect_right = background->clip_rect;
    current_background_piece = 1; //we are displaying the first clip
    rect_in_view = &background_rect_right;
    other_rect = &background_rect_left;

    person_rect = person->clip_rect;

    background_rect_left.x = 0; background_rect_left.y = 0;
    background_rect_right.x = background->w; background_rect_right.y = 0;
    person_rect.y = background_rect_left.h - person_rect.h;
    person_rect.x = 0;
}

and here's the move method which is probably causing all the trouble:

void Game::move(SDLKey direction) {
if(direction == SDLK_RIGHT) {
    if(move_screen(direction)) {
        if(!background_reached_right()) {
            //move background right

            background_rect_left.x += movement_increment;
            background_rect_right.x += movement_increment;

            if(rect_in_view->x >= 0) {
                //move the other rect in to fill the empty space
                SDL_Rect* temp;

                other_rect->x = -w_width + rect_in_view->x;

                temp = rect_in_view;
                rect_in_view = other_rect;
                other_rect = temp;

                current_background_piece++;
                std::cout << current_background_piece << std::endl;
            }

            if(background_overshoots_right()) {
                //sees if this next blit is past the surface
                //this is used only for re-aligning the rects when 
                //the end of the screen is reached

                background_rect_left.x = 0;
                background_rect_right.x = w_width;
            }
        }
    }
    else {
        //move the person instead

        person_rect.x += movement_increment;
        if(get_person_right_side() > w_width) {
            //person went too far right

            person_rect.x = w_width - person_rect.w;
        }
    }
}

else if(direction == SDLK_LEFT) {
    if(move_screen(direction)) {
        if(!background_reached_left()) {
            //moves background left

            background_rect_left.x -= movement_increment;
            background_rect_right.x -= movement_increment;

            if(rect_in_view->x <= -w_width) {
                //swap the rect in view
                SDL_Rect* temp;

                rect_in_view->x = w_width;

                temp = rect_in_view;
                rect_in_view = other_rect;
                other_rect = temp;

                current_background_piece--;
                std::cout << current_background_piece << std::endl;
            }

            if(background_overshoots_left()) {
                background_rect_left.x = 0;
                background_rect_right.x = w_width;
            }
        }
    }
    else {
        //move the person instead

        person_rect.x -= movement_increment;
        if(person_rect.x < 0) {
            //person went too far left

            person_rect.x = 0;
        }
    }
}
}

without the rest of the code this doesn't make too much sense. Since there is too much of it I'll upload it here for testing. Anyway does anyone know how I could fix this inconsistency?

© Stack Overflow or respective owner

Related posts about c++

Related posts about sdl