package sprites import ( "image" "git.vezzani.net/ben/games/common/ux/v1" "github.com/hajimehoshi/ebiten/v2" ) var ( updateCount int ) func Update() { updateCount++ } type animation struct { RowNumber uint8 FrameCount uint8 Scale float32 } type subImager interface { image.Image SubImage(r image.Rectangle) image.Image } type Sprite struct { width, height int imgData subImager animations map[string]animation baseAnim *animation } func (s *Sprite) baseAnimation() animation { if s.baseAnim != nil { return *s.baseAnim } for i := range s.animations { if s.animations[i].RowNumber == 0 { a := s.animations[i] s.baseAnim = &a return a } } return animation{} } func (s *Sprite) getAnimation(id string) animation { if id == "" { return s.baseAnimation() } if anim, ok := s.animations[id]; ok { return anim } return s.baseAnimation() } func (s *Sprite) Image(ops imageOptions) image.Image { anim := s.getAnimation(ops.animation) xOffset := updateCount % int(anim.FrameCount) * s.width yOffset := int(anim.RowNumber) * s.height r := image.Rect(xOffset, yOffset, s.width, s.height).Intersect(s.imgData.Bounds()) return s.imgData.SubImage(r) } func (s *Sprite) Draw(screen *ebiten.Image, options ...ImageOption) { ops := imageOptions{ scaleX: ux.Scale, scaleY: ux.Scale, } for _, o := range options { o(&ops) } geom := ebiten.GeoM{} geom.Translate(ops.x, ops.y) geom.Scale(ops.scaleX, ops.scaleY) geom.Rotate(ops.rotateTheta) screen.DrawImage( ebiten.NewImageFromImage( s.Image(ops), ), &ebiten.DrawImageOptions{ GeoM: geom, }, ) } type imageOptions struct { x, y float64 scaleX, scaleY float64 rotateTheta float64 animation string } type ImageOption func(options *imageOptions) func ToScale(x, y float64) ImageOption { return func(o *imageOptions) { o.scaleX *= x o.scaleY *= y } } func Animation(name string) ImageOption { return func(o *imageOptions) { o.animation = name } } func AtPosition(x, y float64) ImageOption { return func(o *imageOptions) { o.x, o.y = x, y } } func Rotate(theta float64) ImageOption { return func(o *imageOptions) { o.rotateTheta = theta } }