1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-12-26 12:06:24 -05:00

Handles Click and Hovers on most game control elements (#413) (#418)

* Handles Click and Hovers on most game control elements.

Creates a new type of "Actionable" which includes most of the bottom
bar elements. Then handles both "Click" and "Hover" into a separate
handler function.

At the moment, hover does nothing but routes correctly. Click logs
the corresponding actionable.

Known issues:
  - Not capturing button press on click (meaning player will move).
  - Basic touch detection, could be a more fancy QuadTree like struct.
  - Since the visual frames used are not just the actionable, the actual
    x, y coordinates of the actionable need to be entered statically. Changes
    in resolution would probably affect this.

* Renaming vars for code consistency and readability
This commit is contained in:
Maxime Lavigne (malavv) 2020-06-23 12:28:05 -04:00 committed by GitHub
parent 7f4db3b874
commit b640385623
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 97 additions and 8 deletions

View File

@ -15,6 +15,7 @@ averrin
Dylan "Gravestench" Knuth
Intyre
Gürkan Kaymak
Maxime "malavv" Lavigne
* DIABLO2 LOGO
Jose Pardilla (th3-prophetman)

View File

@ -2,6 +2,7 @@ package d2player
import (
"image/color"
"log"
"time"
"github.com/OpenDiablo2/OpenDiablo2/d2common"
@ -38,14 +39,30 @@ type GameControls struct {
FreeCam bool
// UI
globeSprite *d2ui.Sprite
mainPanel *d2ui.Sprite
menuButton *d2ui.Sprite
skillIcon *d2ui.Sprite
zoneChangeText *d2ui.Label
isZoneTextShown bool
globeSprite *d2ui.Sprite
mainPanel *d2ui.Sprite
menuButton *d2ui.Sprite
skillIcon *d2ui.Sprite
zoneChangeText *d2ui.Label
isZoneTextShown bool
actionableRegions []ActionableRegion
}
type ActionableType int
type ActionableRegion struct { ActionableTypeId ActionableType; Rect d2common.Rectangle }
const (
// Since they require special handling, not considering (1) globes, (2) content of the mini panel, (3) belt
leftSkill = ActionableType(iota)
leftSelec = ActionableType(iota)
xp = ActionableType(iota)
walkRun = ActionableType(iota)
stamina = ActionableType(iota)
miniPanel = ActionableType(iota)
rightSelec = ActionableType(iota)
rightSkill = ActionableType(iota)
)
func NewGameControls(hero *d2mapentity.Player, mapEngine *d2mapengine.MapEngine, mapRenderer *d2maprenderer.MapRenderer, inputListener InputCallbackListener) *GameControls {
d2term.BindAction("setmissile", "set missile id to summon on right click", func(id int) {
missileID = id
@ -64,6 +81,16 @@ func NewGameControls(hero *d2mapentity.Player, mapEngine *d2mapengine.MapEngine,
heroStats: NewHeroStats(),
escapeMenu: NewEscapeMenu(),
zoneChangeText: &label,
actionableRegions: []ActionableRegion {
{leftSkill, d2common.Rectangle{Left:115, Top:550, Width:50, Height:50 }},
{leftSelec, d2common.Rectangle{Left:206, Top:563, Width:30, Height:30 }},
{xp, d2common.Rectangle{Left:253, Top:560, Width:125, Height:5 }},
{walkRun, d2common.Rectangle{Left:255, Top:573, Width:17, Height:20 }},
{stamina, d2common.Rectangle{Left:273, Top:573, Width:105, Height:20 }},
{miniPanel, d2common.Rectangle{Left:393, Top:563, Width:12, Height:23 }},
{rightSelec,d2common.Rectangle{Left:562, Top:563, Width:30, Height:30 }},
{rightSkill,d2common.Rectangle{Left:634, Top:550, Width:50, Height:50 }},
},
}
d2term.BindAction("freecam", "toggle free camera movement", func() {
@ -162,7 +189,19 @@ func (g *GameControls) OnMouseButtonRepeat(event d2input.MouseEvent) bool {
}
func (g *GameControls) OnMouseMove(event d2input.MouseMoveEvent) bool {
g.escapeMenu.OnMouseMove(event)
if g.escapeMenu.IsOpen() {
g.escapeMenu.OnMouseMove(event)
return false
}
mx, my := event.X, event.Y
for i := range g.actionableRegions {
// Mouse over a game control element
if g.actionableRegions[i].Rect.IsInRect(mx, my) {
g.onHoverActionable(g.actionableRegions[i].ActionableTypeId)
}
}
return false
}
@ -171,7 +210,16 @@ func (g *GameControls) OnMouseButtonDown(event d2input.MouseEvent) bool {
return g.escapeMenu.OnMouseButtonDown(event)
}
px, py := g.mapRenderer.ScreenToWorld(event.X, event.Y)
mx, my := event.X, event.Y
for i := range g.actionableRegions {
// If click is on a game control element
if g.actionableRegions[i].Rect.IsInRect(mx, my) {
g.onClickActionable(g.actionableRegions[i].ActionableTypeId)
return false
}
}
px, py := g.mapRenderer.ScreenToWorld(mx, my)
px = float64(int(px*10)) / 10.0
py = float64(int(py*10)) / 10.0
@ -358,3 +406,43 @@ func (g *GameControls) HideZoneChangeTextAfter(delay float64) {
func (g *GameControls) InEscapeMenu() bool {
return g != nil && g.escapeMenu != nil && g.escapeMenu.IsOpen()
}
// Handles what to do when an actionable is hovered
func (g *GameControls) onHoverActionable(item ActionableType) {
switch item {
case leftSkill:
return
case leftSelec:
return
case xp:
return
case walkRun:
return
case stamina:
return
case miniPanel:
return
case rightSelec:
return
case rightSkill:
return
default:
log.Printf("Unrecognized ActionableType(%d) being hovered\n", item)
}
}
// Handles what to do when an actionable is clicked
func (g *GameControls) onClickActionable(item ActionableType) {
switch item {
case leftSkill: log.Println("Left Skill Action Pressed")
case leftSelec: log.Println("Left Skill Selector Action Pressed")
case xp: log.Println("XP Action Pressed")
case walkRun: log.Println("Walk/Run Action Pressed")
case stamina: log.Println("Stamina Action Pressed")
case miniPanel: log.Println("Mini Panel Action Pressed")
case rightSelec: log.Println("Right Skill Selector Action Pressed")
case rightSkill: log.Println("Right Skill Action Pressed")
default:
log.Printf("Unrecognized ActionableType(%d) being clicked\n", item)
}
}