Question

I am currently learning SDL and I am trying to create a Pacman game. I'm trying to take it in steps so as not to get bogged down with massive amounts of code.

So far I have created a blank window and rendered a Pacman image onto it. I am able to press the arrow keys and move the Pacman around the window. I have it set up so the Pacman image is stored as an SDL_Texture, which I blit to the window using RenderCopy. Each time the user presses an arrow, I move the coordinates of the image and re render the whole image. This works just fine. Now, however, I want to put some dots on the screen for the Pacman to eat. If I load a dot image and store it as a new texture to blit to the screen along with the Pacman, however, each time I move the Pacman the dot flashes in and out because it is being erased and re rendered along with the Pacman.

My question is, how do I avoid this "flashing"? Can I somehow re render only the Pacman without re rendering the rest of the screen? Or is there another way to do this? I figure I'm also going to have the same problem when I try to create the maze later in the background. How do I make a static background that doesn't flash in and out each time I re render?

Below is my code so far. Forgive me if there is any code of bad form in there. As I said, I am just starting to learn SDL (pretty new to C++ as well), so if there is any glaring "You should never do that!" kind of things in there, I would appreciate anyone pointing it out :)

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

EDIT: In answer to raser's comment, here is the link where I found the PollEvent example: http://wiki.libsdl.org/SDL_CreateRenderer?highlight=%28%5CbCategoryAPI%5Cb%29%7C%28SDLFunctionTemplate%29

Was it helpful?

Solution

The above method used to render the Pacman will actually work just fine for rendering the dots to the screen. Simply store an image for the dot in a new texture, create an SDL_Rect to hold this texture, and then use SDL_CreateRenderer to render the dot image to the screen along with the Pacman. You should notice no flashing of the dot between renderings as long as you have not used something like SDL_Delay to slow the framerate.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top