diff --git a/engine/debug.go b/engine/debug.go index aaf1e25..6879712 100644 --- a/engine/debug.go +++ b/engine/debug.go @@ -18,9 +18,14 @@ func init() { } // PerfDisplay debugprints CurrentTPS and CurrentFPS in the top left. -type PerfDisplay struct{} +type PerfDisplay struct { + Hidden bool +} -func (PerfDisplay) Draw(screen *ebiten.Image, _ ebiten.GeoM) { +func (p PerfDisplay) Draw(screen *ebiten.Image, _ ebiten.GeoM) { + if p.Hidden { + return + } ebitenutil.DebugPrint(screen, fmt.Sprintf("TPS: %0.2f FPS: %0.2f", ebiten.CurrentTPS(), ebiten.CurrentFPS())) } diff --git a/engine/game.go b/engine/game.go index f2caf65..5f17554 100644 --- a/engine/game.go +++ b/engine/game.go @@ -2,6 +2,7 @@ package engine import ( "encoding/gob" + "fmt" "github.com/hajimehoshi/ebiten/v2" ) @@ -10,10 +11,10 @@ func init() { gob.Register(Game{}) } -// IDer components have a name. This makes it easier for components to -// find and interact with one another. -type IDer interface { - ID() string +// Identifier components have a sense of self. This makes it easier for +// components to find and interact with one another. +type Identifier interface { + Ident() string } // Scanner components can be scanned. It is called when the game @@ -47,6 +48,20 @@ func (g *Game) Update() error { return g.Scene.Update() } +// RegisterComponent tells the game there is a new component. +func (g *Game) RegisterComponent(c interface{}) { + if id, ok := c.(Identifier); ok { + g.componentsByID[id.Ident()] = c + } +} + +// UnregisterComponent tells the game the component is no more. +func (g *Game) UnregisterComponent(c interface{}) { + if id, ok := c.(Identifier); ok { + delete(g.componentsByID, id.Ident()) + } +} + // Component returns the component with a given ID. func (g *Game) Component(id string) interface{} { return g.componentsByID[id] } @@ -71,12 +86,10 @@ func (g *Game) walk(c interface{}, v func(interface{}) bool) { // Build builds the component database. func (g *Game) Build() { - byID := make(map[string]interface{}) - g.walk(g.Scene, func(c interface{}) bool { - if id, ok := c.(IDer); ok { - byID[id.ID()] = c - } + g.componentsByID = make(map[string]interface{}) + g.Walk(func(c interface{}) bool { + g.RegisterComponent(c) return true }) - g.componentsByID = byID + fmt.Printf("%#v\n", g.componentsByID) } diff --git a/engine/z.go b/engine/misc.go similarity index 52% rename from engine/z.go rename to engine/misc.go index cf34c60..fcc386a 100644 --- a/engine/z.go +++ b/engine/misc.go @@ -1,5 +1,11 @@ package engine +// ID implements Identifier directly (as a string value). +type ID string + +// Ident returns id as a string. +func (id ID) Ident() string { return string(id) } + // ZPos implements ZPositioner directly (as a float64 value). type ZPos float64 diff --git a/engine/scene.go b/engine/scene.go index c1ccb39..57ba004 100644 --- a/engine/scene.go +++ b/engine/scene.go @@ -30,11 +30,17 @@ type ZPositioner interface { // Scene manages drawing and updating a bunch of components. type Scene struct { Components []interface{} - Transform ebiten.GeoM + Hidden bool + ID + Transform ebiten.GeoM + ZPos } // Draw draws all components in order. func (s *Scene) Draw(screen *ebiten.Image, geom ebiten.GeoM) { + if s.Hidden { + return + } geom.Concat(s.Transform) for _, i := range s.Components { if d, ok := i.(Drawer); ok { diff --git a/engine/tiles.go b/engine/tiles.go index b689707..296e505 100644 --- a/engine/tiles.go +++ b/engine/tiles.go @@ -15,6 +15,8 @@ func init() { // Tilemap renders a grid of tiles. type Tilemap struct { + Hidden bool + ID Map [][]Tile Src ImageRef // must be a horizontal tile set TileSize int @@ -24,6 +26,9 @@ type Tilemap struct { // Draw draws the tilemap. func (t *Tilemap) Draw(screen *ebiten.Image, geom ebiten.GeoM) { + if t.Hidden { + return + } geom.Concat(t.Transform) for j, row := range t.Map { for i, tile := range row { diff --git a/main.go b/main.go index a9ed90a..d84bcb3 100644 --- a/main.go +++ b/main.go @@ -74,6 +74,7 @@ func main() { ScreenHeight: screenHeight, ScreenWidth: screenWidth, Scene: &engine.Scene{ + ID: "root_scene", Components: []interface{}{ &engine.GobDumper{ KeyCombo: []ebiten.Key{