0
\$\begingroup\$

I'm using SDL to create a 2D side-scrolling platformer, but I'm getting ghosting from the sprite. I'm not used to programming with graphics or SDL so excuse any stupid remarks I make.

Here's the issue:

https://i.sstatic.net/9Go7i.png

The tutorial I'm following: http://gamedevgeek.com/tutorials/moving-sprites-with-sdl/

int main(int argc, char* argv[])
{
    SDL_Surface *screen, *temp, *sprite;
    int colorkey;

    SDL_Init(SDL_INIT_VIDEO); //Initialize SDL

    SDL_WM_SetCaption(WINDOW_TITLE, 0); //Window title

    screen = SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0); //Create window frame

    SDL_EnableKeyRepeat(70, 70); //Keyboard Repeat

    temp   = SDL_LoadBMP("sprite.bmp"); //Load the actual sprite
    sprite = SDL_DisplayFormat(temp);
    SDL_FreeSurface(temp);

    /* setup sprite colorkey and turn on RLE */
    colorkey = SDL_MapRGB(screen->format, 160, 136, 128); //Make this RGB color transparent, so sprite isn't surrounded by a colored box
    SDL_SetColorKey(sprite, SDL_SRCCOLORKEY | SDL_RLEACCEL, colorkey);

    spriteRect.x = 150; //Initial X Position
    spriteRect.y = 150; //Initial Y Position

    /* set animation frame */
    srcRect.x = 0;
    srcRect.y = 0;
    srcRect.w = SPRITE_SIZE;
    srcRect.h = SPRITE_SIZE;

    gameover = 0;

    /* message pump */
    while (!gameover)
    {
        SDL_Event event;

        /* look for an event */
        if (SDL_PollEvent(&event)) {
            HandleEvent(event);
        }

        /* collide with edges of screen */
        if (spriteRect.x <= 0)
            spriteRect.x = 0;
        if (spriteRect.x >= WINDOW_WIDTH - SPRITE_SIZE)
            spriteRect.x = WINDOW_WIDTH - SPRITE_SIZE;

        if (spriteRect.y <= 0)
            spriteRect.y = 0;
        if (spriteRect.y >= WINDOW_HEIGHT - SPRITE_SIZE)
            spriteRect.y = WINDOW_HEIGHT - SPRITE_SIZE;

        SDL_BlitSurface(sprite, &srcRect, screen, &spriteRect);
        SDL_UpdateRect(screen, 0, 0, 0, 0);
    }

    /* clean up */
    SDL_FreeSurface(sprite);
    SDL_Quit();

    return 0;
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ I don't use SDL, but I assume you need to clear the screen inbetween frames? SDL_FillRect(screen, NULL, 0x000000); It would probably work differently if you were drawing a background. \$\endgroup\$
    – House
    Apr 13, 2013 at 18:04
  • \$\begingroup\$ Yeah that sorted it, keep forgetting about the rectangles! \$\endgroup\$
    – SRG3006
    Apr 14, 2013 at 12:49

1 Answer 1

2
\$\begingroup\$

This sort of "smearing" effect is generally the result of not re-painting the entire screen between frames, so every subsequent frame contains the previous frame plus what you just drew on top of it. In your case you're only repeatedly blitting your sprite to the render surface, so you get multiple copies of the sprite.

You could clear the entire background with a function like SDL_FillRect or, as your game progresses in complexity, add a background image (perhaps via SDL_BlitSurface) fills the whole screen and paint that first at the top of the frame. In the Old Days we would use dirty rectangles to optimize this process and only redraw what has changed, but these days the power of modern GPUs makes that largely unnecessary for most computers, and we can just repaint everything from a blank slate every frame.

\$\endgroup\$
1
  • \$\begingroup\$ Just to help you to think of it: Imagine the screen surface as a blank sheet of paper. Draw anything on top of it with pencil. Now, draw it again at a different position. You have the same drawing two times in the same sheet. SDL_FillRect with your background color would act like changing to the next sheet of paper, or even erasing all previous drawings. \$\endgroup\$ May 2, 2014 at 16:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .