diff --git a/Snake.Avalonia/Views/SnakeRenderer.cs b/Snake.Avalonia/Views/SnakeRenderer.cs index 934004a..1a09eb4 100644 --- a/Snake.Avalonia/Views/SnakeRenderer.cs +++ b/Snake.Avalonia/Views/SnakeRenderer.cs @@ -373,22 +373,18 @@ public sealed class SnakeRenderer : Control private (double X, double Y) GetVisualPosition(Position pos, int segmentIndex, double t) { - if (Segments == null) - return (pos.X * CellSize + CellSize * 0.5, pos.Y * CellSize + CellSize * 0.5); - - var isHead = segmentIndex == 0; - var isTail = Segments.Count > 1 && segmentIndex == Segments.Count - 1; - - // Only interpolate head and tail — middle segments stay grid-snapped + // Only interpolate the head — all other segments stay grid-snapped // to preserve sharp corners when the snake bends. - if (!isHead && !isTail) + // Interpolating the tail creates diagonal shortcuts at corners because + // the tail position drifts while the adjacent segment is already at its + // new grid position. + if (segmentIndex != 0) return (pos.X * CellSize + CellSize * 0.5, pos.Y * CellSize + CellSize * 0.5); var from = PreviousSegments != null && PreviousSegments.Count > 0 - ? AnimationHelper.GetPreviousPosition(segmentIndex, Segments, PreviousSegments, SnakeDirection) + ? AnimationHelper.GetPreviousPosition(0, Segments!, PreviousSegments, SnakeDirection) : pos; - // Head gets easing for snappy feel; tail uses linear interpolation - return AnimationHelper.InterpolatePosition(from, pos, t, CellSize, useEasing: isHead); + return AnimationHelper.InterpolatePosition(from, pos, t, CellSize, useEasing: true); } }