big ol refactor
This commit is contained in:
102
types/player.go
102
types/player.go
@ -8,6 +8,66 @@ import (
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
// AnimationController manages animation state and updates
|
||||
type AnimationController struct {
|
||||
animations AnimationSet
|
||||
currentAnimation string // "idle" or "walk"
|
||||
frame int32
|
||||
lastUpdate time.Time
|
||||
frameCount int32
|
||||
}
|
||||
|
||||
// NewAnimationController creates a new animation controller
|
||||
func NewAnimationController(animations AnimationSet) *AnimationController {
|
||||
return &AnimationController{
|
||||
animations: animations,
|
||||
currentAnimation: "idle",
|
||||
frame: 0,
|
||||
lastUpdate: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
// Update updates the animation state based on movement
|
||||
func (ac *AnimationController) Update(deltaTime float32, isMoving bool) {
|
||||
// Set the current animation based on movement
|
||||
newAnimation := "idle"
|
||||
if isMoving {
|
||||
newAnimation = "walk"
|
||||
}
|
||||
|
||||
// Reset frame counter when animation changes
|
||||
if ac.currentAnimation != newAnimation {
|
||||
ac.frame = 0
|
||||
ac.currentAnimation = newAnimation
|
||||
}
|
||||
|
||||
// Update the frame
|
||||
ac.frame += int32(deltaTime * 60)
|
||||
|
||||
// Determine which animation set to use
|
||||
var frames []rl.ModelAnimation
|
||||
if ac.currentAnimation == "walk" && len(ac.animations.Walk) > 0 {
|
||||
frames = ac.animations.Walk
|
||||
} else if len(ac.animations.Idle) > 0 {
|
||||
frames = ac.animations.Idle
|
||||
}
|
||||
|
||||
// If we have frames, ensure we loop properly
|
||||
if len(frames) > 0 && frames[0].FrameCount > 0 {
|
||||
ac.frame = ac.frame % frames[0].FrameCount
|
||||
}
|
||||
}
|
||||
|
||||
// GetAnimFrame returns the current animation frame
|
||||
func (ac *AnimationController) GetAnimFrame() int32 {
|
||||
return ac.frame
|
||||
}
|
||||
|
||||
// GetCurrentAnimation returns the current animation type
|
||||
func (ac *AnimationController) GetCurrentAnimation() string {
|
||||
return ac.currentAnimation
|
||||
}
|
||||
|
||||
type Player struct {
|
||||
sync.RWMutex // Keep this for network operations
|
||||
Model rl.Model
|
||||
@ -28,6 +88,7 @@ type Player struct {
|
||||
LastUpdateTime time.Time
|
||||
InterpolationProgress float32
|
||||
PlaceholderColor rl.Color
|
||||
AnimController *AnimationController
|
||||
}
|
||||
|
||||
func (p *Player) MoveTowards(target Tile, deltaTime float32, mapGrid [][]Tile) {
|
||||
@ -42,29 +103,29 @@ func (p *Player) MoveTowards(target Tile, deltaTime float32, mapGrid [][]Tile) {
|
||||
distance := rl.Vector3Length(direction)
|
||||
|
||||
if distance > 1.0 {
|
||||
wasMoving := p.IsMoving
|
||||
p.IsMoving = true
|
||||
|
||||
if !wasMoving {
|
||||
p.AnimationFrame = 0
|
||||
}
|
||||
|
||||
oldFrame := p.AnimationFrame
|
||||
p.AnimationFrame += int32(deltaTime * 60)
|
||||
rl.TraceLog(rl.LogDebug, "Walk frame update: %d -> %d (delta: %f)",
|
||||
oldFrame, p.AnimationFrame, deltaTime)
|
||||
} else {
|
||||
wasMoving := p.IsMoving
|
||||
p.IsMoving = false
|
||||
}
|
||||
|
||||
if wasMoving {
|
||||
p.AnimationFrame = 0
|
||||
// Update animation if controller exists
|
||||
if p.AnimController != nil {
|
||||
p.AnimController.Update(deltaTime, p.IsMoving)
|
||||
p.AnimationFrame = p.AnimController.GetAnimFrame()
|
||||
} else {
|
||||
// Legacy animation update for backward compatibility
|
||||
if p.IsMoving {
|
||||
if !p.IsMoving {
|
||||
p.AnimationFrame = 0
|
||||
}
|
||||
p.AnimationFrame += int32(deltaTime * 60)
|
||||
} else {
|
||||
wasMoving := p.IsMoving
|
||||
if wasMoving {
|
||||
p.AnimationFrame = 0
|
||||
}
|
||||
p.AnimationFrame += int32(deltaTime * 60)
|
||||
}
|
||||
|
||||
oldFrame := p.AnimationFrame
|
||||
p.AnimationFrame += int32(deltaTime * 60)
|
||||
rl.TraceLog(rl.LogDebug, "Idle frame update: %d -> %d (delta: %f)",
|
||||
oldFrame, p.AnimationFrame, deltaTime)
|
||||
}
|
||||
|
||||
if distance > 0 {
|
||||
@ -100,6 +161,11 @@ func NewPlayer(state *pb.PlayerState) *Player {
|
||||
}
|
||||
}
|
||||
|
||||
// InitializeAnimations sets up the animation controller for the player
|
||||
func (p *Player) InitializeAnimations(animations AnimationSet) {
|
||||
p.AnimController = NewAnimationController(animations)
|
||||
}
|
||||
|
||||
func (p *Player) UpdatePosition(state *pb.PlayerState, tickRate time.Duration) {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
|
@ -59,3 +59,12 @@ const (
|
||||
ClientTickRate = 50 * time.Millisecond
|
||||
MaxTickDesync = 5
|
||||
)
|
||||
|
||||
// UI constants
|
||||
const (
|
||||
ChatMargin = 10
|
||||
ChatHeight = 200
|
||||
MessageHeight = 20
|
||||
InputHeight = 30
|
||||
MaxChatMessages = 50
|
||||
)
|
||||
|
Reference in New Issue
Block a user