project-ely/internal/sprite/sprite_animation.go

117 lines
2.2 KiB
Go

package sprite
import (
"fmt"
rl "github.com/gen2brain/raylib-go/raylib"
)
// spriteAnimation specifies which subsections of a spritesheet define this animation.
// For example, walking to the right could be defined by 4 subsections of a sprite sheet.
type spriteAnimation struct {
spritesheet *spritesheet
dimensions rl.Vector2
offset rl.Vector2
length int
border int
}
func NewAnimation(
filename string,
dimensions rl.Vector2,
offset rl.Vector2,
length int,
border int,
) spriteAnimation {
spritesheet := GetSpritesheet(filename)
return spriteAnimation{
spritesheet: spritesheet,
dimensions: dimensions,
offset: offset,
length: length,
border: border,
}
}
func (a spriteAnimation) Draw(
frame int,
windowPosition rl.Vector2,
angle float32,
center rl.Vector2,
flip rl.Vector2,
color rl.Color,
) error {
width := a.dimensions.X
height := a.dimensions.Y
border := float32(a.border)
base := rl.Vector2{
X: (width+border)*a.offset.X + border,
Y: (height+border)*a.offset.Y + border,
}
// Assuming all frames are horizontal going left to right.
// Potentially with a border offset as well.
f := float32(frame % a.length)
section := rl.Rectangle{
X: base.X + f*(width+border),
Y: base.Y,
Width: width,
Height: height,
}
if flip.X > 0 {
section.Width *= -1
}
if flip.Y > 0 {
section.Height *= -1
}
err := a.checkBounds(section)
if err != nil {
return err
}
placement := rl.Rectangle{
X: windowPosition.X,
Y: windowPosition.Y,
Width: width * 2,
Height: height * 2,
}
err = a.spritesheet.Draw(section, placement, angle, center, color)
if err != nil {
return err
}
return nil
}
func (a spriteAnimation) checkBounds(section rl.Rectangle) error {
width := float32(a.spritesheet.texture.Width)
height := float32(a.spritesheet.texture.Height)
outOfBounds := false
if section.X < 0 {
outOfBounds = true
}
if section.Y < 0 {
outOfBounds = true
}
if section.X+section.Width > width {
outOfBounds = true
}
if section.Y+section.Height > height {
outOfBounds = true
}
if outOfBounds {
return fmt.Errorf("draw section was out of bounds - section: %v, image: %v", section, a.spritesheet.Bounds())
}
return nil
}