99 lines
2 KiB
Go
99 lines
2 KiB
Go
package gg
|
|
|
|
import (
|
|
"github.com/hajimehoshi/ebiten/v2"
|
|
//"fmt"
|
|
)
|
|
|
|
type Animation []*Image
|
|
|
|
type AnimationDefine struct{
|
|
Id AnimationId
|
|
Indexes []ImageRectIndex
|
|
}
|
|
// Animation define
|
|
func AD(id AnimationId, indexes ...ImageRectIndex) AnimationDefine {
|
|
return AnimationDefine{
|
|
Id: id,
|
|
Indexes: indexes,
|
|
}
|
|
}
|
|
func (ad AnimationDefine) DefRow(y int, xs ...int) AnimationDefine {
|
|
for _, x := range xs {
|
|
ad.Indexes = append(ad.Indexes, ImageRectIndex{x, y})
|
|
}
|
|
return ad
|
|
}
|
|
|
|
func (ad AnimationDefine) DefCol(x int, ys ...int) AnimationDefine {
|
|
for _, y := range ys {
|
|
ad.Indexes = append(ad.Indexes, ImageRectIndex{x, y})
|
|
}
|
|
return ad
|
|
}
|
|
|
|
type AnimationId int
|
|
type AnimationSet map[AnimationId] Animation
|
|
func AnimationSetFromImage(
|
|
img *Image,
|
|
w, h int,
|
|
defines ...AnimationDefine,
|
|
) (AnimationSet, error) {
|
|
set := AnimationSet{}
|
|
|
|
r := img.Bounds()
|
|
fw, fh := r.Dx()/w, r.Dy()/h
|
|
|
|
for _, define := range defines {
|
|
animation := make(Animation, len(define.Indexes))
|
|
for i := range animation {
|
|
idx := define.Indexes[i]
|
|
animation[i] = ebiten.NewImageFromImage(img.SubImage(
|
|
ImageRect{
|
|
Min: ImagePoint{idx.X*fw, idx.Y*fh},
|
|
Max: ImagePoint{(idx.X+1)*fw, (idx.Y+1)*fh},
|
|
},
|
|
))
|
|
}
|
|
set[define.Id] = animation
|
|
}
|
|
|
|
return set, nil
|
|
}
|
|
|
|
// The type implements animated sprites.
|
|
type AnimatedSprite struct {
|
|
Sprite
|
|
Animations AnimationSet
|
|
AnimationId AnimationId
|
|
CurrentFrame int
|
|
// This is time between animation frames, not
|
|
// engine ones.
|
|
TimeBetweenFrames Duration
|
|
duration Duration
|
|
}
|
|
|
|
func (as *AnimatedSprite) Animate(id AnimationId) bool {
|
|
if as.AnimationId == id {
|
|
return true
|
|
}
|
|
_, ok := as.Animations[id]
|
|
if ok {
|
|
as.duration = 0
|
|
as.AnimationId = id
|
|
}
|
|
return ok
|
|
}
|
|
|
|
func (as *AnimatedSprite) Draw(c *Context) []EVertex {
|
|
as.duration += c.DrawDt()
|
|
frames := as.Animations[as.AnimationId]
|
|
fullTime := Duration(len(frames)) * as.TimeBetweenFrames
|
|
if as.duration > fullTime {
|
|
as.duration -= fullTime
|
|
}
|
|
as.Images[0] = frames[(as.duration/as.TimeBetweenFrames)%Duration(len(frames))]
|
|
|
|
return as.Sprite.Draw(c)
|
|
}
|
|
|