sprite stuff

This commit is contained in:
2025-08-25 11:56:44 -04:00
parent a7b3a6cd4a
commit f94f3b9448
2 changed files with 138 additions and 0 deletions

133
common/sprites/v1/sprite.go Normal file
View File

@@ -0,0 +1,133 @@
package sprites
import (
"image"
"git.vezzani.net/ben/games/common/window/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) int {
ops := imageOptions{
scaleX: window.Scale,
scaleY: window.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
}
}

View File

@@ -0,0 +1,5 @@
package window
var (
Scale float64 = 1.0
)