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:
- 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. - The
Render()
method blits the current frame to the destination surface. - The
NextFrame()
method advances to the next frame, wrapping around to the first frame after the last one. - 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.