more transforms; fix first update-ordering crash :-)
This commit is contained in:
parent
400552e742
commit
6155e64c60
10 changed files with 58 additions and 31 deletions
BIN
cpuprofile.pprof
BIN
cpuprofile.pprof
Binary file not shown.
|
@ -16,6 +16,7 @@ type AnimFrame struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Anim is n animation being displayed, together with the current state.
|
// Anim is n animation being displayed, together with the current state.
|
||||||
|
// A nil *Anim can be used, but always returns 0 for the current frame.
|
||||||
type Anim struct {
|
type Anim struct {
|
||||||
Frames []AnimFrame
|
Frames []AnimFrame
|
||||||
OneShot bool
|
OneShot bool
|
||||||
|
@ -25,18 +26,34 @@ type Anim struct {
|
||||||
|
|
||||||
// Copy makes a shallow copy of the anim.
|
// Copy makes a shallow copy of the anim.
|
||||||
func (a *Anim) Copy() *Anim {
|
func (a *Anim) Copy() *Anim {
|
||||||
|
if a == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
a2 := *a
|
a2 := *a
|
||||||
return &a2
|
return &a2
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentFrame returns the frame number for the current index.
|
// CurrentFrame returns the frame number for the current index.
|
||||||
func (a *Anim) CurrentFrame() int { return a.Frames[a.Index].Frame }
|
func (a *Anim) CurrentFrame() int {
|
||||||
|
if a == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return a.Frames[a.Index].Frame
|
||||||
|
}
|
||||||
|
|
||||||
// Reset resets both Index and Ticks to 0.
|
// Reset resets both Index and Ticks to 0.
|
||||||
func (a *Anim) Reset() { a.Index, a.Ticks = 0, 0 }
|
func (a *Anim) Reset() {
|
||||||
|
if a == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
a.Index, a.Ticks = 0, 0
|
||||||
|
}
|
||||||
|
|
||||||
// Update increments the tick count and advances the frame if necessary.
|
// Update increments the tick count and advances the frame if necessary.
|
||||||
func (a *Anim) Update() error {
|
func (a *Anim) Update() error {
|
||||||
|
if a == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
a.Ticks++
|
a.Ticks++
|
||||||
if a.OneShot && a.Index == len(a.Frames)-1 {
|
if a.OneShot && a.Index == len(a.Frames)-1 {
|
||||||
// on the last frame of a one shot so remain on final frame
|
// on the last frame of a one shot so remain on final frame
|
||||||
|
|
|
@ -30,13 +30,14 @@ type Billboard struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw draws the image.
|
// Draw draws the image.
|
||||||
func (b *Billboard) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
func (b *Billboard) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
|
||||||
var geom ebiten.GeoM
|
screen.DrawImage(b.Src.Image(), opts)
|
||||||
geom.Translate(float64(b.Pos.X), float64(b.Pos.Y))
|
|
||||||
geom.Concat(opts.GeoM)
|
|
||||||
opts.GeoM = geom
|
|
||||||
screen.DrawImage(b.Src.Image(), &opts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan returns a slice containing Src.
|
// Scan returns a slice containing Src.
|
||||||
func (b *Billboard) Scan() []interface{} { return []interface{}{&b.Src} }
|
func (b *Billboard) Scan() []interface{} { return []interface{}{&b.Src} }
|
||||||
|
|
||||||
|
func (b *Billboard) Transform() (opts ebiten.DrawImageOptions) {
|
||||||
|
opts.GeoM.Translate(float2(b.Pos))
|
||||||
|
return opts
|
||||||
|
}
|
||||||
|
|
|
@ -10,12 +10,21 @@ import (
|
||||||
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
|
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ interface {
|
var (
|
||||||
Drawer
|
_ interface {
|
||||||
Hider
|
Drawer
|
||||||
} = &PerfDisplay{}
|
Hider
|
||||||
|
} = &PerfDisplay{}
|
||||||
|
|
||||||
|
_ interface {
|
||||||
|
Drawer
|
||||||
|
Hider
|
||||||
|
Updater
|
||||||
|
} = &DebugToast{}
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
gob.Register(&DebugToast{})
|
||||||
gob.Register(&PerfDisplay{})
|
gob.Register(&PerfDisplay{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +37,7 @@ type DebugToast struct {
|
||||||
Text string
|
Text string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DebugToast) Draw(screen *ebiten.Image, _ ebiten.DrawImageOptions) {
|
func (d *DebugToast) Draw(screen *ebiten.Image, _ *ebiten.DrawImageOptions) {
|
||||||
ebitenutil.DebugPrintAt(screen, d.Text, d.Pos.X, d.Pos.Y)
|
ebitenutil.DebugPrintAt(screen, d.Text, d.Pos.X, d.Pos.Y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +63,7 @@ type PerfDisplay struct {
|
||||||
Hidden
|
Hidden
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p PerfDisplay) Draw(screen *ebiten.Image, _ ebiten.DrawImageOptions) {
|
func (p PerfDisplay) Draw(screen *ebiten.Image, _ *ebiten.DrawImageOptions) {
|
||||||
ebitenutil.DebugPrint(screen, fmt.Sprintf("TPS: %0.2f FPS: %0.2f", ebiten.CurrentTPS(), ebiten.CurrentFPS()))
|
ebitenutil.DebugPrint(screen, fmt.Sprintf("TPS: %0.2f FPS: %0.2f", ebiten.CurrentTPS(), ebiten.CurrentFPS()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,6 @@ type Fill struct {
|
||||||
ZOrder
|
ZOrder
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Fill) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
func (f *Fill) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
|
||||||
screen.Fill(opts.ColorM.Apply(f.Color))
|
screen.Fill(opts.ColorM.Apply(f.Color))
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
||||||
if st.hidden {
|
if st.hidden {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
d.Draw(screen, st.opts)
|
d.Draw(screen, &st.opts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,7 +390,7 @@ var _ Drawer = tombstone{}
|
||||||
|
|
||||||
type tombstone struct{}
|
type tombstone struct{}
|
||||||
|
|
||||||
func (tombstone) Draw(*ebiten.Image, ebiten.DrawImageOptions) {}
|
func (tombstone) Draw(*ebiten.Image, *ebiten.DrawImageOptions) {}
|
||||||
|
|
||||||
func (tombstone) DrawOrder() float64 { return math.Inf(1) }
|
func (tombstone) DrawOrder() float64 { return math.Inf(1) }
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ type Disabler interface {
|
||||||
// must call Draw on any internal components not known to the engine (i.e. not
|
// must call Draw on any internal components not known to the engine (i.e. not
|
||||||
// passed to Game.Register or returned from Scan).
|
// passed to Game.Register or returned from Scan).
|
||||||
type Drawer interface {
|
type Drawer interface {
|
||||||
Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions)
|
Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions)
|
||||||
DrawOrder() float64
|
DrawOrder() float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,8 @@ type Sprite struct {
|
||||||
anim *Anim
|
anim *Anim
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sprite) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
func (s *Sprite) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
|
||||||
screen.DrawImage(s.Sheet.SubImage(s.anim.CurrentFrame()), &opts)
|
screen.DrawImage(s.Sheet.SubImage(s.anim.CurrentFrame()), opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sprite) Scan() []interface{} {
|
func (s *Sprite) Scan() []interface{} {
|
||||||
|
@ -53,5 +53,6 @@ func (s *Sprite) Transform() (opts ebiten.DrawImageOptions) {
|
||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|
||||||
// anim isn't returned from Scan so we must update it ourselves
|
// anim can change a bit so we don't tell Game about it, but that means it must
|
||||||
|
// be updated here.
|
||||||
func (s *Sprite) Update() error { return s.anim.Update() }
|
func (s *Sprite) Update() error { return s.anim.Update() }
|
||||||
|
|
|
@ -65,7 +65,7 @@ func (t *Tilemap) CollidesWith(r image.Rectangle) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw draws the tilemap.
|
// Draw draws the tilemap.
|
||||||
func (t *Tilemap) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
func (t *Tilemap) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
|
||||||
og := opts.GeoM
|
og := opts.GeoM
|
||||||
var geom ebiten.GeoM
|
var geom ebiten.GeoM
|
||||||
for p, tile := range t.Map {
|
for p, tile := range t.Map {
|
||||||
|
@ -78,7 +78,7 @@ func (t *Tilemap) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
||||||
opts.GeoM = geom
|
opts.GeoM = geom
|
||||||
|
|
||||||
src := t.Sheet.SubImage(tile.CellIndex())
|
src := t.Sheet.SubImage(tile.CellIndex())
|
||||||
screen.DrawImage(src, &opts)
|
screen.DrawImage(src, opts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,14 +78,8 @@ type WallUnit struct {
|
||||||
wall *Wall
|
wall *Wall
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *WallUnit) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
func (u *WallUnit) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
|
||||||
var geom ebiten.GeoM
|
screen.DrawImage(u.wall.Sheet.SubImage(u.Tile.CellIndex()), opts)
|
||||||
geom.Translate(float2(mul2(u.Pos, u.wall.UnitSize).Add(u.wall.UnitOffset).Add(u.wall.Offset)))
|
|
||||||
geom.Concat(opts.GeoM)
|
|
||||||
opts.GeoM = geom
|
|
||||||
|
|
||||||
src := u.wall.Sheet.SubImage(u.Tile.CellIndex())
|
|
||||||
screen.DrawImage(src, &opts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *WallUnit) Prepare(g *Game) error {
|
func (u *WallUnit) Prepare(g *Game) error {
|
||||||
|
@ -95,3 +89,8 @@ func (u *WallUnit) Prepare(g *Game) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *WallUnit) Scan() []interface{} { return []interface{}{u.Tile} }
|
func (u *WallUnit) Scan() []interface{} { return []interface{}{u.Tile} }
|
||||||
|
|
||||||
|
func (u *WallUnit) Transform() (opts ebiten.DrawImageOptions) {
|
||||||
|
opts.GeoM.Translate(float2(mul2(u.Pos, u.wall.UnitSize).Add(u.wall.UnitOffset).Add(u.wall.Offset)))
|
||||||
|
return opts
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue