137 lines
3.1 KiB
Go
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.22",
|
|
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]
|
|
}
|