fix: interpolate only head, pin all other segments to grid

Tail interpolation caused diagonal shortcuts at corners because
the interpolated tail position would drift while the adjacent
segment was already at its new grid position. By keeping only
the head interpolated, L-shaped bends render correctly.
This commit is contained in:
Heller
2026-06-19 10:14:51 +00:00
parent cb06980cfb
commit 4446bd778f

View File

@@ -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);
}
}