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:
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};
};
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.
Learn how to control cursor visibility, switch between default system cursors, and create custom cursors