Changing Cursor Appearance on Hover

Can I make the cursor change appearance when it hovers over different game objects? Like showing a sword over enemies?

To implement a cursor that changes based on what it's hovering over, we need to track object positions and cursor position, then switch cursors when they intersect. Here's how to set this up:

Creating Different Cursors

First, let's create a class that manages multiple cursor types:

#include <SDL.h>
#include <SDL_image.h>
#include <unordered_map>
#include <string>

class CursorManager {
public:
  // Cursor types our game supports
  enum class CursorType {
    Default,
    Attack,
    Interact
  };

  CursorManager() {
    // Load different cursor images
    LoadCursor("default.png", CursorType::Default);
    LoadCursor("sword.png", CursorType::Attack);
    LoadCursor("hand.png", CursorType::Interact);

    // Start with default cursor
    SetActiveCursor(CursorType::Default);
  }

  ~CursorManager() {
    for (auto& [type, cursor] : Cursors) {
      SDL_FreeCursor(cursor);
    }
  }

private:
  void LoadCursor(const std::string& path, CursorType type) {
    SDL_Surface* surface{IMG_Load(path.c_str())};
    if (!surface) {
      return;
    }

    SDL_Cursor* cursor{SDL_CreateColorCursor(surface, 0, 0)};
    SDL_FreeSurface(surface);

    if (cursor) {
      Cursors[type] = cursor;
    }
  }

  void SetActiveCursor(CursorType type) {
    if (auto it = Cursors.find(type); it != Cursors.end()) {
      SDL_SetCursor(it->second);
      CurrentType = type;
    }
  }

  std::unordered_map<CursorType, SDL_Cursor*> Cursors;
  CursorType CurrentType{CursorType::Default};
};

Checking for Intersections

Next, we need to check if the cursor intersects with game objects and change the cursor accordingly:

void GameWorld::Update() {
  int mouseX, mouseY;
  SDL_GetMouseState(&mouseX, &mouseY);

  // Check for intersections with game objects
  for (const auto& enemy : Enemies) {
    SDL_Rect enemyRect{
      enemy.GetX(), enemy.GetY(),
      enemy.GetWidth(), enemy.GetHeight()
    };

    if (mouseX >= enemyRect.x &&
        mouseX < enemyRect.x + enemyRect.w &&
        mouseY >= enemyRect.y &&
        mouseY < enemyRect.y + enemyRect.h) {
      CursorManager.SetActiveCursor(
        CursorType::Attack
      );
      return;
    }
  }

  // No intersections found, revert to default
  CursorManager.SetActiveCursor(CursorType::Default);
}

This solution provides a flexible way to manage multiple cursor types and switch between them based on game state. Consider caching the last cursor type to avoid unnecessary cursor switches when the type hasn't changed.

Customising Mouse Cursors

Learn how to control cursor visibility, switch between default system cursors, and create custom cursors

Questions & Answers

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

Creating Cursor Trail Effects
How can I implement a cursor trail effect, where the cursor leaves a temporary trail as it moves?
Animating Custom Cursors
Can I animate my custom cursor by loading multiple images? How would I implement a cursor that changes appearance?
Preventing Cursor Blur When Scaling
Why does my custom cursor look blurry/pixelated when I scale my window? How can I make it stay sharp?
Adding Physics to Cursor Movement
Is there a way to limit how fast the cursor can move across the screen? Like adding weight/momentum to it?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant