ichigo/engine/game.go

79 lines
1.7 KiB
Go
Raw Normal View History

2021-07-23 13:12:54 +10:00
package engine
import (
2021-07-23 13:46:19 +10:00
"sort"
2021-07-23 13:12:54 +10:00
"github.com/hajimehoshi/ebiten/v2"
)
2021-07-23 14:59:49 +10:00
// Updater is a component that can update. Update is called repeatedly.
2021-07-23 13:12:54 +10:00
type Updater interface {
Update() error
}
2021-07-23 14:59:49 +10:00
// Drawer is a component that can draw itself. Draw is called often.
// DrawAfter is used to reorder components.
2021-07-23 13:12:54 +10:00
type Drawer interface {
Draw(*ebiten.Image)
2021-07-23 17:05:05 +10:00
Z() float64
2021-07-23 13:12:54 +10:00
}
// Game implements the ebiten methods using a collection of components.
type Game struct {
2021-07-23 13:13:50 +10:00
ScreenWidth int
ScreenHeight int
Components []interface{}
2021-07-25 15:03:10 +10:00
needsSort bool
2021-07-23 13:12:54 +10:00
}
// Update calls Update on all Updater components.
func (g *Game) Update() error {
for _, c := range g.Components {
if u, ok := c.(Updater); ok {
if err := u.Update(); err != nil {
return err
}
}
}
2021-07-25 15:03:10 +10:00
if g.needsSort {
g.needsSort = false
g.sortDrawers()
}
2021-07-23 13:12:54 +10:00
return nil
}
// Draw calls Draw on all Drawer components.
func (g *Game) Draw(screen *ebiten.Image) {
for _, c := range g.Components {
if d, ok := c.(Drawer); ok {
d.Draw(screen)
}
}
}
// Layout returns the configured screen width/height.
func (g *Game) Layout(outsideWidth, outsideHeight int) (w, h int) {
return g.ScreenWidth, g.ScreenHeight
}
2021-07-23 13:46:19 +10:00
2021-07-25 15:03:10 +10:00
// SetNeedsSort tells the game that the Drawers need sorting.
// This will be done in the current update.
func (g *Game) SetNeedsSort() {
g.needsSort = true
}
// sortDrawers sorts the components by Z position.
2021-07-23 17:05:05 +10:00
// Non-Drawers are sorted before all Drawers.
2021-07-25 15:03:10 +10:00
func (g *Game) sortDrawers() {
2021-07-23 17:27:10 +10:00
// Stable sort to avoid z-fighting (among Non-Drawers and equal Drawers)
2021-07-23 17:05:05 +10:00
sort.SliceStable(g.Components, func(i, j int) bool {
2021-07-23 13:46:19 +10:00
a, aok := g.Components[i].(Drawer)
b, bok := g.Components[j].(Drawer)
if aok && bok {
2021-07-23 17:05:05 +10:00
return a.Z() < b.Z()
2021-07-23 13:46:19 +10:00
}
return !aok && bok
})
}