fix out-of-order detection, tweak sprite

This commit is contained in:
Josh Deprez 2021-08-05 15:14:56 +10:00 committed by Josh Deprez
parent 8d9806f93f
commit 9485fdfb4f
6 changed files with 46 additions and 29 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 633 B

After

Width:  |  Height:  |  Size: 605 B

22
engine/fill.go Normal file
View file

@ -0,0 +1,22 @@
package engine
import (
"image/color"
"github.com/hajimehoshi/ebiten/v2"
)
// Fill fills the screen with a colour.
type Fill struct {
Color color.Color
Hidden bool
ID
ZPos
}
func (f *Fill) Draw(screen *ebiten.Image, _ ebiten.GeoM) {
if f.Hidden {
return
}
screen.Fill(f.Color)
}

View file

@ -1,7 +1,6 @@
package engine package engine
import ( import (
"image/color"
"unsafe" "unsafe"
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
@ -31,12 +30,3 @@ func ToGeoMDef(m *ebiten.GeoM) *GeoMDef {
func (d *GeoMDef) GeoM() *ebiten.GeoM { func (d *GeoMDef) GeoM() *ebiten.GeoM {
return (*ebiten.GeoM)(unsafe.Pointer(d)) return (*ebiten.GeoM)(unsafe.Pointer(d))
} }
// Fill fills the image with a colour.
type Fill struct {
Color color.Color
}
func (f Fill) Draw(screen *ebiten.Image, _ ebiten.GeoM) {
screen.Fill(color.Color(f.Color))
}

View file

@ -36,9 +36,12 @@ func (s *Scene) Draw(screen *ebiten.Image, geom ebiten.GeoM) {
} }
} }
// Prepare does an initial Z-order sort.
func (s *Scene) Prepare(*Game) { s.sortByZ() }
// sortByZ sorts the components by Z position. // sortByZ sorts the components by Z position.
// Stable sort is used to avoid Z-fighting among layers without a Z, or // Everything without a Z sorts first. Stable sort is used to avoid Z-fighting
// among those with equal Z. All non-ZPositioners are sorted first. // (among layers without a Z, or those with equal Z).
func (s *Scene) sortByZ() { func (s *Scene) sortByZ() {
sort.SliceStable(s.Components, func(i, j int) bool { sort.SliceStable(s.Components, func(i, j int) bool {
a, aok := s.Components[i].(ZPositioner) a, aok := s.Components[i].(ZPositioner)
@ -58,8 +61,7 @@ func (s *Scene) Update() error {
if s.Disabled { if s.Disabled {
return nil return nil
} }
needsSort := false
curZ := -math.MaxFloat64 // fun fact: this is min float64
for _, c := range s.Components { for _, c := range s.Components {
// Update each updater in turn // Update each updater in turn
if u, ok := c.(Updater); ok { if u, ok := c.(Updater); ok {
@ -67,18 +69,20 @@ func (s *Scene) Update() error {
return err return err
} }
} }
if !needsSort {
// Check if the update put the components out of order
if z, ok := c.(ZPositioner); ok {
if t := z.Z(); t < curZ {
needsSort = true
curZ = t
} }
// Check if the updates put the components out of order; if so, sort
curZ := -math.MaxFloat64 // fun fact: this is min float64
for _, c := range s.Components {
z, ok := c.(ZPositioner)
if !ok {
continue
} }
} t := z.Z()
} if t < curZ {
if needsSort {
s.sortByZ() s.sortByZ()
return nil
}
curZ = t
} }
return nil return nil
} }

View file

@ -44,15 +44,16 @@ func main() {
level1 := &engine.Scene{ level1 := &engine.Scene{
ID: "level_1", ID: "level_1",
Components: []interface{}{ Components: []interface{}{
engine.Fill{ &engine.Fill{
Color: color.White, Color: color.Gray{100},
ZPos: 0,
}, },
&engine.Tilemap{ &engine.Tilemap{
ID: "terrain", ID: "terrain",
Map: tiles, Map: tiles,
Src: engine.ImageRef{Path: "assets/boxes.png"}, Src: engine.ImageRef{Path: "assets/boxes.png"},
TileSize: 16, TileSize: 16,
ZPos: 0, ZPos: 1,
}, },
&engine.SolidRect{ &engine.SolidRect{
ID: "ceiling", ID: "ceiling",
@ -75,7 +76,7 @@ func main() {
Size: image.Pt(10, 16), Size: image.Pt(10, 16),
}, },
Src: engine.ImageRef{Path: "assets/aw.png"}, Src: engine.ImageRef{Path: "assets/aw.png"},
ZPos: 1, ZPos: 2,
}, },
}, },
}, },