mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-12-28 13:06:55 -05:00
- New menu in d2player. - Added OnMouseMove and Advance to GameControl. - Pause the MapEngine when single player.
This commit is contained in:
parent
7ba3cb702d
commit
8bdbef60ed
@ -59,7 +59,13 @@ func (v *Game) Render(screen d2render.Surface) error {
|
||||
}
|
||||
|
||||
func (v *Game) Advance(tickTime float64) error {
|
||||
if !v.gameControls.InEscapeMenu() || len(v.gameClient.Players) != 1 {
|
||||
v.gameClient.MapEngine.Advance(tickTime) // TODO: Hack
|
||||
}
|
||||
|
||||
if v.gameControls != nil {
|
||||
v.gameControls.Advance(tickTime)
|
||||
}
|
||||
|
||||
v.ticksSinceLevelCheck += tickTime
|
||||
if v.ticksSinceLevelCheck > 1.0 {
|
||||
|
223
d2game/d2player/escape_menu.go
Normal file
223
d2game/d2player/escape_menu.go
Normal file
@ -0,0 +1,223 @@
|
||||
package d2player
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||
)
|
||||
|
||||
type EscapeOption int
|
||||
|
||||
const (
|
||||
EscapeOptions = EscapeOption(iota)
|
||||
EscapeSaveExit = EscapeOption(iota)
|
||||
EscapeReturn = EscapeOption(iota)
|
||||
)
|
||||
|
||||
type mouseRegion int
|
||||
|
||||
const (
|
||||
regAbove = mouseRegion(iota)
|
||||
regIn = mouseRegion(iota)
|
||||
regBelow = mouseRegion(iota)
|
||||
)
|
||||
|
||||
// EscapeMenu is the overlay menu shown in-game when pressing Escape
|
||||
type EscapeMenu struct {
|
||||
current EscapeOption
|
||||
isOpen bool
|
||||
labels []d2ui.Label
|
||||
pentLeft *d2ui.Sprite
|
||||
pentRight *d2ui.Sprite
|
||||
|
||||
// pre-computations
|
||||
pentWidth int
|
||||
pentHeight int
|
||||
textHeight int
|
||||
}
|
||||
|
||||
// Creates an default instance of the EscapeMenu
|
||||
func NewEscapeMenu() *EscapeMenu {
|
||||
return &EscapeMenu{
|
||||
labels: make([]d2ui.Label, 0),
|
||||
}
|
||||
}
|
||||
|
||||
// ScreenLoadHandler
|
||||
func (m *EscapeMenu) OnLoad() error {
|
||||
|
||||
m.labels = []d2ui.Label{
|
||||
d2ui.CreateLabel(d2resource.Font42, d2resource.PaletteSky),
|
||||
d2ui.CreateLabel(d2resource.Font42, d2resource.PaletteSky),
|
||||
d2ui.CreateLabel(d2resource.Font42, d2resource.PaletteSky),
|
||||
}
|
||||
|
||||
m.labels[EscapeOptions].SetText("OPTIONS")
|
||||
m.labels[EscapeSaveExit].SetText("SAVE AND EXIT GAME")
|
||||
m.labels[EscapeReturn].SetText("RETURN TO GAME")
|
||||
|
||||
for i := range m.labels {
|
||||
m.labels[i].Alignment = d2ui.LabelAlignCenter
|
||||
}
|
||||
|
||||
animation, _ := d2asset.LoadAnimation(d2resource.PentSpin, d2resource.PaletteUnits)
|
||||
m.pentLeft, _ = d2ui.LoadSprite(animation)
|
||||
m.pentLeft.SetBlend(false)
|
||||
m.pentLeft.PlayBackward()
|
||||
|
||||
m.pentRight, _ = d2ui.LoadSprite(animation)
|
||||
m.pentRight.SetBlend(false)
|
||||
m.pentRight.PlayForward()
|
||||
|
||||
m.pentWidth, m.pentHeight = m.pentLeft.GetFrameBounds()
|
||||
_, m.textHeight = m.labels[EscapeOptions].GetSize()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ScreenUnloadHandler
|
||||
func (m *EscapeMenu) OnUnload() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ScreenRenderHandler
|
||||
func (m *EscapeMenu) Render(target d2render.Surface) error {
|
||||
if !m.isOpen {
|
||||
return nil
|
||||
}
|
||||
|
||||
tw, _ := target.GetSize()
|
||||
// X Position of the mid-render target.
|
||||
midX := tw / 2
|
||||
|
||||
// Y Coordinates for the center of the first option
|
||||
choiceStart := 210
|
||||
// Y Delta, in pixels, between center of choices
|
||||
choiceDx := 50
|
||||
// X Delta, in pixels, between center of pentagrams
|
||||
betwPentDist := 275
|
||||
|
||||
for i := range m.labels {
|
||||
m.labels[i].SetPosition(midX, choiceStart+i*choiceDx-m.textHeight/2)
|
||||
m.labels[i].Render(target)
|
||||
}
|
||||
|
||||
m.pentLeft.SetPosition(midX-(betwPentDist+m.pentWidth/2), choiceStart+int(m.current)*choiceDx+m.pentHeight/2)
|
||||
m.pentRight.SetPosition(midX+(betwPentDist-m.pentWidth/2), choiceStart+int(m.current)*choiceDx+m.pentHeight/2)
|
||||
|
||||
m.pentLeft.Render(target)
|
||||
m.pentRight.Render(target)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ScreenAdvanceHandler
|
||||
func (m *EscapeMenu) Advance(elapsed float64) error {
|
||||
if !m.isOpen {
|
||||
return nil
|
||||
}
|
||||
|
||||
m.pentLeft.Advance(elapsed)
|
||||
m.pentRight.Advance(elapsed)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *EscapeMenu) IsOpen() bool {
|
||||
return m.isOpen
|
||||
}
|
||||
|
||||
func (m *EscapeMenu) Toggle() {
|
||||
m.isOpen = !m.isOpen
|
||||
}
|
||||
|
||||
func (m *EscapeMenu) Open() {
|
||||
m.isOpen = true
|
||||
}
|
||||
|
||||
func (m *EscapeMenu) Close() {
|
||||
m.isOpen = false
|
||||
}
|
||||
|
||||
// Moves current selection marker to closes option to mouse.
|
||||
func (m *EscapeMenu) OnMouseMove(event d2input.MouseMoveEvent) bool {
|
||||
if !m.isOpen {
|
||||
return false
|
||||
}
|
||||
lbl := &m.labels[EscapeSaveExit]
|
||||
reg := m.toMouseRegion(event.HandlerEvent, lbl)
|
||||
|
||||
switch reg {
|
||||
case regAbove:
|
||||
m.current = EscapeOptions
|
||||
case regIn:
|
||||
m.current = EscapeSaveExit
|
||||
case regBelow:
|
||||
m.current = EscapeReturn
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Allows user to click on menu options in Y coord. of mouse is over label.
|
||||
func (m *EscapeMenu) OnMouseButtonDown(event d2input.MouseEvent) bool {
|
||||
if !m.isOpen {
|
||||
return false
|
||||
}
|
||||
|
||||
lbl := &m.labels[EscapeOptions]
|
||||
if m.toMouseRegion(event.HandlerEvent, lbl) == regIn {
|
||||
m.onOptions()
|
||||
return false
|
||||
}
|
||||
|
||||
lbl = &m.labels[EscapeSaveExit]
|
||||
if m.toMouseRegion(event.HandlerEvent, lbl) == regIn {
|
||||
m.onSaveAndExit()
|
||||
return false
|
||||
}
|
||||
|
||||
lbl = &m.labels[EscapeReturn]
|
||||
if m.toMouseRegion(event.HandlerEvent, lbl) == regIn {
|
||||
m.onReturnToGame()
|
||||
return false
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// User clicked on "OPTIONS"
|
||||
func (m *EscapeMenu) onOptions() error {
|
||||
log.Println("OPTIONS Clicked from Escape Menu")
|
||||
return nil
|
||||
}
|
||||
|
||||
// User clicked on "SAVE AND EXIT"
|
||||
func (m *EscapeMenu) onSaveAndExit() error {
|
||||
log.Println("SAVE AND EXIT GAME Clicked from Escape Menu")
|
||||
return nil
|
||||
}
|
||||
|
||||
// User clicked on "RETURN TO GAME"
|
||||
func (m *EscapeMenu) onReturnToGame() error {
|
||||
m.Toggle()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Where is the Y coordinate of the mouse compared to this label.
|
||||
func (m *EscapeMenu) toMouseRegion(event d2input.HandlerEvent, lbl *d2ui.Label) mouseRegion {
|
||||
_, h := lbl.GetSize()
|
||||
y := lbl.Y
|
||||
my := event.Y
|
||||
|
||||
if my < y {
|
||||
return regAbove
|
||||
}
|
||||
if my > (y + h) {
|
||||
return regBelow
|
||||
}
|
||||
return regIn
|
||||
}
|
@ -28,6 +28,7 @@ type GameControls struct {
|
||||
mapRenderer *d2map.MapRenderer
|
||||
inventory *Inventory
|
||||
heroStats *HeroStats
|
||||
escapeMenu *EscapeMenu
|
||||
inputListener InputCallbackListener
|
||||
|
||||
// UI
|
||||
@ -49,42 +50,37 @@ func NewGameControls(hero *d2map.Player, mapEngine *d2map.MapEngine, mapRenderer
|
||||
mapRenderer: mapRenderer,
|
||||
inventory: NewInventory(),
|
||||
heroStats: NewHeroStats(),
|
||||
escapeMenu: NewEscapeMenu(),
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GameControls) OnKeyDown(event d2input.KeyEvent) bool {
|
||||
if event.Key == d2input.KeyEscape {
|
||||
g.escapeMenu.Toggle()
|
||||
return true
|
||||
}
|
||||
if event.Key == d2input.KeyI {
|
||||
g.inventory.Toggle()
|
||||
g.updateLayout()
|
||||
return true
|
||||
}
|
||||
if event.Key == d2input.KeyC {
|
||||
g.heroStats.Toggle()
|
||||
g.updateLayout()
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GameControls) updateLayout() {
|
||||
isRightPanelOpen := false
|
||||
isLeftPanelOpen := false
|
||||
|
||||
// todo : add same logic when adding quest log and skill tree
|
||||
isRightPanelOpen = g.inventory.isOpen || isRightPanelOpen
|
||||
isLeftPanelOpen = g.heroStats.isOpen || isLeftPanelOpen
|
||||
|
||||
if isRightPanelOpen == isLeftPanelOpen {
|
||||
g.mapRenderer.ViewportDefault()
|
||||
} else if isRightPanelOpen == true {
|
||||
g.mapRenderer.ViewportToLeft()
|
||||
} else {
|
||||
g.mapRenderer.ViewportToRight()
|
||||
}
|
||||
func (g *GameControls) OnMouseMove(event d2input.MouseMoveEvent) bool {
|
||||
g.escapeMenu.OnMouseMove(event)
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GameControls) OnMouseButtonDown(event d2input.MouseEvent) bool {
|
||||
if g.escapeMenu.IsOpen() {
|
||||
return g.escapeMenu.OnMouseButtonDown(event)
|
||||
}
|
||||
|
||||
px, py := g.mapRenderer.ScreenToWorld(event.X, event.Y)
|
||||
px = float64(int(px*10)) / 10.0
|
||||
py = float64(int(py*10)) / 10.0
|
||||
@ -136,12 +132,20 @@ func (g *GameControls) Load() {
|
||||
|
||||
g.inventory.Load()
|
||||
g.heroStats.Load()
|
||||
g.escapeMenu.OnLoad()
|
||||
}
|
||||
|
||||
// ScreenAdvanceHandler
|
||||
func (g *GameControls) Advance(elapsed float64) error {
|
||||
g.escapeMenu.Advance(elapsed)
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: consider caching the panels to single image that is reused.
|
||||
func (g *GameControls) Render(target d2render.Surface) {
|
||||
g.inventory.Render(target)
|
||||
g.heroStats.Render(target)
|
||||
g.escapeMenu.Render(target)
|
||||
|
||||
width, height := target.GetSize()
|
||||
offset := 0
|
||||
@ -218,3 +222,7 @@ func (g *GameControls) Render(target d2render.Surface) {
|
||||
g.globeSprite.Render(target)
|
||||
|
||||
}
|
||||
|
||||
func (g *GameControls) InEscapeMenu() bool {
|
||||
return g != nil && g.escapeMenu != nil && g.escapeMenu.IsOpen()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user