2021-08-26 11:31:39 +10:00
|
|
|
package engine
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/gob"
|
2021-09-17 11:13:39 +10:00
|
|
|
"fmt"
|
2021-08-26 11:31:39 +10:00
|
|
|
|
2021-09-08 20:08:57 +10:00
|
|
|
"drjosh.dev/gurgle/geom"
|
2021-08-26 11:31:39 +10:00
|
|
|
"github.com/hajimehoshi/ebiten/v2"
|
|
|
|
)
|
|
|
|
|
2021-08-26 11:33:58 +10:00
|
|
|
// Ensure Billboard satisfies interfaces.
|
2021-08-27 11:49:11 +10:00
|
|
|
var _ interface {
|
2021-09-15 11:42:07 +10:00
|
|
|
BoundingBoxer
|
2021-08-27 11:49:11 +10:00
|
|
|
Identifier
|
|
|
|
Drawer
|
|
|
|
Scanner
|
2021-09-01 09:52:40 +10:00
|
|
|
Transformer
|
2021-08-27 11:49:11 +10:00
|
|
|
} = &Billboard{}
|
2021-08-26 11:31:39 +10:00
|
|
|
|
|
|
|
func init() {
|
|
|
|
gob.Register(&Billboard{})
|
|
|
|
}
|
|
|
|
|
|
|
|
// Billboard draws an image at a position.
|
|
|
|
type Billboard struct {
|
|
|
|
ID
|
2021-09-13 16:50:35 +10:00
|
|
|
Hides
|
2021-09-15 11:42:07 +10:00
|
|
|
Pos geom.Int3
|
2021-08-26 11:31:39 +10:00
|
|
|
Src ImageRef
|
2021-09-15 11:42:07 +10:00
|
|
|
|
|
|
|
game *Game
|
|
|
|
}
|
|
|
|
|
|
|
|
// BoundingBox returns a 0-depth box incorporating the image size.
|
|
|
|
func (b *Billboard) BoundingBox() geom.Box {
|
|
|
|
sx, sy := b.Src.Image().Size()
|
|
|
|
return geom.Box{
|
|
|
|
Min: b.Pos,
|
|
|
|
Max: b.Pos.Add(geom.Pt3(sx, sy, 0)),
|
|
|
|
}
|
2021-08-26 11:31:39 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// Draw draws the image.
|
2021-09-01 09:48:01 +10:00
|
|
|
func (b *Billboard) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
|
|
|
|
screen.DrawImage(b.Src.Image(), opts)
|
2021-08-26 11:31:39 +10:00
|
|
|
}
|
|
|
|
|
2021-09-15 11:42:07 +10:00
|
|
|
// DrawAfter reports if b.Pos.Z >= x.Max.Z.
|
|
|
|
func (b *Billboard) DrawAfter(x Drawer) bool {
|
|
|
|
switch x := x.(type) {
|
|
|
|
case BoundingBoxer:
|
|
|
|
return b.Pos.Z >= x.BoundingBox().Max.Z
|
|
|
|
case ZPositioner:
|
|
|
|
return b.Pos.Z > x.ZPos()
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// DrawBefore reports if b.Pos.Z < x.Min.Z.
|
|
|
|
func (b *Billboard) DrawBefore(x Drawer) bool {
|
|
|
|
switch x := x.(type) {
|
|
|
|
case BoundingBoxer:
|
|
|
|
return b.Pos.Z < x.BoundingBox().Min.Z
|
|
|
|
case ZPositioner:
|
|
|
|
return b.Pos.Z < x.ZPos()
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// Prepare saves the reference to Game.
|
|
|
|
func (b *Billboard) Prepare(g *Game) error {
|
|
|
|
b.game = g
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-08-26 11:31:39 +10:00
|
|
|
// Scan returns a slice containing Src.
|
|
|
|
func (b *Billboard) Scan() []interface{} { return []interface{}{&b.Src} }
|
2021-09-01 09:48:01 +10:00
|
|
|
|
2021-09-17 11:13:39 +10:00
|
|
|
func (b *Billboard) String() string {
|
|
|
|
return fmt.Sprintf("Billboard@%v", b.Pos)
|
|
|
|
}
|
|
|
|
|
2021-09-15 11:42:07 +10:00
|
|
|
// Transform returns a translation by the projected position.
|
2021-09-07 14:00:50 +10:00
|
|
|
func (b *Billboard) Transform() (opts ebiten.DrawImageOptions) {
|
2021-09-15 11:42:07 +10:00
|
|
|
opts.GeoM.Translate(geom.CFloat(
|
|
|
|
b.game.Projection.Project(b.Pos),
|
|
|
|
))
|
2021-09-07 14:00:50 +10:00
|
|
|
return opts
|
2021-09-01 09:48:01 +10:00
|
|
|
}
|