Cropping and Positioning Images

Creating a Slideshow Effect in SDL2

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

Abstract art representing computer programming

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.

This Question is from the Lesson:

Cropping and Positioning Images

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

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

Cropping and Positioning Images

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

3D art representing computer programming
Part of the course:

Building Minesweeper with C++ and SDL2

Apply what we learned to build an interactive, portfolio-ready capstone project using C++ and the SDL2 library

Free, unlimited access

This course includes:

  • 37 Lessons
  • 100+ Code Samples
  • 92% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved