- Two-timer architecture: game timer + 60fps render timer for smooth interpolation - Snake body: StreamGeometry path with teal gradient, rounded joins - Directional head with white eyes and dark pupils - Food: pulsating glow, highlight, green leaf animation - Modern dark theme (#0D1117), glassmorphism HUD - Speed indicator bar, score +N popup - High score persistence to JSON - All keyboard shortcuts: Arrows, WASD, Space/P pause, Enter start, R restart, Esc quit - Window resizable, 640x540 default New files: AnimationHelper.cs, HighScoreManager.cs, SnakeRenderer.cs
59 lines
1.4 KiB
C#
59 lines
1.4 KiB
C#
using System.Text.Json;
|
|
|
|
namespace Snake.Avalonia.Views;
|
|
|
|
/// <summary>
|
|
/// Persists high score to a JSON file in the user's local app data.
|
|
/// </summary>
|
|
public static class HighScoreManager
|
|
{
|
|
private static readonly string FilePath;
|
|
|
|
static HighScoreManager()
|
|
{
|
|
var appData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
|
var dir = Path.Combine(appData, "SnakeAvalonia");
|
|
Directory.CreateDirectory(dir);
|
|
FilePath = Path.Combine(dir, "highscore.json");
|
|
}
|
|
|
|
public static int Load()
|
|
{
|
|
try
|
|
{
|
|
if (File.Exists(FilePath))
|
|
{
|
|
var json = File.ReadAllText(FilePath);
|
|
var data = JsonSerializer.Deserialize<HighScoreData>(json);
|
|
return data?.Score ?? 0;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// Corrupted file — reset
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
public static void Save(int score)
|
|
{
|
|
try
|
|
{
|
|
var data = new HighScoreData { Score = score, Date = DateTime.UtcNow.ToString("O") };
|
|
var json = JsonSerializer.Serialize(data);
|
|
File.WriteAllText(FilePath, json);
|
|
}
|
|
catch
|
|
{
|
|
// Silently fail — high score is non-critical
|
|
}
|
|
}
|
|
|
|
private sealed class HighScoreData
|
|
{
|
|
public int Score { get; set; }
|
|
public string Date { get; set; } = string.Empty;
|
|
}
|
|
}
|