- 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
176 lines
7.8 KiB
XML
176 lines
7.8 KiB
XML
<UserControl xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:views="using:Snake.Avalonia.Views"
|
|
x:Class="Snake.Avalonia.Views.GameView"
|
|
Background="#0D1117"
|
|
Focusable="True">
|
|
|
|
<Grid RowDefinitions="Auto,*">
|
|
|
|
<!-- HUD Panel — glassmorphism top bar -->
|
|
<Border Grid.Row="0"
|
|
Background="#141C24"
|
|
BorderBrush="#1E3A3A"
|
|
BorderThickness="0,0,0,1"
|
|
Padding="16,10">
|
|
|
|
<Grid ColumnDefinitions="Auto,*,Auto,Auto,Auto">
|
|
|
|
<!-- Score -->
|
|
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="6">
|
|
<TextBlock Text="🍎" FontSize="16" VerticalAlignment="Center" />
|
|
<TextBlock x:Name="ScoreText"
|
|
FontSize="16"
|
|
FontWeight="Bold"
|
|
Foreground="#E6EDF3" />
|
|
</StackPanel>
|
|
|
|
<!-- Spacer -->
|
|
<TextBlock Grid.Column="1" />
|
|
|
|
<!-- Level -->
|
|
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="6" Margin="0,0,24,0">
|
|
<TextBlock Text="⚡" FontSize="14" VerticalAlignment="Center" />
|
|
<TextBlock x:Name="LevelText"
|
|
FontSize="14"
|
|
Foreground="#8B949E"
|
|
VerticalAlignment="Center" />
|
|
</StackPanel>
|
|
|
|
<!-- Speed indicator bar -->
|
|
<Border Grid.Column="3"
|
|
Width="60" Height="16"
|
|
Background="#1C2128"
|
|
CornerRadius="8"
|
|
Margin="0,0,24,0"
|
|
VerticalAlignment="Center">
|
|
<Border x:Name="SpeedBar"
|
|
Background="#0D9488"
|
|
CornerRadius="8"
|
|
HorizontalAlignment="Left"
|
|
Width="15" />
|
|
</Border>
|
|
|
|
<!-- High Score -->
|
|
<StackPanel Grid.Column="4" Orientation="Horizontal" Spacing="6">
|
|
<TextBlock Text="🏆" FontSize="14" VerticalAlignment="Center" />
|
|
<TextBlock x:Name="HighScoreText"
|
|
FontSize="14"
|
|
Foreground="#FBBF24"
|
|
VerticalAlignment="Center" />
|
|
</StackPanel>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- Game canvas area -->
|
|
<Grid Grid.Row="1">
|
|
<!-- Snake renderer control -->
|
|
<views:SnakeRenderer x:Name="SnakeCanvas"
|
|
BoardWidth="20"
|
|
BoardHeight="15"
|
|
CellSize="28"
|
|
Width="560"
|
|
Height="420"
|
|
HorizontalAlignment="Center"
|
|
VerticalAlignment="Center" />
|
|
|
|
<!-- Start screen overlay -->
|
|
<Border x:Name="StartOverlay"
|
|
Background="#0D1117"
|
|
IsVisible="True"
|
|
HorizontalAlignment="Stretch"
|
|
VerticalAlignment="Stretch">
|
|
<StackPanel HorizontalAlignment="Center"
|
|
VerticalAlignment="Center"
|
|
Spacing="16">
|
|
<TextBlock Text="🐍"
|
|
FontSize="48"
|
|
HorizontalAlignment="Center" />
|
|
<TextBlock Text="SNAKE"
|
|
FontSize="36"
|
|
FontWeight="Bold"
|
|
Foreground="#14B8A6"
|
|
HorizontalAlignment="Center" />
|
|
<TextBlock Text="Press ENTER or Arrow Keys to Start"
|
|
FontSize="16"
|
|
Foreground="#8B949E"
|
|
HorizontalAlignment="Center"
|
|
Margin="0,12,0,0" />
|
|
<TextBlock Text="WASD / Arrows = Move · Space = Pause · R = Restart · Esc = Quit"
|
|
FontSize="12"
|
|
Foreground="#484F58"
|
|
HorizontalAlignment="Center" />
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Pause overlay -->
|
|
<Border x:Name="PauseOverlay"
|
|
Background="#800D1117"
|
|
IsVisible="False"
|
|
HorizontalAlignment="Stretch"
|
|
VerticalAlignment="Stretch">
|
|
<StackPanel HorizontalAlignment="Center"
|
|
VerticalAlignment="Center"
|
|
Spacing="12">
|
|
<TextBlock Text="⏸"
|
|
FontSize="48"
|
|
HorizontalAlignment="Center" />
|
|
<TextBlock Text="PAUSED"
|
|
FontSize="28"
|
|
FontWeight="Bold"
|
|
Foreground="#8B949E"
|
|
HorizontalAlignment="Center" />
|
|
<TextBlock Text="Press Space or P to Resume"
|
|
FontSize="14"
|
|
Foreground="#484F58"
|
|
HorizontalAlignment="Center" />
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Game Over overlay -->
|
|
<Border x:Name="GameOverOverlay"
|
|
Background="#B30D1117"
|
|
IsVisible="False"
|
|
HorizontalAlignment="Stretch"
|
|
VerticalAlignment="Stretch">
|
|
<StackPanel HorizontalAlignment="Center"
|
|
VerticalAlignment="Center"
|
|
Spacing="12">
|
|
<TextBlock Text="💀"
|
|
FontSize="48"
|
|
HorizontalAlignment="Center" />
|
|
<TextBlock Text="GAME OVER"
|
|
FontSize="32"
|
|
FontWeight="Bold"
|
|
Foreground="#EF4444"
|
|
HorizontalAlignment="Center" />
|
|
<TextBlock x:Name="GameOverScoreText"
|
|
FontSize="18"
|
|
Foreground="#E6EDF3"
|
|
HorizontalAlignment="Center" />
|
|
<TextBlock x:Name="GameOverHighScoreText"
|
|
FontSize="14"
|
|
Foreground="#FBBF24"
|
|
HorizontalAlignment="Center" />
|
|
|
|
<StackPanel Orientation="Horizontal"
|
|
HorizontalAlignment="Center"
|
|
Spacing="16"
|
|
Margin="0,16,0,0">
|
|
<Button x:Name="GameOverRestartBtn"
|
|
Content="🔄 Restart"
|
|
Classes="GameButton"
|
|
Width="140" />
|
|
<Button x:Name="GameOverQuitBtn"
|
|
Content="✕ Quit"
|
|
Classes="GameButton GameButtonSecondary"
|
|
Width="140" />
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Score popup (will be rendered by SnakeRenderer) -->
|
|
</Grid>
|
|
</Grid>
|
|
</UserControl>
|