Creating the Grid

Cell Clearing Animations in Minesweeper

How can we add animations for cell clearing or mine explosions?

Abstract art representing computer programming

Adding animations to our Minesweeper game can greatly enhance the user experience. Let's explore how we can implement animations for cell clearing and mine explosions using SDL2.

Basic Animation Framework

First, we'll create a simple animation framework:

#include <SDL.h>
#include <functional>
#include <vector>

class Animation {
public:
  Animation(
    int duration,
    std::function<void(float)> updateFunc) :
      Duration{duration},
      UpdateFunc{updateFunc}, ElapsedTime{0} {}

  bool Update(int deltaTime) {
    ElapsedTime += deltaTime;
    float progress =
      std::min(1.0f,
               static_cast<float>(ElapsedTime) /
                 Duration);
    UpdateFunc(progress);
    return ElapsedTime >= Duration;
  }

private:
  int Duration;
  std::function<void(float)> UpdateFunc;
  int ElapsedTime;
};

class AnimationManager {
public:
  void AddAnimation(Animation animation) {
    Animations.push_back(std::move(animation));
  }

  void Update(int deltaTime) {
    Animations.erase(
      std::remove_if(
        Animations.begin(), Animations.end(),
        [deltaTime](Animation &anim) {
          return anim.Update(deltaTime);
        }),
      Animations.end());
  }

private:
  std::vector<Animation> Animations;
};

Cell Clearing Animation

Now, let's modify our MinesweeperCell class to include an animation when clearing:

class MinesweeperCell : public Engine::Button {
public:
  // ... existing code ...

  void ClearCell() {
    if (isCleared) return;
    isCleared = true;
    SetIsDisabled(true);

    // Start clearing animation
    AnimationManager.AddAnimation(Animation(
      500, // Duration in milliseconds
      [this](float progress) {
        // Interpolate between initial and
        // cleared color
        SDL_Color initialColor =
          Config::BUTTON_COLOR;
        SDL_Color targetColor =
          Config::BUTTON_CLEARED_COLOR;
        Color.r = initialColor.r +
          (targetColor.r - initialColor.r) *
            progress;
        Color.g = initialColor.g +
          (targetColor.g - initialColor.g) *
            progress;
        Color.b = initialColor.b +
          (targetColor.b - initialColor.b) *
            progress;
      }));

    ReportEvent(UserEvents::CELL_CLEARED);
  }

  void Update(int deltaTime) {
    AnimationManager.Update(deltaTime);
  }

private:
  AnimationManager AnimationManager;
};

Mine Explosion Animation

For mine explosions, we can create a more dramatic animation:

class MinesweeperCell : public Engine::Button {
public:
  // ... existing code ...

  void ExplodeMine() {
    if (isExploded) return;
    isExploded = true;
    SetIsDisabled(true);

    AnimationManager.AddAnimation(Animation(
      1000, // Duration in milliseconds
      [this](float progress) {
        // Pulsating red effect
        float intensity =
          (std::sin(progress * 10) + 1) / 2;
        Color.r = 255;
        Color.g = Color.b = static_cast<Uint8>(
          255 * (1 - intensity));

        // Expand cell size
        float scale = 1 + progress * 0.2f;
        SetSize(static_cast<int>(OriginalWidth *
                                 scale),
                static_cast<int>(
                  OriginalHeight * scale));
      }));

    ReportEvent(UserEvents::MINE_EXPLODED);
  }

private:
  bool isExploded{false};
  int OriginalWidth, OriginalHeight;
};

Integrating Animations

To integrate these animations into our game loop, we need to update our main game class:

class MinesweeperGame {
public:
  void Update(int deltaTime) {
    for (auto &cell : Grid.Children) {
      cell.Update(deltaTime);
    }
  }

  void Render(SDL_Surface *Surface) {
    Grid.Render(Surface);
  }

private:
  MinesweeperGrid Grid;
};

And in our main loop:

int main() {
  // ... initialization code ...

  Uint32 lastTime = SDL_GetTicks();
  while (Running) {
    // ... event handling ...

    Uint32 currentTime = SDL_GetTicks();
    int deltaTime = currentTime - lastTime;
    lastTime = currentTime;

    Game.Update(deltaTime);
    Game.Render(WindowSurface);
    SDL_UpdateWindowSurface(Window);

    SDL_Delay(16); // Cap at roughly 60 FPS
  }

  // ... cleanup code ...
}

These animations add visual flair to our Minesweeper game. The cell clearing animation provides a smooth transition, while the mine explosion creates a dramatic effect.

Remember to adjust the animation durations and effects to suit your game's style and pacing. You can also extend this system to include other animations, such as flagging cells or revealing the entire board at game end.

This Question is from the Lesson:

Creating the Grid

Building a two-dimensional grid of interactive minesweeper cells

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

This Question is from the Lesson:

Creating the Grid

Building a two-dimensional grid of interactive minesweeper cells

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 51 Lessons
  • 100+ Code Samples
  • 91% 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