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:
SDL_Rect
structures for each frame.Render()
method blits the current frame to the destination surface.NextFrame()
method advances to the next frame, wrapping around to the first frame after the last one.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:
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.
Answers to questions are automatically generated and may not have been reviewed.
Learn to precisely control image display using source and destination rectangles.