change how walk works
This commit is contained in:
parent
51d9a69a4b
commit
cd7b0fae99
3 changed files with 47 additions and 21 deletions
|
@ -2,6 +2,7 @@ package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
|
@ -12,6 +13,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
gob.Register(GobDumper{})
|
||||||
gob.Register(PerfDisplay{})
|
gob.Register(PerfDisplay{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,19 +32,32 @@ func (PerfDisplay) Z() float64 {
|
||||||
// GobDumper waits for a given key combo, then dumps the game into a gob file
|
// GobDumper waits for a given key combo, then dumps the game into a gob file
|
||||||
// in the current directory.
|
// in the current directory.
|
||||||
type GobDumper struct {
|
type GobDumper struct {
|
||||||
combo []ebiten.Key
|
KeyCombo []ebiten.Key
|
||||||
game ebiten.Game
|
|
||||||
|
game *Game
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d GobDumper) Update() error {
|
func (d *GobDumper) Scan(g *Game) []interface{} {
|
||||||
for _, key := range d.combo {
|
d.game = g
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *GobDumper) Update() error {
|
||||||
|
for _, key := range d.KeyCombo {
|
||||||
if !ebiten.IsKeyPressed(key) {
|
if !ebiten.IsKeyPressed(key) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if d.game == nil {
|
||||||
|
return errors.New("nil d.game in GobDumper.Update")
|
||||||
|
}
|
||||||
f, err := os.Create(time.Now().Format("20060102030405.gob"))
|
f, err := os.Create(time.Now().Format("20060102030405.gob"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return gob.NewEncoder(f).Encode(d.game)
|
defer f.Close()
|
||||||
|
if err := gob.NewEncoder(f).Encode(d.game); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return f.Close()
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ type Game struct {
|
||||||
ScreenHeight int
|
ScreenHeight int
|
||||||
Scene *Scene
|
Scene *Scene
|
||||||
|
|
||||||
allComponents []interface{}
|
|
||||||
componentsByID map[string]interface{}
|
componentsByID map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,11 +50,21 @@ func (g *Game) Update() error {
|
||||||
// Component returns the component with a given ID.
|
// Component returns the component with a given ID.
|
||||||
func (g *Game) Component(id string) interface{} { return g.componentsByID[id] }
|
func (g *Game) Component(id string) interface{} { return g.componentsByID[id] }
|
||||||
|
|
||||||
// Walk calls visit with every component, for as long as visit returns true.
|
// Walk calls v with every component, for as long as visit returns true.
|
||||||
func (g *Game) Walk(visit func(interface{}) bool) {
|
func (g *Game) Walk(v func(interface{}) bool) {
|
||||||
for _, c := range g.allComponents {
|
g.walk(g.Scene, v)
|
||||||
if !visit(c) {
|
}
|
||||||
return
|
|
||||||
|
func (g *Game) walk(c interface{}, v func(interface{}) bool) {
|
||||||
|
if !v(c) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if sc, ok := c.(Scanner); ok {
|
||||||
|
for _, c := range sc.Scan(g) {
|
||||||
|
if !v(c) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
g.walk(c, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,16 +72,11 @@ func (g *Game) Walk(visit func(interface{}) bool) {
|
||||||
// Build builds the component database.
|
// Build builds the component database.
|
||||||
func (g *Game) Build() {
|
func (g *Game) Build() {
|
||||||
byID := make(map[string]interface{})
|
byID := make(map[string]interface{})
|
||||||
all := []interface{}{g.Scene}
|
g.walk(g.Scene, func(c interface{}) bool {
|
||||||
for offset := 0; offset < len(all); offset++ {
|
if id, ok := c.(IDer); ok {
|
||||||
head := all[offset]
|
byID[id.ID()] = c
|
||||||
if id, ok := head.(IDer); ok {
|
|
||||||
byID[id.ID()] = head
|
|
||||||
}
|
}
|
||||||
if sc, ok := head.(Scanner); ok {
|
return true
|
||||||
all = append(all, sc.Scan(g))
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
g.allComponents = all
|
|
||||||
g.componentsByID = byID
|
g.componentsByID = byID
|
||||||
}
|
}
|
||||||
|
|
7
main.go
7
main.go
|
@ -75,6 +75,12 @@ func main() {
|
||||||
ScreenWidth: screenWidth,
|
ScreenWidth: screenWidth,
|
||||||
Scene: &engine.Scene{
|
Scene: &engine.Scene{
|
||||||
Components: []interface{}{
|
Components: []interface{}{
|
||||||
|
&engine.GobDumper{
|
||||||
|
KeyCombo: []ebiten.Key{
|
||||||
|
ebiten.KeyControl,
|
||||||
|
ebiten.KeyD,
|
||||||
|
},
|
||||||
|
},
|
||||||
&engine.Tilemap{
|
&engine.Tilemap{
|
||||||
Map: tiles,
|
Map: tiles,
|
||||||
Src: engine.ImageRef{Path: "assets/boxes.png"},
|
Src: engine.ImageRef{Path: "assets/boxes.png"},
|
||||||
|
@ -84,6 +90,7 @@ func main() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
game.Build()
|
||||||
|
|
||||||
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