Creating a Slideshow Effect in SDL2

How do I create a simple slideshow effect by changing the source rectangle?

Creating a slideshow effect by changing the source rectangle is a great way to display different parts of a larger image sequentially.

This technique is often used in games for animations or in applications for image galleries. Here's how you can implement a simple slideshow effect in SDL2:

#include <SDL.h>

#include <iostream>
#include <vector>

class Slideshow {
public:
  Slideshow(const char* file, int frameWidth,
            int frameHeight)
    : surface{SDL_LoadBMP(file)},
      frameWidth{frameWidth},
      frameHeight{frameHeight},
      currentFrame{0} {
    if (!surface) {
      std::cerr << "Failed to load image: " <<
        SDL_GetError() << '\n';
      return;
    }

    // Calculate number of frames
    int cols = surface->w / frameWidth;
    int rows = surface->h / frameHeight;
    totalFrames = cols * rows;

    // Prepare frame rectangles
    for (int y = 0; y < rows; ++y) {
      for (int x = 0; x < cols; ++x) {
        frames.push_back(
          SDL_Rect{
            x * frameWidth, y * frameHeight,
            frameWidth, frameHeight});
      }
    }
  }

  void Render(SDL_Surface* destSurface, int x,
              int y) {
    if (!surface || !destSurface || frames.
      empty()) return;

    SDL_Rect destRect{
      x, y, frameWidth, frameHeight};
    SDL_BlitSurface(surface,
                    &frames[currentFrame],
                    destSurface, &destRect);
  }

  void NextFrame() {
    currentFrame = (currentFrame + 1) %
      totalFrames;
  }

  ~Slideshow() {
    if (surface) SDL_FreeSurface(surface);
  }

private:
  SDL_Surface* surface;
  int frameWidth, frameHeight;
  std::vector<SDL_Rect> frames;
  int currentFrame;
  int totalFrames;
};

int main() {
  SDL_Init(SDL_INIT_VIDEO);

  SDL_Window* window =
    SDL_CreateWindow("Slideshow Effect",
                     SDL_WINDOWPOS_UNDEFINED,
                     SDL_WINDOWPOS_UNDEFINED,
                     640, 480, 0);
  SDL_Surface* screenSurface =
    SDL_GetWindowSurface(window);

  // Assume we have a sprite sheet "slideshow.bmp"
  // with 4x4 frames, each 100x100 pixels
  Slideshow show{"slideshow.bmp", 100, 100};

  for (int i = 0; i < 64; ++i) {
    // Show each frame twice
    SDL_FillRect(screenSurface, nullptr,
                 SDL_MapRGB(
                   screenSurface->format, 255,
                   255, 255));

    show.Render(screenSurface, 270, 190);
    // Center in 640x480 window
    show.NextFrame();

    SDL_UpdateWindowSurface(window);
    SDL_Delay(500);
    // 500ms delay between frames
  }

  SDL_DestroyWindow(window);
  SDL_Quit();

  return 0;
}

This example introduces a Slideshow class that manages a sprite sheet (a single image containing multiple frames) and allows you to cycle through the frames. Here's how it works:

  1. The constructor takes the filename of the sprite sheet and the dimensions of each frame. It calculates the total number of frames and prepares SDL_Rect structures for each frame.
  2. The Render() method blits the current frame to the destination surface.
  3. The NextFrame() method advances to the next frame, wrapping around to the first frame after the last one.
  4. In the main() function, we create a loop that renders each frame, advances to the next frame, and adds a delay to control the speed of the slideshow.

The key to this slideshow effect is changing the source rectangle (frames[currentFrame]) in the SDL_BlitSurface() call. By changing which part of the source image we're blitting, we create the illusion of a changing image or animation.

This technique is versatile and can be used for various purposes:

  • Character animations in games
  • Slideshows for photo galleries
  • Animated UI elements
  • Sprite-based particle systems

Remember to handle potential errors, such as failing to load the image. Also, in a real application, you might want to add more controls like pausing, reversing, or jumping to a specific frame.

Cropping and Positioning Images

Learn to precisely control image display using source and destination rectangles.

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Centering an Image in SDL2
How do I move an image to the center of the screen using SDL2?
Detecting Image Clipping in SDL2
How do I check if an image is being clipped when rendered?
Image Rotation in SDL2 with Blitting
Is it possible to rotate an image using SDL2's blitting functions?
Rendering Multiple Instances of an Image in SDL2
How can I display the same image multiple times in different positions on the screen?
Using Negative Coordinates in SDL2
What happens if I set negative values for x and y in the destination rectangle?
Fitting an Image to Window in SDL2
How do I ensure an image always fits within the window, regardless of its size?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant