79 lines
1.6 KiB
Go
79 lines
1.6 KiB
Go
package engine
|
|
|
|
import "encoding/gob"
|
|
|
|
// Ensure Anim satisfies Animer.
|
|
var _ interface {
|
|
Cell() int
|
|
Reset()
|
|
Updater
|
|
} = &Anim{}
|
|
|
|
func init() {
|
|
gob.Register(&Anim{})
|
|
}
|
|
|
|
// AnimDef defines an animation, as a sequence of steps and other information.
|
|
type AnimDef struct {
|
|
Steps []AnimStep
|
|
OneShot bool
|
|
}
|
|
|
|
// NewAnim spawns a new anim using this def, or nil if d is nil.
|
|
func (d *AnimDef) NewAnim() *Anim {
|
|
if d == nil {
|
|
return nil
|
|
}
|
|
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
|
|
}
|
|
|
|
// Cell returns the cell index for the current step.
|
|
func (a *Anim) Cell() int {
|
|
if a == nil {
|
|
return 0
|
|
}
|
|
return a.Def.Steps[a.Index].Cell
|
|
}
|
|
|
|
// Reset resets both Index and Ticks to 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.
|
|
func (a *Anim) Update() error {
|
|
if a == nil {
|
|
return nil
|
|
}
|
|
a.Ticks++
|
|
if a.Def.OneShot && a.Index == len(a.Def.Steps)-1 {
|
|
// on the last frame of a one shot so remain on final frame
|
|
return nil
|
|
}
|
|
if a.Ticks >= a.Def.Steps[a.Index].Duration {
|
|
a.Ticks = 0
|
|
a.Index++
|
|
}
|
|
if !a.Def.OneShot && a.Index >= len(a.Def.Steps) {
|
|
a.Index = 0
|
|
}
|
|
return nil
|
|
}
|