game does drawing
This commit is contained in:
parent
a05cf83a7b
commit
46c6a72fdd
5 changed files with 62 additions and 28 deletions
|
@ -11,6 +11,7 @@ import (
|
||||||
var _ interface {
|
var _ interface {
|
||||||
Identifier
|
Identifier
|
||||||
Prepper
|
Prepper
|
||||||
|
Transformer
|
||||||
} = &Camera{}
|
} = &Camera{}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -37,3 +38,13 @@ func (c *Camera) Prepare(game *Game) error {
|
||||||
c.game = game
|
c.game = game
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transform returns the camera transform.
|
||||||
|
func (c *Camera) Transform() ebiten.DrawImageOptions {
|
||||||
|
var opts ebiten.DrawImageOptions
|
||||||
|
opts.GeoM.Translate(float2(c.Centre.Mul(-1)))
|
||||||
|
opts.GeoM.Scale(c.Zoom, c.Zoom)
|
||||||
|
opts.GeoM.Rotate(c.Rotation)
|
||||||
|
opts.GeoM.Translate(float64(c.game.ScreenWidth/2), float64(c.game.ScreenHeight/2))
|
||||||
|
return opts
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const gameDoesEverything = false
|
const gameDoesEverything = true
|
||||||
|
|
||||||
var _ interface {
|
var _ interface {
|
||||||
Disabler
|
Disabler
|
||||||
|
@ -68,60 +68,71 @@ func (d drawers) Less(i, j int) bool { return d[i].DrawOrder() < d[j].DrawOrder(
|
||||||
func (d drawers) Len() int { return len(d) }
|
func (d drawers) Len() int { return len(d) }
|
||||||
func (d drawers) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
|
func (d drawers) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
|
||||||
|
|
||||||
|
func concatOpts(a, b ebiten.DrawImageOptions) ebiten.DrawImageOptions {
|
||||||
|
a.ColorM.Concat(b.ColorM)
|
||||||
|
a.GeoM.Concat(b.GeoM)
|
||||||
|
a.CompositeMode = b.CompositeMode
|
||||||
|
a.Filter = b.Filter
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
// Draw draws the entire thing, with default draw options.
|
// Draw draws the entire thing, with default draw options.
|
||||||
func (g *Game) Draw(screen *ebiten.Image) {
|
func (g *Game) Draw(screen *ebiten.Image) {
|
||||||
if g.Hidden {
|
if g.Hidden {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !gameDoesEverything {
|
|
||||||
g.Root.Draw(screen, ebiten.DrawImageOptions{})
|
|
||||||
}
|
|
||||||
if gameDoesEverything {
|
if gameDoesEverything {
|
||||||
hidden := map[interface{}]bool{
|
type state struct {
|
||||||
g: false, // g.Hidden checked above
|
hidden bool
|
||||||
|
opts ebiten.DrawImageOptions
|
||||||
}
|
}
|
||||||
transform := map[interface{}]ebiten.DrawImageOptions{
|
accum := map[interface{}]state{
|
||||||
g: {},
|
g: {hidden: false},
|
||||||
}
|
}
|
||||||
// draw everything
|
// draw everything
|
||||||
for _, d := range g.drawList {
|
for _, d := range g.drawList {
|
||||||
// directly hidden?
|
// is d directly hidden?
|
||||||
if h, ok := d.(Hider); ok && h.IsHidden() {
|
if h, ok := d.(Hider); ok && h.IsHidden() {
|
||||||
hidden[d] = true
|
accum[d] = state{hidden: true}
|
||||||
continue
|
continue // skip drawing
|
||||||
}
|
}
|
||||||
// hidden by parent?
|
// walk up g.par to find the nearest parent state in accum
|
||||||
// walk up the parents to find the lowest known
|
var st state
|
||||||
hid := false
|
|
||||||
stack := []interface{}{d}
|
stack := []interface{}{d}
|
||||||
for p := g.par[d]; p != nil; p = g.par[p] {
|
for p := g.par[d]; ; p = g.par[p] {
|
||||||
if h, found := hidden[p]; found {
|
if s, found := accum[p]; found {
|
||||||
hid = h
|
st = s
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
stack = append(stack, p)
|
stack = append(stack, p)
|
||||||
}
|
}
|
||||||
// unwind the stack, setting known values
|
// unwind the stack, accumulating state along the way
|
||||||
for len(stack) > 0 {
|
for len(stack) > 0 {
|
||||||
l1 := len(stack) - 1
|
l1 := len(stack) - 1
|
||||||
p := stack[l1]
|
p := stack[l1]
|
||||||
stack = stack[:l1]
|
stack = stack[:l1]
|
||||||
if h, ok := p.(Hider); ok {
|
if h, ok := p.(Hider); ok {
|
||||||
hid = hid || h.IsHidden()
|
st.hidden = st.hidden || h.IsHidden()
|
||||||
hidden[p] = hid
|
|
||||||
}
|
}
|
||||||
|
if st.hidden {
|
||||||
|
accum[p] = state{hidden: true}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if t, ok := p.(Transformer); ok {
|
||||||
|
st.opts = concatOpts(t.Transform(), st.opts)
|
||||||
|
}
|
||||||
|
accum[p] = st
|
||||||
}
|
}
|
||||||
|
|
||||||
// now...skip if hidden
|
// now...skip drawing if hidden :P
|
||||||
if hid {
|
if st.hidden {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
d.Draw(screen, st.opts)
|
||||||
if t, ok := d.(Transformer); ok {
|
|
||||||
transform[t] = t.Transform() // concatted with parent transform...
|
|
||||||
}
|
|
||||||
d.Draw(screen, ebiten.DrawImageOptions{})
|
|
||||||
}
|
}
|
||||||
|
} else { // !gameDoesEverything
|
||||||
|
g.Root.Draw(screen, ebiten.DrawImageOptions{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -156,6 +156,7 @@ type Scener interface {
|
||||||
Identifier
|
Identifier
|
||||||
Prepper
|
Prepper
|
||||||
Scanner
|
Scanner
|
||||||
|
Transformer
|
||||||
Updater
|
Updater
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ type Scene struct {
|
||||||
|
|
||||||
// Draw draws all components in order.
|
// Draw draws all components in order.
|
||||||
func (s *Scene) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
func (s *Scene) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
||||||
if s.Hidden {
|
if s.Hidden || gameDoesEverything {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if s.Camera == nil {
|
if s.Camera == nil {
|
||||||
|
@ -106,6 +106,14 @@ func (s *Scene) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transform returns the camera transform
|
||||||
|
func (s *Scene) Transform() ebiten.DrawImageOptions {
|
||||||
|
if s.Camera == nil {
|
||||||
|
return ebiten.DrawImageOptions{}
|
||||||
|
}
|
||||||
|
return s.Camera.Transform()
|
||||||
|
}
|
||||||
|
|
||||||
// Prepare does an initial Z-order sort.
|
// Prepare does an initial Z-order sort.
|
||||||
func (s *Scene) Prepare(game *Game) error {
|
func (s *Scene) Prepare(game *Game) error {
|
||||||
s.sortByDrawOrder()
|
s.sortByDrawOrder()
|
||||||
|
|
|
@ -88,5 +88,8 @@ func (r SceneRef) Prepare(g *Game) error { return r.scene.Prepare(g) }
|
||||||
// Scan returns the components in the scene.
|
// Scan returns the components in the scene.
|
||||||
func (r SceneRef) Scan() []interface{} { return r.scene.Scan() }
|
func (r SceneRef) Scan() []interface{} { return r.scene.Scan() }
|
||||||
|
|
||||||
|
// Transform returns the value of Transform from the scene.
|
||||||
|
func (r SceneRef) Transform() ebiten.DrawImageOptions { return r.scene.Transform() }
|
||||||
|
|
||||||
// Update updates the scene.
|
// Update updates the scene.
|
||||||
func (r SceneRef) Update() error { return r.scene.Update() }
|
func (r SceneRef) Update() error { return r.scene.Update() }
|
||||||
|
|
Loading…
Reference in a new issue