109 lines
2.1 KiB
Go
109 lines
2.1 KiB
Go
package sprite
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/veandco/go-sdl2/sdl"
|
|
)
|
|
|
|
// 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 sdl.Point
|
|
offset sdl.Point
|
|
length int
|
|
border int
|
|
}
|
|
|
|
func NewAnimation(
|
|
filename string,
|
|
dimensions sdl.Point,
|
|
offset sdl.Point,
|
|
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 sdl.Point,
|
|
angle float64,
|
|
center sdl.Point,
|
|
flip sdl.RendererFlip,
|
|
) error {
|
|
|
|
width := a.dimensions.X
|
|
height := a.dimensions.Y
|
|
border := int32(a.border)
|
|
|
|
base := sdl.Point{
|
|
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 := int32(frame % a.length)
|
|
section := sdl.Rect{
|
|
X: base.X + f*(width+border),
|
|
Y: base.Y,
|
|
W: width,
|
|
H: height,
|
|
}
|
|
|
|
err := a.checkBounds(section)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
placement := sdl.Rect{
|
|
X: windowPosition.X,
|
|
Y: windowPosition.Y,
|
|
W: width * 2, // TODO just testing with x2, eventually scale based on screen size or something
|
|
H: height * 2,
|
|
}
|
|
|
|
err = a.spritesheet.Draw(section, placement, angle, center, flip)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (a spriteAnimation) checkBounds(section sdl.Rect) error {
|
|
width := a.spritesheet.surface.W
|
|
height := a.spritesheet.surface.H
|
|
|
|
outOfBounds := false
|
|
if section.X < 0 {
|
|
outOfBounds = true
|
|
}
|
|
if section.Y < 0 {
|
|
outOfBounds = true
|
|
}
|
|
if section.X+section.W > width {
|
|
outOfBounds = true
|
|
}
|
|
if section.Y+section.H > height {
|
|
outOfBounds = true
|
|
}
|
|
|
|
if outOfBounds {
|
|
return fmt.Errorf("draw section was out of bounds - section: %v, image: %v", section, a.spritesheet.surface.Bounds())
|
|
}
|
|
|
|
return nil
|
|
}
|