Scener
This commit is contained in:
parent
946b76df9a
commit
b5792d3c8a
6 changed files with 35 additions and 32 deletions
|
@ -55,6 +55,7 @@ type ImageRef struct {
|
||||||
|
|
||||||
// Image returns the image. If it hasn't been loaded yet, it loads.
|
// Image returns the image. If it hasn't been loaded yet, it loads.
|
||||||
// Multiple distinct ImageRefs can use the same path.
|
// Multiple distinct ImageRefs can use the same path.
|
||||||
|
// TODO: adopt Loader?
|
||||||
func (r *ImageRef) Image() *ebiten.Image {
|
func (r *ImageRef) Image() *ebiten.Image {
|
||||||
if r.image != nil {
|
if r.image != nil {
|
||||||
return r.image
|
return r.image
|
||||||
|
@ -78,6 +79,7 @@ func (r *ImageRef) Image() *ebiten.Image {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SceneRef loads a gzipped, gob-encoded Scene from the asset FS.
|
// SceneRef loads a gzipped, gob-encoded Scene from the asset FS.
|
||||||
|
// After Load, Scene is usable.
|
||||||
type SceneRef struct {
|
type SceneRef struct {
|
||||||
Path string
|
Path string
|
||||||
|
|
||||||
|
@ -101,17 +103,12 @@ func (r *SceneRef) Load() error {
|
||||||
if err := gob.NewDecoder(gz).Decode(sc); err != nil {
|
if err := gob.NewDecoder(gz).Decode(sc); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := sc.Load(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
r.scene = sc
|
r.scene = sc
|
||||||
return sc.Load()
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement Scener by forwarding all the other calls to r.scene
|
// Scene returns the loaded scene, or nil if not yet loaded.
|
||||||
|
func (r SceneRef) Scene() *Scene { return r.scene }
|
||||||
func (r SceneRef) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
|
||||||
r.scene.Draw(screen, opts)
|
|
||||||
}
|
|
||||||
func (r SceneRef) DrawOrder() float64 { return r.scene.DrawOrder() }
|
|
||||||
func (r SceneRef) Ident() string { return r.scene.Ident() }
|
|
||||||
func (r SceneRef) Prepare(g *Game) { r.scene.Prepare(g) }
|
|
||||||
func (r SceneRef) Scan() []interface{} { return r.scene.Scan() }
|
|
||||||
func (r SceneRef) Update() error { return r.scene.Update() }
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ func (c *Camera) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
||||||
comm.Concat(opts.GeoM)
|
comm.Concat(opts.GeoM)
|
||||||
|
|
||||||
// Draw everything.
|
// Draw everything.
|
||||||
for _, i := range c.Scene.Components {
|
for _, i := range c.Scene.Scan() {
|
||||||
if d, ok := i.(Drawer); ok {
|
if d, ok := i.(Drawer); ok {
|
||||||
pf := 1.0
|
pf := 1.0
|
||||||
if s, ok := i.(ParallaxScaler); ok {
|
if s, ok := i.(ParallaxScaler); ok {
|
||||||
|
@ -106,5 +106,5 @@ func (c *Camera) Update() error { return c.Scene.Update() }
|
||||||
// Scan returns the only child (c.Scene).
|
// Scan returns the only child (c.Scene).
|
||||||
func (c *Camera) Scan() []interface{} { return []interface{}{c.Scene} }
|
func (c *Camera) Scan() []interface{} { return []interface{}{c.Scene} }
|
||||||
|
|
||||||
// Prepare grabs a copy of game.
|
// Prepare grabs a copy of game (needed for screen dimensions)
|
||||||
func (c *Camera) Prepare(game *Game) { c.game = game }
|
func (c *Camera) Prepare(game *Game) { c.game = game }
|
||||||
|
|
|
@ -14,19 +14,19 @@ func init() {
|
||||||
type Game struct {
|
type Game struct {
|
||||||
ScreenWidth int
|
ScreenWidth int
|
||||||
ScreenHeight int
|
ScreenHeight int
|
||||||
Scene *Scene
|
Scener
|
||||||
|
|
||||||
componentsByID map[string]interface{}
|
componentsByID map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw draws the entire thing, with default draw options.
|
// Draw draws the entire thing, with default draw options.
|
||||||
func (g *Game) Draw(screen *ebiten.Image) {
|
func (g *Game) Draw(screen *ebiten.Image) {
|
||||||
g.Scene.Draw(screen, ebiten.DrawImageOptions{})
|
g.Scene().Draw(screen, ebiten.DrawImageOptions{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update updates the current scene.
|
// Update updates the current scene.
|
||||||
func (g *Game) Update() error {
|
func (g *Game) Update() error {
|
||||||
return g.Scene.Update()
|
return g.Scene().Update()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layout returns the configured screen width/height.
|
// Layout returns the configured screen width/height.
|
||||||
|
@ -86,10 +86,10 @@ func Walk(c interface{}, v func(interface{}) error) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrepareToRun builds the component database (using Walk) and then calls
|
// Prepare builds the component database (using Walk) and then calls
|
||||||
// Prepare on every Preparer. You must call PrepareToRun before passing to
|
// Prepare on every Preparer. You must call Prepare before any calls
|
||||||
// ebiten.RunGame.
|
// to Component.
|
||||||
func (g *Game) PrepareToRun() {
|
func (g *Game) Prepare() {
|
||||||
g.componentsByID = make(map[string]interface{})
|
g.componentsByID = make(map[string]interface{})
|
||||||
Walk(g, func(c interface{}) error {
|
Walk(g, func(c interface{}) error {
|
||||||
g.RegisterComponent(c)
|
g.RegisterComponent(c)
|
||||||
|
|
|
@ -18,7 +18,7 @@ type Drawer interface {
|
||||||
Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions)
|
Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DrawOrderer is used to reorder layers.
|
// DrawOrderer components can provide a number for determining draw order.
|
||||||
type DrawOrderer interface {
|
type DrawOrderer interface {
|
||||||
DrawOrder() float64
|
DrawOrder() float64
|
||||||
}
|
}
|
||||||
|
@ -55,16 +55,10 @@ type Scanner interface {
|
||||||
Scan() []interface{}
|
Scan() []interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scener components do everything that a Scene can. The other implementation
|
// Scener components are a scene (Scene or SceneRef).
|
||||||
// is SceneRef.
|
|
||||||
type Scener interface {
|
type Scener interface {
|
||||||
Drawer
|
|
||||||
DrawOrderer
|
|
||||||
Identifier
|
|
||||||
Loader
|
Loader
|
||||||
Prepper
|
Scene() *Scene
|
||||||
Scanner
|
|
||||||
Updater
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updater components can update themselves. Update is called repeatedly.
|
// Updater components can update themselves. Update is called repeatedly.
|
||||||
|
|
|
@ -10,7 +10,16 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure Scene satisfies Scener.
|
// Ensure Scene satisfies Scener.
|
||||||
var _ Scener = &Scene{}
|
var (
|
||||||
|
_ Drawer = &Scene{}
|
||||||
|
_ DrawOrderer = &Scene{}
|
||||||
|
_ Identifier = &Scene{}
|
||||||
|
_ Loader = &Scene{}
|
||||||
|
_ Scanner = &Scene{}
|
||||||
|
_ Scener = &Scene{}
|
||||||
|
_ Prepper = &Scene{}
|
||||||
|
_ Updater = &Scene{}
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
gob.Register(Scene{})
|
gob.Register(Scene{})
|
||||||
|
@ -73,6 +82,9 @@ func (s *Scene) sortByDrawOrder() {
|
||||||
// Scan returns all immediate subcomponents.
|
// Scan returns all immediate subcomponents.
|
||||||
func (s *Scene) Scan() []interface{} { return s.Components }
|
func (s *Scene) Scan() []interface{} { return s.Components }
|
||||||
|
|
||||||
|
// Scene returns itself.
|
||||||
|
func (s *Scene) Scene() *Scene { return s }
|
||||||
|
|
||||||
// Update calls Update on all Updater components.
|
// Update calls Update on all Updater components.
|
||||||
func (s *Scene) Update() error {
|
func (s *Scene) Update() error {
|
||||||
if s.Disabled {
|
if s.Disabled {
|
||||||
|
|
4
main.go
4
main.go
|
@ -102,7 +102,7 @@ func main() {
|
||||||
game := &engine.Game{
|
game := &engine.Game{
|
||||||
ScreenHeight: 240,
|
ScreenHeight: 240,
|
||||||
ScreenWidth: 320,
|
ScreenWidth: 320,
|
||||||
Scene: &engine.Scene{
|
Scener: &engine.Scene{
|
||||||
ID: "root",
|
ID: "root",
|
||||||
Components: []interface{}{
|
Components: []interface{}{
|
||||||
&engine.GobDumper{
|
&engine.GobDumper{
|
||||||
|
@ -116,7 +116,7 @@ func main() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
game.PrepareToRun()
|
game.Prepare()
|
||||||
|
|
||||||
if err := ebiten.RunGame(game); err != nil {
|
if err := ebiten.RunGame(game); err != nil {
|
||||||
log.Fatalf("Game error: %v", err)
|
log.Fatalf("Game error: %v", err)
|
||||||
|
|
Loading…
Reference in a new issue