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