Files
survive/screenmanager/manager.go
2024-11-11 14:07:02 -05:00

137 lines
3.1 KiB
Go

package screenmanager
import (
"mover/gamedata"
"mover/screens"
"github.com/hajimehoshi/ebiten/v2"
)
const (
defaultWidth = 1024
defaultHeight = 768
)
type Manager struct {
Info gamedata.GameInfo
currentScene screens.Screen
currentSceneId uint
nextSceneId uint
screens []screens.Screen
internalerr error
}
// can be used to create default manager instance
func NewManager() Manager {
return Manager{
Info: gamedata.GameInfo{
Name: "survive",
Version: "0.16",
Dimensions: gamedata.Area{
Width: defaultWidth,
Height: defaultHeight,
},
},
currentSceneId: 0,
nextSceneId: 1,
internalerr: nil,
}
}
// ebitengine update proxy on behalf of current scene
func (m *Manager) Update() error {
if m.currentScene == nil {
return nil
}
err := m.currentScene.Update()
if err != nil {
return err
}
return m.internalerr
}
// shutdown application
func (m *Manager) Quit() {
m.internalerr = ebiten.Termination
}
// calls current scene's draw method if the currentscene is valid
func (m *Manager) Draw(screen *ebiten.Image) {
if m.currentScene != nil {
m.currentScene.Draw(screen)
}
}
// ebitengine proxy for layout
func (m *Manager) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
return m.Info.Dimensions.Width, m.Info.Dimensions.Height
}
// appends scene to the managed screens
func (m *Manager) AddScene(s screens.Screen) {
setDefaultHandlers(m, s)
s.SetDimensions(m.Info.Dimensions)
m.screens = append(m.screens, s)
}
// sets the default callback handlers for a given scene within manager
// Default Handling behaviours:
//
// reset: sets (scene, nextscene) to {0, 1}
// scene completion: sets (scene, nextscene) to {nextscene, nextscene+1}
// end game: shutdown groovy
//
// note: NOOP and RELOAD are purposefully not mapped; they are scene
// specific and should be mapped to by user of groovy
func setDefaultHandlers(m *Manager, s screens.Screen) {
s.SetEventHandler(screens.EventReset, func() { m.ResetScenes() })
s.SetEventHandler(screens.EventCompleted, func() { m.TransitionScene() })
s.SetEventHandler(screens.EventEndgame, func() { m.Quit() })
}
// we're going to reset the scene to the first one
func (m *Manager) ResetScenes() {
m.currentSceneId = 0
m.nextSceneId = 1
m.SetCurrentScene(0)
}
// sets the current scene, based on sceneindex n
// n > scenelist, quit
// otherwise, scene = n
func (m *Manager) SetCurrentScene(sceneId uint) {
if sceneId >= uint(len(m.screens)) {
m.Quit()
} else {
m.currentSceneId = sceneId
m.currentScene = m.screens[sceneId]
m.nextSceneId = m.currentSceneId + 1
}
}
// handle scene transition
func (m *Manager) TransitionScene() {
m.SetCurrentScene(m.nextSceneId)
}
// set new sceneId as the successor
func (m *Manager) SetNextScene(sceneId uint) {
m.nextSceneId = sceneId
}
// sets sene dimensions
func (m *Manager) SetDimensions(a gamedata.Area) {
m.Info.Dimensions = a
}
// report number of total screens
func (m *Manager) SceneCount() uint {
return uint(len(m.screens))
}
func (m *Manager) GetScene(sceneId uint) screens.Screen {
return m.screens[sceneId]
}