You can change animation directions!
parent
9de48f0bab
commit
46a1e33ae8
|
@ -0,0 +1,43 @@
|
|||
package entity
|
||||
|
||||
import "github.com/veandco/go-sdl2/sdl"
|
||||
|
||||
type SpriteAnimation interface {
|
||||
Draw(frame int32, worldPosition *sdl.Point, angle float64, center *sdl.Point, flip sdl.RendererFlip) error
|
||||
}
|
||||
|
||||
// An entityAnimation will take a SpriteAnimation and may manipulate it somehow (e.g. flipped for walking the other direction)
|
||||
// This way you may cut down the actual number of pictures needed to define all the different animations.
|
||||
type entityAnimation struct {
|
||||
spriteAnimation SpriteAnimation
|
||||
speed int32
|
||||
length int32
|
||||
angle float64
|
||||
center *sdl.Point
|
||||
flip sdl.RendererFlip
|
||||
}
|
||||
|
||||
func NewEntityAnimation(
|
||||
spriteAnimation SpriteAnimation,
|
||||
speed int32,
|
||||
length int32,
|
||||
angle float64,
|
||||
center *sdl.Point,
|
||||
flip sdl.RendererFlip,
|
||||
) *entityAnimation {
|
||||
|
||||
e := entityAnimation{
|
||||
spriteAnimation: spriteAnimation,
|
||||
speed: speed,
|
||||
length: length,
|
||||
angle: angle,
|
||||
center: center,
|
||||
flip: flip,
|
||||
}
|
||||
|
||||
return &e
|
||||
}
|
||||
|
||||
func (e *entityAnimation) Draw(frame int32, worldPosition *sdl.Point) error {
|
||||
return e.spriteAnimation.Draw(frame, worldPosition, e.angle, e.center, e.flip)
|
||||
}
|
|
@ -1,33 +1,40 @@
|
|||
package entity
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
)
|
||||
|
||||
type penguin struct {
|
||||
worldPosition *sdl.Point
|
||||
animationStep int32
|
||||
worldPosition *sdl.Point
|
||||
currentAnimation *entityAnimation
|
||||
animationStep int32
|
||||
facingRight bool
|
||||
}
|
||||
|
||||
func NewPenguin(renderer *sdl.Renderer) *penguin {
|
||||
position := sdl.Point{}
|
||||
|
||||
p := penguin{
|
||||
worldPosition: &position,
|
||||
worldPosition: &position,
|
||||
currentAnimation: penguinAnimations[PENGUIN_DEFAULT],
|
||||
animationStep: 0,
|
||||
facingRight: true,
|
||||
}
|
||||
|
||||
return &p
|
||||
}
|
||||
|
||||
func (p *penguin) Draw() error {
|
||||
a := penguinAnimations[PENGUIN_WALK_RIGHT]
|
||||
step := p.animationStep / 10
|
||||
err := a.Draw(step, p.worldPosition)
|
||||
step := p.animationStep / p.currentAnimation.speed
|
||||
|
||||
err := p.currentAnimation.Draw(step, p.worldPosition)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.animationStep += 1
|
||||
p.animationStep = 1 + p.animationStep
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -36,12 +43,31 @@ func (p *penguin) SetPosition(point *sdl.Point) {
|
|||
p.worldPosition = point
|
||||
}
|
||||
|
||||
func (p *penguin) SetAnimation(name string) {
|
||||
a, exists := penguinAnimations[name]
|
||||
|
||||
if !exists {
|
||||
log.Printf("animation does not exist: %v", name)
|
||||
a = penguinAnimations[PENGUIN_DEFAULT]
|
||||
}
|
||||
|
||||
if a != p.currentAnimation {
|
||||
p.animationStep = 0
|
||||
}
|
||||
|
||||
p.currentAnimation = a
|
||||
}
|
||||
|
||||
func (p *penguin) MoveRight() {
|
||||
p.worldPosition.X += 1
|
||||
p.SetAnimation(PENGUIN_WALK_RIGHT)
|
||||
p.facingRight = true
|
||||
}
|
||||
|
||||
func (p *penguin) MoveLeft() {
|
||||
p.worldPosition.X -= 1
|
||||
p.SetAnimation(PENGUIN_WALK_LEFT)
|
||||
p.facingRight = false
|
||||
}
|
||||
|
||||
func (p *penguin) MoveUp() {
|
||||
|
@ -53,3 +79,11 @@ func (p *penguin) MoveDown() {
|
|||
// positive y moves down
|
||||
p.worldPosition.Y += 1
|
||||
}
|
||||
|
||||
func (p *penguin) StopMove() {
|
||||
if p.facingRight {
|
||||
p.SetAnimation(PENGUIN_STATIONARY_RIGHT)
|
||||
} else {
|
||||
p.SetAnimation(PENGUIN_STATIONARY_LEFT)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,14 +5,15 @@ import (
|
|||
"github.com/veandco/go-sdl2/sdl"
|
||||
)
|
||||
|
||||
type Animation interface {
|
||||
Draw(frame int32, worldPosition *sdl.Point) error
|
||||
}
|
||||
|
||||
var penguinAnimations map[string]Animation
|
||||
var penguinAnimations map[string]*entityAnimation
|
||||
|
||||
const (
|
||||
PENGUIN_WALK_RIGHT = "walk-right"
|
||||
PENGUIN_WALK_RIGHT = "walk-right"
|
||||
PENGUIN_WALK_LEFT = "walk-left"
|
||||
PENGUIN_STATIONARY_RIGHT = "stationary-right"
|
||||
PENGUIN_STATIONARY_LEFT = "stationary-left"
|
||||
|
||||
PENGUIN_DEFAULT = PENGUIN_STATIONARY_RIGHT
|
||||
)
|
||||
|
||||
func DefinePenguinAnimations() {
|
||||
|
@ -21,13 +22,28 @@ func DefinePenguinAnimations() {
|
|||
var (
|
||||
dimensions sdl.Point
|
||||
offset sdl.Point
|
||||
center *sdl.Point
|
||||
length int32
|
||||
speed int32
|
||||
)
|
||||
|
||||
dimensions = sdl.Point{X: 32, Y: 32}
|
||||
penguinAnimations = make(map[string]Animation)
|
||||
penguinAnimations = make(map[string]*entityAnimation)
|
||||
|
||||
// Walking Right is in the spritesheet.
|
||||
speed = 10
|
||||
offset = sdl.Point{X: 0, Y: 2}
|
||||
length = 4
|
||||
penguinAnimations[PENGUIN_WALK_RIGHT] = sprite.NewAnimation(filename, dimensions, offset, length)
|
||||
center = nil // center is for rotation, nil will default to w/2 h/2
|
||||
walkRight := sprite.NewAnimation(filename, dimensions, offset, length)
|
||||
penguinAnimations[PENGUIN_WALK_RIGHT] = NewEntityAnimation(walkRight, speed, length, 0, center, sdl.FLIP_NONE)
|
||||
|
||||
// Walking Left is just that flipped.
|
||||
penguinAnimations[PENGUIN_WALK_LEFT] = NewEntityAnimation(walkRight, speed, length, 0, center, sdl.FLIP_HORIZONTAL)
|
||||
|
||||
// Stationary is just the first frame.
|
||||
length = 1
|
||||
stationaryRight := sprite.NewAnimation(filename, dimensions, offset, length)
|
||||
penguinAnimations[PENGUIN_STATIONARY_RIGHT] = NewEntityAnimation(stationaryRight, speed, length, 0, center, sdl.FLIP_NONE)
|
||||
penguinAnimations[PENGUIN_STATIONARY_LEFT] = NewEntityAnimation(stationaryRight, speed, length, 0, center, sdl.FLIP_HORIZONTAL)
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ import (
|
|||
"github.com/veandco/go-sdl2/sdl"
|
||||
)
|
||||
|
||||
// animation defines a specific for an entity that references a sequence of sections of a sprite sheet.
|
||||
// For example, walking to the left could be defined by 4 subsections of a sprite sheet.
|
||||
type animation struct {
|
||||
// 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
|
||||
|
@ -20,10 +20,10 @@ func NewAnimation(
|
|||
dimensions sdl.Point,
|
||||
offset sdl.Point,
|
||||
length int32,
|
||||
) *animation {
|
||||
) *spriteAnimation {
|
||||
spritesheet := GetSpritesheet(filename)
|
||||
|
||||
a := animation{
|
||||
a := spriteAnimation{
|
||||
spritesheet: spritesheet,
|
||||
dimensions: dimensions,
|
||||
offset: offset,
|
||||
|
@ -33,7 +33,14 @@ func NewAnimation(
|
|||
return &a
|
||||
}
|
||||
|
||||
func (a *animation) Draw(frame int32, worldPosition *sdl.Point) error {
|
||||
func (a *spriteAnimation) Draw(
|
||||
frame int32,
|
||||
worldPosition *sdl.Point,
|
||||
angle float64,
|
||||
center *sdl.Point,
|
||||
flip sdl.RendererFlip,
|
||||
) error {
|
||||
|
||||
width := a.dimensions.X
|
||||
height := a.dimensions.Y
|
||||
|
||||
|
@ -64,7 +71,7 @@ func (a *animation) Draw(frame int32, worldPosition *sdl.Point) error {
|
|||
H: height,
|
||||
}
|
||||
|
||||
err = a.spritesheet.Draw(§ion, &placement)
|
||||
err = a.spritesheet.Draw(§ion, &placement, angle, center, flip)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -72,7 +79,7 @@ func (a *animation) Draw(frame int32, worldPosition *sdl.Point) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (a *animation) checkBounds(section *sdl.Rect) error {
|
||||
func (a *spriteAnimation) checkBounds(section *sdl.Rect) error {
|
||||
width := a.spritesheet.surface.W
|
||||
height := a.spritesheet.surface.H
|
||||
|
||||
|
|
|
@ -71,10 +71,17 @@ func (s *spritesheet) Cleanup() {
|
|||
}()
|
||||
}
|
||||
|
||||
func (s *spritesheet) Draw(section *sdl.Rect, placement *sdl.Rect) error {
|
||||
func (s *spritesheet) Draw(
|
||||
section *sdl.Rect,
|
||||
placement *sdl.Rect,
|
||||
angle float64,
|
||||
center *sdl.Point,
|
||||
flip sdl.RendererFlip,
|
||||
) error {
|
||||
|
||||
var err error
|
||||
sdl.Do(func() {
|
||||
err = s.renderer.Copy(s.texture, section, placement)
|
||||
err = s.renderer.CopyEx(s.texture, section, placement, angle, center, flip)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
14
main.go
14
main.go
|
@ -91,6 +91,7 @@ func run(configMap gosimpleconf.ConfigMap) error {
|
|||
penguin := entity.NewPenguin(renderer)
|
||||
p2 := entity.NewPenguin(renderer)
|
||||
p2.SetPosition(&sdl.Point{X: 100, Y: 100})
|
||||
p2.SetAnimation(entity.PENGUIN_WALK_LEFT)
|
||||
|
||||
keystates := make(map[sdl.Keycode]bool)
|
||||
|
||||
|
@ -123,19 +124,22 @@ func run(configMap gosimpleconf.ConfigMap) error {
|
|||
})
|
||||
}
|
||||
|
||||
if keystates[sdl.K_a] {
|
||||
penguin.MoveLeft()
|
||||
}
|
||||
if keystates[sdl.K_d] {
|
||||
penguin.MoveRight()
|
||||
} else if keystates[sdl.K_a] {
|
||||
penguin.MoveLeft()
|
||||
}
|
||||
|
||||
if keystates[sdl.K_w] {
|
||||
penguin.MoveUp()
|
||||
}
|
||||
if keystates[sdl.K_s] {
|
||||
} else if keystates[sdl.K_s] {
|
||||
penguin.MoveDown()
|
||||
}
|
||||
|
||||
if !keystates[sdl.K_a] && !keystates[sdl.K_d] && !keystates[sdl.K_w] && !keystates[sdl.K_s] {
|
||||
penguin.StopMove()
|
||||
}
|
||||
|
||||
// Background
|
||||
sdl.Do(func() {
|
||||
err = renderer.SetDrawColor(0, 120, 0, 255)
|
||||
|
|
Loading…
Reference in New Issue