一. 遊戲界面
首先,按照慣例,編輯MainWindow.xaml,先將遊戲界面製做好。很是簡單:
(1)主遊戲區依然使用咱們熟悉的Canvas控件,大小爲640X480像素,設定每小格子爲20px,因此橫堅座標的格子數爲32x24。見源代碼的最後位置。
(2)定位控件咱們使用DockPanel,方便放置主菜單。
(3)將按鍵事件PreviewKeyDown放在Window內。html
<Window x:Class="MoonSnake.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:MoonSnake" mc:Ignorable="d" PreviewKeyDown="MyCanvas_PreviewKeyDown" Title="Moon Snake Game" Height="540" Width="660" WindowStartupLocation="CenterScreen" ResizeMode="CanMinimize"> <DockPanel> <Menu DockPanel.Dock="Top"> <MenuItem Header="文件"> <MenuItem Name="MenuFile_NewGame" Header="新遊戲" Click="MenuFile_NewGame_Click" /> <Separator/> <MenuItem Name="MenuFile_Exit" Header="退出" Click="MenuFile_Exit_Click" /> </MenuItem> <MenuItem Header="控制"> <MenuItem Name="MenuControl_Pause" Header="暫停" Click="MenuControl_Pause_Click" /> </MenuItem> <MenuItem Header="幫助"> <MenuItem Name="MenuHelp_About" Header="關於..." Click="MenuHelp_About_Click" /> </MenuItem> </Menu> <Canvas x:Name="myCanvas" Height="480" Width="640" Background="#222222" Focusable="True" PreviewKeyDown="MyCanvas_PreviewKeyDown" /> </DockPanel> </Window>
2、添加水果Fruit類
由於咱們不打算使用任何圖片,因此爲了簡單起見,就只使用紅色的實心圓表明水果好了。
看下面的代碼:功能簡單,主要經過兩個屬性指定水果的位置和圖形。express
public class Fruit { public Point _pos { get; set; } public Ellipse _ellipse { get; set; } public Canvas _canvas { get; set; } public Fruit(Point point, Canvas canvas) { _pos = point; _canvas = canvas; _ellipse = new Ellipse { Width = 20, Height = 20, Fill = Brushes.Red }; _ellipse.SetValue(Canvas.LeftProperty, _pos.X * 20); _ellipse.SetValue(Canvas.TopProperty, _pos.Y * 20); _canvas.Children.Add(_ellipse); } public void SetPostion(Point pos) { _pos = pos; _ellipse.SetValue(Canvas.LeftProperty, _pos.X * 20); _ellipse.SetValue(Canvas.TopProperty, _pos.Y * 20); } }
3、添加單節蛇身SnakeNode類
每一個SnakeNode表明蛇身的一節,以後咱們會經過List<SnakeNode>列表表明整條蛇。
看代碼就知道了,與水果類很是類似,甚至比它更簡單,構造函數沒有傳遞Canvas參數,由於咱們打算在主程序實現添加圖形到主遊戲區的功能,只要指定它的位置和形狀便可,形狀則使用了有邊線的矩形代替。canvas
public class SnakeNode { public Point _pos { get; set; } public Rectangle _rect { get; set; } public SnakeNode(Point point) { _pos = point; _rect = new Rectangle { Width = 20, Height = 20, Stroke = new SolidColorBrush(Colors.DodgerBlue), StrokeThickness = 3, Fill = Brushes.SkyBlue }; _rect.SetValue(Canvas.LeftProperty, _pos.X * 20); _rect.SetValue(Canvas.TopProperty, _pos.Y * 20); } }
4、定義四個常量和兩個枚舉
看註釋:dom
const int CellSize = 20; // 小格子大小 const int SnakeHead = 0; // 蛇頭位置(永遠位於列表0) const int CellWidth = 640 / CellSize; // 遊戲區橫格數 const int CellHeight = 480 / CellSize; // 遊戲區縱格數 // 蛇身前進方向 enum Direction { UP, DOWN, LEFT, RIGHT } Direction Direct = Direction.UP; // 遊戲狀態 enum GameState { NONE, GAMEING, PAUSE, STOP } GameState CurrGameState = GameState.NONE;
5、不多的幾個字段變量函數
List<SnakeNode> SnakeNodes = new List<SnakeNode>(); // 蛇身列表 Fruit fruit; // 水果 Random rnd = new Random((int)DateTime.Now.Ticks); // 隨機數 System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer(); // 計時器
6、畫遊戲區暗格線
主要使用Path控件,經過循環每隔20px畫一根橫線和縱線。ui
private void DrawGrid() { Path gridPath = new Path(); gridPath.Stroke = new SolidColorBrush(Color.FromArgb(255, 50, 50, 50)); gridPath.StrokeThickness = 1; StringBuilder data = new StringBuilder(); for (int x = 0; x < 640; x += CellSize) { data.Append($"M{x},0 L{x},480 "); } for (int y = 0; y<480; y += CellSize) { data.Append($"M0,{y} L640,{y} "); } gridPath.Data = Geometry.Parse(data.ToString()); myCanvas.Children.Add(gridPath); }
7、我是構造方法
這裏畫底線和設置計時器。spa
public MainWindow() { InitializeComponent(); DrawGrid(); timer.Interval = new TimeSpan(0, 0, 0, 0, 260); timer.Tick += Timer_Tick; }
可先註釋掉最後一行,運行看看遊戲界面了。3d