167 lines
3.7 KiB
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
|
|
}
|