目录
源码可以在github上获取https://github.com/ZombieAllen/WPF.git
源码可以在github上获取https://github.com/ZombieAllen/WPF.git
基于WPF的贪吃蛇游戏设计
摘要:针对现有的网上关于WPF以及C#开发缺乏系统化的学习资料,现在设计一款大家耳熟能详的贪吃蛇的小游戏,来比较好的把XMAL界面设计,XML文件的信息写入与读取,C#面向对象的程序设计整合到一个游戏里。
关键字:WPF;C#;XML;界面设计;Visual Studio 2019
1 引言
随着工厂信息化以及数字化的飞速发展,对于工厂的自动化工程师,掌握一门高级的开发语言,来开发界面美观的windows客户端,实现数据的采集,存储,展示已经变得越来越必须。跨学科的人才需求也在日渐加大。
C#语言是现如今比较流行的一门面向对象的编程语言,在微软新一代界面设计技术WPF的加持下,设计出一款界面美观,功能强大的windows客户端应用变得非常方便。
这款基于WPF的贪吃蛇游戏,会利用Canvas来绘制界面的背景以及蛇和果实,并利用障眼法来实现蛇的动画效果,并利用事件来实现方向控制,最后会利用xml技术来存储高分榜,游戏开始的时候可以列出玩家排名。
2 功能设计
2.1游戏区域
首先我们打开Visual Studio2019 , 新建WPF项目
短短的几行xmal代码,就实现了游戏窗口
接下来我们在这个Canvas区域画出网格,来规范蛇以及果实出现的位置
技巧:通过isOdd变量的值通过嵌套For循环来在画布上画出一个个颜色相间的方块。
最终实现的代码以及效果
private void Window_ContentRendered(object sender, EventArgs e)
{
DrawGameArea();
}
private void DrawGameArea()
{
for (int y = 0; y < GameArea.ActualHeight; y+=squareSize)
{
for (int x = 0; x < GameArea.ActualWidth; x += squareSize)
{
Rectangle rectangle = new Rectangle() { Width = squareSize, Height = squareSize };
rectangle.Fill = isOdd ? Brushes.White : Brushes.WhiteSmoke;
GameArea.Children.Add(rectangle);
Canvas.SetLeft(rectangle, x);
Canvas.SetTop(rectangle, y);
isOdd = !isOdd;
}
isOdd = !isOdd;
}
}
2.2 贪吃蛇动画
这里我们会接触第一个面向对象设计的套路:类-à实例
对于一条蛇来说,C#自身并没有这个实例。 这时候我们需要自己创建一个SnakePart的类,然后进行实例化出一条蛇。
实现方法:
在项目里添加一个SnakePart的类,定义其主要属性:UI元素,位置,是否是蛇头
代码如下
namespace WPF贪吃蛇游戏设计
{
public class SnakePart
{
public UIElement uIElement { get; set; }
public Point point { get; set; }
public Boolean isHead { get; set; }
}
}
然后我们用泛型集合List把一个个蛇的部分串起来,就成了一条蛇了。
List<SnakePart> snakeParts = new List<SnakePart>();
那么我们先画一条静态的蛇
定义蛇的初始位置以及长度
//初始位置
Point startPos = new Point(120, 120);
//初始长度
int snakeLength = 3;
然后判断是否是蛇头来画不同颜色的方框,并把方框添加到蛇的uIElement上,然后在Canvas里画出来
具体实现代码:
private void DrawSnake(Point startPos, int snakelength)
{
Boolean isHead = false;
double nextX = startPos.X;
double nextY = startPos.Y;
for (int i = 0; i < snakelength; i++)
{
if (i < snakelength - 1)
{
isHead = false;
DrawSnake_sub(isHead, nextX, nextY);
nextX += squareSize;
}
else
{
isHead = true;
DrawSnake_sub(isHead, nextX, nextY);
}
}
}
private void DrawSnake_sub(Boolean isHead , double nextX,double nextY)
{
Rectangle rectangle = new Rectangle() { Width = squareSize, Height = squareSize };
rectangle.Fill = isHead ? snakeHeadColor : snakeBodyColor;
SnakePart snakepart = new SnakePart();
snakepart.uIElement = rectangle;
snakeParts.Add(snakepart);
GameArea.Children.Add(rectangle);
Canvas.SetLeft(rectangle, nextX);
Canvas.SetTop(rectangle, nextY);
}
然后在页面渲染的时候调用
DrawSnake(startPos, snakeLength);
这样我们就初始化了一条蛇,具体实现结果如下(红色为蛇头,绿色为蛇身)
接下来我们的任务就是让蛇动起来:控制蛇的方向和蛇的速度
蛇的方向:
首先我们定义一个枚举类型SnakeDirection,来表示蛇移动的四个方向。
namespace WPF贪吃蛇游戏设计
{
public enum SnakeDirection
{
left,
top,
right,
down
}
}
然后我们设定蛇的初始行进方向为向右
接下来我们定义蛇的行进速度,这时候就得用到定时器以及事件了
首先我们实例化一个定时器dispatch
//定时器
DispatcherTimer dispatcher = new DispatcherTimer();
为其绑定一个事件MoveSnake(),定时器的间隔时间设定以及开始计时
dispatcher.Interval = TimeSpan.FromMilliseconds(1000);
dispatcher.Tick += Dispatcher_Tick;
dispatcher.Start();
接下来就是MoveSnake函数的编写了。
对于蛇的移动来说,其实用到的就是障眼法,分为4步
- 移去蛇尾
- 在原先蛇头的位置画蛇身
- 移去原先的蛇头
- 根据蛇头原先的位置,在其行进方向一个单元格的位置重新画一个蛇头
具体实现代码
private void MoveSnake()
{
//移去最后一节身子
GameArea.Children.Remove(snakeParts[0].uIElement);
snakeParts.Remove(snakeParts[0]);
//获取原先蛇头的位置,并重新画一个身子
double exHeadPosX = snakeParts[snakeParts.Count-1].point.X;
double exHeadPosY = snakeParts[snakeParts.Count - 1].point.Y;
DrawSnake_sub(false, exHeadPosX, exHeadPosY);
//移去原先的蛇头
GameArea.Children.Remove(snakeParts[snakeParts.Count - 2].uIElement);
snakeParts.Remove(snakeParts[snakeParts.Count - 2]);
//重新画一个蛇头
DrawSnake_sub(true, exHeadPosX+squareSize, exHeadPosY);
}
经过测试,蛇就可以沿着向右的方向每隔1s移动一格了