project-ely/internal/game/entity/types/penguin.go

167 lines
3.7 KiB
Go

package types
import (
"log"
"math"
"sync"
"git.wisellama.rocks/Project-Ely/project-ely/internal/game/entity/animation"
rl "github.com/gen2brain/raylib-go/raylib"
)
type penguin struct {
mx sync.RWMutex
// Animation parameters
currentAnimation EntityAnimation // pointer to current animation loop
animationStep int // index of animation loop
direction int // direction facing for sprite animations
updateAnimation bool // if false, don't change the animation
// Physical parameters
worldPosition rl.Vector2 // where is the center of this object
velocity rl.Vector2 // movement direction to be applied each tick
speed float32 // movement magnitude to multiply with the velocity
}
func NewPenguin() penguin {
position := rl.Vector2{}
velocity := rl.Vector2{}
speed := float32(1)
return penguin{
currentAnimation: animation.PenguinAnimations[animation.PENGUIN_DEFAULT],
animationStep: 0,
direction: DIR_RIGHT,
worldPosition: position,
speed: speed,
velocity: velocity,
}
}
func (p *penguin) Draw() error {
step := p.animationStep / p.currentAnimation.GetSpeed()
// TODO
//windowPosition := worldPosToWindowPos()
windowPosition := rl.Vector2{
X: float32(math.Round(float64(p.worldPosition.X))),
Y: float32(math.Round(float64(-1 * p.worldPosition.Y))),
}
err := p.currentAnimation.Draw(step, windowPosition, rl.White)
if err != nil {
return err
}
p.animationStep = 1 + p.animationStep
return nil
}
func (p *penguin) SetPosition(vec rl.Vector2) {
p.worldPosition = vec
}
func (p *penguin) SetDirection(dir int) {
p.direction = dir
}
func (p *penguin) SetAnimation(id int) {
a, exists := animation.PenguinAnimations[id]
if !exists {
log.Printf("animation does not exist: %v", id)
a = animation.PenguinAnimations[animation.PENGUIN_DEFAULT]
}
if a != p.currentAnimation {
p.animationStep = 0
}
p.currentAnimation = a
}
func (p *penguin) MoveX(x float32) {
p.mx.Lock()
defer p.mx.Unlock()
p.velocity.X = x
if p.velocity.X != 0 || p.velocity.Y != 0 {
p.velocity = rl.Vector2Normalize(p.velocity)
}
p.updateAnimation = true
}
func (p *penguin) MoveY(y float32) {
p.mx.Lock()
defer p.mx.Unlock()
p.velocity.Y = y
if p.velocity.X != 0 || p.velocity.Y != 0 {
p.velocity = rl.Vector2Normalize(p.velocity)
}
p.updateAnimation = true
}
func (p *penguin) SetSpeed(s float32) {
p.speed = s
}
func (p *penguin) GetSpeed() float32 {
return p.speed
}
func (p *penguin) SetMoveAnimation() {
if p.velocity.X == 0 && p.velocity.Y == 0 {
// Stay facing whatever direction we were facing
switch p.direction {
case DIR_LEFT:
p.SetAnimation(animation.PENGUIN_STATIONARY_LEFT)
case DIR_RIGHT:
p.SetAnimation(animation.PENGUIN_STATIONARY_RIGHT)
case DIR_UP:
p.SetAnimation(animation.PENGUIN_STATIONARY_UP)
case DIR_DOWN:
p.SetAnimation(animation.PENGUIN_STATIONARY_DOWN)
default:
log.Printf("unknown direction: %v", p.direction)
p.SetAnimation(animation.PENGUIN_DEFAULT)
}
} else {
// Figure out which way we are facing now that we're moving
p.direction = determineClosestDirection(p.velocity)
switch p.direction {
case DIR_LEFT:
p.SetAnimation(animation.PENGUIN_WALK_LEFT)
case DIR_RIGHT:
p.SetAnimation(animation.PENGUIN_WALK_RIGHT)
case DIR_UP:
p.SetAnimation(animation.PENGUIN_WALK_UP)
case DIR_DOWN:
p.SetAnimation(animation.PENGUIN_WALK_DOWN)
default:
log.Printf("unknown direction: %v", p.direction)
p.SetAnimation(animation.PENGUIN_DEFAULT)
}
}
}
func (p *penguin) Update() error {
if p.updateAnimation {
p.SetMoveAnimation()
p.updateAnimation = false
}
x := p.velocity.X * p.speed
y := p.velocity.Y * p.speed
p.worldPosition.X += x
p.worldPosition.Y += y
return nil
}