Рендеринг неподвижных изображений в SDL

В настоящее время я изучаю SDL и пытаюсь создать игру Pacman. Я пытаюсь сделать это поэтапно, чтобы не увязнуть в огромных объемах кода.

До сих пор я создал пустое окно и вывел на него изображение Pacman. Я могу нажимать клавиши со стрелками и перемещать Pacman вокруг окна. Я настроил его так, чтобы изображение Pacman сохранялось как SDL_Texture, которую я помещаю в окно, используя RenderCo py. Каждый раз, когда пользователь нажимает стрелку, я перемещаю координаты изображения и заново отображаю все изображение. Это работает просто отлично. Теперь, однако, я хочу поставить несколько точек на экране, чтобы Pacman мог есть. Если я загружаю точечное изображение и сохраняю его как новую текстуру для перетаскивания на экран вместе с Pacman, тем не менее, каждый раз, когда я перемещаю Pacman, точка мигает и исчезает, потому что она стирается и воспроизводится вместе с Pacman.

У меня вопрос, как мне избежать этой "перепрошивки"? Могу ли я каким-то образом перерисовать только Pacman без перерисовки остальной части экрана? Или есть другой способ сделать это? Я полагаю, что у меня тоже будет такая же проблема, когда я попытаюсь создать лабиринт позже в фоновом режиме. Как сделать статический фон, который не мигает каждый раз при рендеринге?

Ниже мой код до сих пор. Простите, если там есть какой-то код плохой формы. Как я уже сказал, я только начинаю изучать SDL (также довольно плохо знаком с C++), поэтому, если есть какие-то вопиющие слова "Никогда не делай этого!" Я бы хотел, чтобы кто-нибудь указал на это:)

#include <iostream>
#include <SDL2/SDL.h>
using namespace std;

const int WINDOW_HEIGHT = 480;
const int WINDOW_WIDTH = 640;
const int MOVE_WIDTH = 10;

int main(int argc, const char * argv[])
{
    SDL_Window* mainWindow = NULL; //To hold the main window
    SDL_Renderer* renderer = NULL; //To hold the renderer
    SDL_Rect targetRect; //Rectangle to which pacman image will be drawn
    SDL_Surface* bmpSurface = NULL; //To hold bmp image
    SDL_Texture* bmpTexture = NULL; //To hold bmp image

    //Initialize SDL and check for errors
    if ( SDL_Init(SDL_INIT_EVERYTHING) != 0 )
    {
        cout << "ERROR: could not initialize SDL." << endl;
    }

    //Create a window
    mainWindow = SDL_CreateWindow("BAM", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, 0);

    if (mainWindow == NULL)
    {
        cout << "ERROR: could not initialize mainWindow." << endl;
    }

    //Initialize renderer
    renderer = SDL_CreateRenderer(mainWindow, -1, SDL_RENDERER_ACCELERATED);

    //Load image and store in an SDL_Surface
    bmpSurface = SDL_LoadBMP("/Users/billgrenard/Desktop/Programs/SDL/SDL_KeyPresses/SDL_KeyPresses/pacman_closed.bmp");
    if ( bmpSurface == NULL )
    {
        cout << "ERROR: could not load bmp file." << endl;
    }

    //Convert surface to texture for rendering
    bmpTexture = SDL_CreateTextureFromSurface(renderer, bmpSurface);
    if ( bmpTexture == NULL )
    {
        cout << "ERROR: could not convert bmp surface." << endl;
    }

    SDL_FreeSurface(bmpSurface);

    //Define rectangle where pacman image is to be blitted
    targetRect.w = 30;
    targetRect.h = 30;
    targetRect.x = (WINDOW_WIDTH/2) - (targetRect.w/2);
    targetRect.y = (WINDOW_HEIGHT/2) - (targetRect.h/2);


    //Main game loop
    while (1)
    {
        SDL_Event e;
        if (SDL_PollEvent(&e))
        {
            //Quit when user x's out the window
            if (e.type == SDL_QUIT)
            {
                break;
            }

            //If user presses a key enter switch statement
            else if( e.type == SDL_KEYDOWN )
            {
                switch ( e.key.keysym.sym ) {
                    //If user presses up arrow and the resulting move is inside the window, then move the Pacman's position
                    case SDLK_UP:
                        if ( targetRect.y - MOVE_WIDTH > 0 )
                        {
                            targetRect.y -= MOVE_WIDTH;
                        }

                        break;

                    //If user presses down arrow and the resulting move is inside the window, then move the Pacman's position
                    case SDLK_DOWN:
                        if ( targetRect.y + MOVE_WIDTH < (WINDOW_HEIGHT - targetRect.w) )
                        {
                            targetRect.y += MOVE_WIDTH;
                        }

                        break;

                    //If user presses right arrow and the resulting move is inside the window, then move the Pacman's position
                    case SDLK_RIGHT:
                        if ( targetRect.x + MOVE_WIDTH < (WINDOW_WIDTH - targetRect.w) )
                        {
                            targetRect.x += MOVE_WIDTH;
                        }

                        break;

                    //If user presses left arrow and the resulting move is inside the window, then move the Pacman's position
                    case SDLK_LEFT:
                        if ( targetRect.x - MOVE_WIDTH > 0 )
                        {
                            targetRect.x -= MOVE_WIDTH;
                        }

                        break;

                    default:
                        break;
                }
            }
        }

        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, bmpTexture, NULL, &targetRect);
        SDL_RenderPresent(renderer);       
    }

    SDL_DestroyWindow(mainWindow);
    SDL_DestroyTexture(bmpTexture);
    SDL_DestroyRenderer(renderer);
    SDL_Quit();

    return 0;
}

РЕДАКТИРОВАТЬ: В ответ на комментарий raser, вот ссылка, где я нашел пример PollEvent: http://wiki.libsdl.org/SDL_CreateRenderer?highlight=%28%5CbCategoryAPI%5Cb%29%7C%28SDLFunctionTemplate%29

1 ответ

Решение

Приведенный выше метод, используемый для рендеринга Pacman, на самом деле будет прекрасно работать для рендеринга точек на экране. Просто сохраните изображение для точки в новой текстуре, создайте SDL_Rect для хранения этой текстуры, а затем используйте SDL_CreateRenderer для рендеринга точечного изображения на экран вместе с Pacman. Вы должны заметить отсутствие мигания точки между визуализациями, если вы не использовали что-то вроде SDL_Delay для замедления частоты кадров.

Другие вопросы по тегам