Customising Mouse Cursors

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?

Abstract art representing computer programming

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.

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

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:

  • 79 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 © 2025 - All Rights Reserved