PointClickEngine::Scenes::Hotspot
Inherits PointClickEngine::Core::GameObject < PointClickEngine::Core::Drawable < Reference < Object
Represents an interactive area or object within a scene.
Hotspots are the primary way players interact with the game world. They define
clickable regions that respond to different verbs (look, use, talk, etc.) and
can represent doors, items, furniture, characters, or any interactive element.
## Architecture
Hotspots inherit from GameObject and add:
- Cursor feedback system for hover states
- Verb-based interaction routing
- Optional movement blocking for obstacles
- Script integration for complex behaviors
- Debug visualization in development mode
## Basic Usage
```crystal
# Create a simple door hotspot
door = Hotspot.new("door", Vector2.new(400, 200), Vector2.new(80, 150))
door.description = "A sturdy wooden door"
door.cursor_type = Hotspot::CursorType::Use
# Add click handler
door.on_click = -> do
if player.has_item?("key")
engine.change_scene("hallway")
else
player.say("It's locked. I need a key.")
end
end
scene.add_hotspot(door)
```
## Advanced Usage with Verbs
```crystal
# Create a multi-verb NPC hotspot
guard = Hotspot.new("guard", Vector2.new(600, 300), Vector2.new(64, 96))
guard.object_type = UI::ObjectType::Character
guard.default_verb = UI::VerbType::Talk
# Different responses for different verbs
scene.on_hotspot_interact("guard") do |verb, player|
case verb
when .look?
player.say("A tired-looking guard.")
when .talk?
start_dialog("guard_conversation")
when .use?
player.say("I'd rather not touch him.")
end
end
```
## Movement Blocking
```crystal
# Create an obstacle that blocks pathfinding
table = Hotspot.new("table", Vector2.new(300, 400), Vector2.new(120, 80))
table.blocks_movement = true
table.description = "A heavy oak table"
# Characters will path around this hotspot
```
## Script Integration
```crystal
# Use Lua scripts for complex interactions
terminal = Hotspot.new("terminal", Vector2.new(200, 300), Vector2.new(100, 100))
terminal.script_path = "scripts/terminal.lua"
# In terminal.lua:
# hotspot.on_interact("terminal", function(player)
# if game.get_var("power_on") then
# show_terminal_interface()
# else
# player.say("The terminal is powered off")
# end
# end)
```
## Common Gotchas
1. Z-order matters: Hotspots are checked front-to-back
```crystal
# If hotspots overlap, only the front one receives clicks
scene.add_hotspot(background_hotspot) # Added first = behind
scene.add_hotspot(foreground_hotspot) # Added last = in front
```
2. Callbacks aren't serialized: Re-register after loading
```crystal
# ❌ This won't survive save/load:
door.on_click = -> { do_something }
# ✅ Use scripts or scene event handlers instead:
scene.on_hotspot_interact("door") { do_something }
```
3. Debug visualization performance: Many hotspots can slow down debug mode
```crystal
# Consider disabling debug for background hotspots
decorative_hotspot.visible = false # Hides debug overlay
```
4. Cursor changes require mouse movement: Static cursor won't update
```crystal
# After changing cursor_type dynamically:
hotspot.cursor_type = CursorType::Talk
# User must move mouse to see new cursor
```
## Performance Tips
- Use blocks_movement sparingly - each blocking hotspot adds to pathfinding cost
- Consider combining multiple decorative hotspots into one larger area
- Disable visible for purely functional hotspots to skip debug rendering
- Use polygon hotspots only when rectangles won't suffice
## See Also
- PolygonHotspot - For non-rectangular interaction areas
- Scene#add_hotspot - Adding hotspots to scenes
- UI::VerbCoin - Verb selection interface
- CursorManager - Cursor appearance system
Constructors
Creates a hotspot with specified properties
- name : Unique identifier for the hotspot
- position : Top-left corner of the hotspot area
- size : Width and height of the interaction area
Instance methods
Action commands mapped by verb type e.g. {"use" => "transition:garden:swirl:4.5:300,400"}
Action commands mapped by verb type e.g. {"use" => "transition:garden:swirl:4.5:300,400"}
Default verb action for this hotspot (optional)
Renders the hotspot (debug visualization only)
Hotspots are typically invisible during gameplay, but show their interaction areas when debug mode is enabled.
Draws debug visualization of the hotspot area
Override this method in subclasses for custom debug rendering such as polygon outlines or special shapes.
Gets the effective script path for this hotspot
Returns the hotspot's specific script path if set, otherwise falls back to the scene's default script path.
- scene : The scene containing this hotspot
Returns: The script path to use, or nil if no script is available
Gets the outline points for rendering or collision detection
Returns the corner points of the hotspot area. Override in subclasses that use non-rectangular shapes.
Returns: Array of Vector2 points defining the hotspot boundary
Classification of this object for interaction purposes
Callback executed when the hotspot is clicked (runtime only)
Callback executed when the hotspot is hovered (runtime only)
Optional script file path for this hotspot's behavior If nil, the hotspot will use the scene's default script
Optional script file path for this hotspot's behavior If nil, the hotspot will use the scene's default script