experiment continues

This commit is contained in:
Josh Deprez 2021-08-31 18:19:14 +10:00
parent d3284f808d
commit 933340ea8d
2 changed files with 65 additions and 13 deletions

View file

@ -13,6 +13,8 @@ import (
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
) )
const gameDoesEverything = false
var _ interface { var _ interface {
Disabler Disabler
Hider Hider
@ -71,15 +73,57 @@ func (g *Game) Draw(screen *ebiten.Image) {
if g.Hidden { if g.Hidden {
return return
} }
//g.Root.Draw(screen, ebiten.DrawImageOptions{}) if !gameDoesEverything {
g.Root.Draw(screen, ebiten.DrawImageOptions{})
}
if gameDoesEverything {
hidden := map[interface{}]bool{
g: false, // g.Hidden checked above
}
transform := map[interface{}]ebiten.DrawImageOptions{
g: {},
}
// draw everything // draw everything
for _, d := range g.drawList { for _, d := range g.drawList {
// directly hidden?
if h, ok := d.(Hider); ok && h.IsHidden() { if h, ok := d.(Hider); ok && h.IsHidden() {
hidden[d] = true
continue continue
} }
// hidden by parent?
// walk up the parents to find the lowest known
hid := false
stack := []interface{}{d}
for p := g.par[d]; p != nil; p = g.par[p] {
if h, found := hidden[p]; found {
hid = h
break
}
stack = append(stack, p)
}
// unwind the stack, setting known values
for len(stack) > 0 {
l1 := len(stack) - 1
p := stack[l1]
stack = stack[:l1]
if h, ok := p.(Hider); ok {
hid = hid || h.IsHidden()
hidden[p] = hid
}
}
// now...skip if hidden
if hid {
continue
}
if t, ok := d.(Transformer); ok {
transform[t] = t.Transform() // concatted with parent transform...
}
d.Draw(screen, ebiten.DrawImageOptions{}) d.Draw(screen, ebiten.DrawImageOptions{})
} }
} }
}
// Layout returns the configured screen width/height. // Layout returns the configured screen width/height.
func (g *Game) Layout(outsideWidth, outsideHeight int) (w, h int) { func (g *Game) Layout(outsideWidth, outsideHeight int) (w, h int) {
@ -95,7 +139,7 @@ func (g *Game) Update() error {
if err := g.Root.Update(); err != nil { if err := g.Root.Update(); err != nil {
return err return err
} }
if gameDoesEverything {
// sort the draw list (yes, on every frame) // sort the draw list (yes, on every frame)
sort.Stable(g.drawList) sort.Stable(g.drawList)
// slice out any tombstones // slice out any tombstones
@ -104,6 +148,7 @@ func (g *Game) Update() error {
g.drawList = g.drawList[:i] g.drawList = g.drawList[:i]
} }
} }
}
return nil return nil
} }

View file

@ -26,6 +26,7 @@ var (
ScannerType = reflect.TypeOf((*Scanner)(nil)).Elem() ScannerType = reflect.TypeOf((*Scanner)(nil)).Elem()
ScenerType = reflect.TypeOf((*Scener)(nil)).Elem() ScenerType = reflect.TypeOf((*Scener)(nil)).Elem()
SaverType = reflect.TypeOf((*Saver)(nil)).Elem() SaverType = reflect.TypeOf((*Saver)(nil)).Elem()
TransformerType = reflect.TypeOf((*Transformer)(nil)).Elem()
UpdaterType = reflect.TypeOf((*Updater)(nil)).Elem() UpdaterType = reflect.TypeOf((*Updater)(nil)).Elem()
// Behaviours lists all the behaviours that can be queried with Game.Query. // Behaviours lists all the behaviours that can be queried with Game.Query.
@ -44,6 +45,7 @@ var (
ScannerType, ScannerType,
ScenerType, ScenerType,
SaverType, SaverType,
TransformerType,
UpdaterType, UpdaterType,
} }
) )
@ -162,6 +164,11 @@ type Saver interface {
Save() error Save() error
} }
// Transformer components can transform their child components.
type Transformer interface {
Transform() ebiten.DrawImageOptions
}
// Updater components can update themselves. Update is called repeatedly. // Updater components can update themselves. Update is called repeatedly.
// Each component is responsible for calling Update on its child components // Each component is responsible for calling Update on its child components
// (so that disabling the parent prevents updates to the children, etc). // (so that disabling the parent prevents updates to the children, etc).