ichigo/engine/anim.go

80 lines
1.6 KiB
Go
Raw Normal View History

2021-07-31 17:15:32 +10:00
package engine
2021-08-25 15:04:38 +10:00
import "encoding/gob"
2021-08-23 20:28:49 +10:00
// Ensure Anim satisfies Animer.
2021-09-02 11:53:04 +10:00
var _ interface {
Cell() int
Reset()
Updater
} = &Anim{}
2021-08-23 20:28:49 +10:00
2021-08-25 15:04:38 +10:00
func init() {
gob.Register(&Anim{})
}
2021-09-02 11:53:04 +10:00
// AnimDef defines an animation, as a sequence of steps and other information.
type AnimDef struct {
Steps []AnimStep
2021-08-23 20:28:49 +10:00
OneShot bool
}
2021-09-02 11:53:04 +10:00
// NewAnim spawns a new anim using this def, or nil if d is nil.
func (d *AnimDef) NewAnim() *Anim {
if d == nil {
return nil
}
2021-09-02 11:53:04 +10:00
return &Anim{Def: d}
}
// AnimStep describes a step in an animation.
type AnimStep struct {
Cell int // show this cell
Duration int // for this long, in ticks
}
// Anim is the current state of an animation being played (think of it as an
// instance of an AnimDef). nil *Anim can be used, but always returns 0 for the
// current frame.
type Anim struct {
Def *AnimDef
Index int // current step index
Ticks int // ticks spent at this step
2021-07-31 17:15:32 +10:00
}
2021-09-02 11:53:04 +10:00
// Cell returns the cell index for the current step.
func (a *Anim) Cell() int {
if a == nil {
return 0
}
2021-09-02 11:53:04 +10:00
return a.Def.Steps[a.Index].Cell
}
2021-07-31 17:15:32 +10:00
2021-08-23 20:28:49 +10:00
// Reset resets both Index and Ticks to 0.
func (a *Anim) Reset() {
if a == nil {
return
}
a.Index, a.Ticks = 0, 0
}
2021-08-05 15:24:16 +10:00
2021-07-31 17:15:32 +10:00
// Update increments the tick count and advances the frame if necessary.
func (a *Anim) Update() error {
if a == nil {
return nil
}
2021-07-31 17:17:26 +10:00
a.Ticks++
2021-09-02 11:53:04 +10:00
if a.Def.OneShot && a.Index == len(a.Def.Steps)-1 {
2021-07-31 17:15:32 +10:00
// on the last frame of a one shot so remain on final frame
return nil
}
2021-09-02 11:53:04 +10:00
if a.Ticks >= a.Def.Steps[a.Index].Duration {
2021-07-31 17:17:26 +10:00
a.Ticks = 0
a.Index++
2021-07-31 17:15:32 +10:00
}
2021-09-02 11:53:04 +10:00
if !a.Def.OneShot && a.Index >= len(a.Def.Steps) {
2021-07-31 17:17:26 +10:00
a.Index = 0
2021-07-31 17:15:32 +10:00
}
return nil
}