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 }