SDL 横向卷轴滚动不一致

发布于 2024-09-01 16:54:02 字数 3884 浏览 5 评论 0原文

因此,我正在对之前的项目(我在此处发布以供代码审查)进行升级,这次实现了重复背景(如卡通中使用的背景),以便 SDL 不必为关卡加载非常大的图像。 然而,程序中存在一个奇怪的不一致之处:用户第一次一直滚动到右侧时,显示的面板比指定的少 2 个。向后(左)显示正确的面板数量(即面板重复代码中指定的次数)。之后,似乎再次向右走(一次一直在左侧)显示了正确的面板数量,并且向后走也是如此。这是一些选定的代码,这是我所有代码的 .zip

构造函数:

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;
}

和这是可能导致所有麻烦的 move 方法:

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;
        }
    }
}
}

如果没有其余代码,这没有多大意义。由于内容太多,我会将其上传到此处进行测试。无论如何,有谁知道我如何解决这种不一致?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

已下线请稍等 2024-09-08 16:54:02

打印出代表您认为可能可疑的数据的值,并确保它们正在改变您认为应有的方式。这听起来像是一个非常典型的fencepost错误

Print out the values that represent the data you think might be suspect, and make sure they're changing the way you think they should be. It sounds like a pretty typical fencepost error.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文