基于C# WPF框架的贪吃蛇
游戏开始界面
游戏开始
共有两条蛇,吃到红色食物加1分,吃到绿色毒食物减1分,知道0不减;
碰到墙壁游戏结束,碰到对方游戏结束,碰到自己游戏结束
此游戏通过Canvas画布布局,通过C#代码实现
游戏主界面大小为1200*1000
<Window x:Class="贪吃蛇__.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:贪吃蛇__"
mc:Ignorable="d"
Title="贪吃蛇" Loaded="Window_Loaded" Height="700" Width="900">
<Canvas Name="BG" Width = "1200" Height = "1000"></Canvas>
</Window>
全局声明:
Random ran = new Random();// 随机对象
int size = 20; // 边框距离BG距离,格子数
Canvas gameArea = new Canvas(); // 游戏区对象
Border food = new Border(); //食物对象
Border dufood = new Border(); // 毒食物对象
List<Border> snakeList1 = new List<Border>(); // 存储蛇1的泛型
List<Border> snakeList2 = new List<Border>(); // 存储蛇2的泛型
DispatcherTimer moveTimer1 = new DispatcherTimer(); // 蛇1移动定时器
DispatcherTimer moveTimer2 = new DispatcherTimer(); // 蛇2移动定时器
SoundPlayer EatFm = new SoundPlayer(@"../../music/EatFood.wav"); // 吃食物音乐
SoundPlayer EatDuFm = new SoundPlayer(@"../../music/EatDufood.wav");// 吃毒食物音乐
SoundPlayer Overm = new SoundPlayer(@"../../music/Over.wav"); // 游戏结束音乐
SoundPlayer BGm = new SoundPlayer(@"../../music/BGmusic.wav"); // 背景音乐
int score = 0; //记录分数
Label feng = new Label(); // 分数对象
bool Pand = true; // 游戏开始和暂停判断
加载事件:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.Background = Brushes.Cyan;
this.WindowState = WindowState.Maximized; // 屏幕最大化
BG.Background = new LinearGradientBrush(Colors.Yellow, Colors.Pink, 10);
// 边框
Border bianKuang = new Border();
bianKuang.Width = 1040;
bianKuang.Height = 840;
Canvas.SetLeft(bianKuang, size);
Canvas.SetTop(bianKuang, size);
bianKuang.BorderThickness = new Thickness(20); // 边框厚度
bianKuang.CornerRadius = new CornerRadius(10); // 画圆
bianKuang.BorderBrush = Brushes.Green;
BG.Children.Add(bianKuang);
Image map = new Image();
map.Source = new BitmapImage(new Uri("../../img/BGimg.png",UriKind.Relative));
ImageBrush mp = new ImageBrush();
mp.ImageSource = map.Source; // 显示图片
// 游戏区
gameArea.Width = 1000;
gameArea.Height = 800;
gameArea.Background = mp;
mp.Stretch = Stretch.Fill;
Canvas.SetLeft(gameArea, 2 * size);
Canvas.SetTop(gameArea, 2 * size);
BG.Children.Add(gameArea);
// 得分对象
feng.Width = 120;
feng.Height = 50;
Canvas.SetLeft(feng, 1060);
Canvas.SetTop(feng, 100);
feng.Background = Brushes.Coral;
feng.Foreground = Brushes.DeepSkyBlue;
feng.FontFamily = new FontFamily("楷体");
feng.Content = " 得分:" + score + "分";
feng.FontSize = 20;
BG.Children.Add(feng);
// 蛇1移动定时器
moveTimer1.Tick += MoveTimer1_Tick; ;
moveTimer1.Interval = TimeSpan.FromMilliseconds(100);
// 蛇2移动定时器
moveTimer2.Tick += MoveTimer2_Tick;
moveTimer2.Interval = TimeSpan.FromMilliseconds(100);
// 开始按钮
Button Kaise = new Button();
Kaise.Cursor = Cursors.Hand; // 鼠标移动到按钮处变成手型
Kaise.Width = 120;
Kaise.Height = 50;
Canvas.SetLeft(Kaise, 1060);
Canvas.SetTop(Kaise, 160);
Kaise.Content = "开始游戏";
Kaise.FontFamily = new FontFamily("楷体");
Kaise.BorderBrush = Brushes.Cyan; // 边框颜色
Kaise.Foreground = Brushes.DarkRed; // 字体颜色
Kaise.FontSize = 20;
Kaise.Background = Brushes.DarkKhaki;
Kaise.Click += Kaise_Click;
BG.Children.Add(Kaise);
// 暂停按钮
Button Zanting = new Button();
Zanting.Cursor = Cursors.Hand; // 鼠标移动到按钮处变为手型
Zanting.Width = 120;
Zanting.Height = 50;
Canvas.SetLeft(Zanting, 1060);
Canvas.SetTop(Zanting, 220);
Zanting.Content = "暂停游戏";
Zanting.FontFamily = new FontFamily("楷体");
Zanting.BorderBrush = Brushes.Cyan;
Zanting.Foreground = Brushes.DarkRed;
Zanting.FontSize = 20;
Zanting.Background = Brushes.BurlyWood;
Zanting.Click += Zanting_Click;
BG.Children.Add(Zanting);
// 背景音乐播放
BGm.Play();
}
开启游戏按钮
// 开启游戏
private void Kaise_Click(object sender, RoutedEventArgs e)
{
BGm.Stop(); // 背景音乐停止
this.KeyDown += MainWindow_KeyDown;
if (Pand == true)
{
CreateSnake1(); // 生成蛇1方法
CreateSnake2(); // 生成蛇2方法
CreateFood(); // 生成食物
CReateDufood();// 生成毒食物
}
moveTimer1.Start(); // 蛇1移动
moveTimer2.Start();// 蛇2移动
Pand = false;
}
暂停按钮
// 暂停游戏
private void Zanting_Click(object sender, RoutedEventArgs e)
{
this.KeyDown -= MainWindow_KeyDown;
moveTimer1.Stop(); // 蛇1移动
moveTimer2.Stop();// 蛇2移动
Pand = false;
}
创建食物方法:
// 创建食物
private void CreateFood()
{
food.Width = food.Height = size;
food.Background = Brushes.Red;
food.CornerRadius = new CornerRadius(20);
Canvas.SetLeft(food, ran.Next(1, 50) * size);
Canvas.SetTop(food, ran.Next(1, 40) * size);
// 判断食物在蛇位置上
for (int i = 0; i < snakeList1.Count; i++)
{
for (int j = 0; j < snakeList2.Count; j++)
{
if (Canvas.GetLeft(food)==Canvas.GetLeft(snakeList1[i])&&Canvas.GetTop(food)==Canvas.GetTop(snakeList1[i])||Canvas.GetLeft(food)==Canvas.GetLeft(snakeList2[j])&&Canvas.GetTop(food)==Canvas.GetTop(snakeList2[j]))
{
Canvas.SetLeft(food, ran.Next(1, 50) * size);
Canvas.SetTop(food, ran.Next(1, 40) * size);
}
}
}
gameArea.Children.Add(food);
}
创建毒食物方法:
// 创建毒食物
private void CReateDufood()
{
dufood.Width = dufood.Height = size;
dufood.Background = Brushes.GreenYellow;
dufood.CornerRadius = new CornerRadius(20);
Canvas.SetLeft(dufood, ran.Next(1, 50) * size);
Canvas.SetTop(dufood, ran.Next(1, 40) * size);
// 毒食物与食物位置重合
if (Canvas.GetLeft(dufood)==Canvas.GetLeft(food)&&Canvas.GetTop(dufood)==Canvas.GetTop(food))
{
Canvas.SetLeft(dufood, ran.Next(1, 50) * size);
Canvas.SetTop(dufood, ran.Next(1, 40) * size);
}
// 毒食物在蛇身上
for (int i = 0; i < snakeList1.Count; i++)
{
for (int j = 0; j < snakeList2.Count; j++)
{
if (Canvas.GetLeft(dufood) == Canvas.GetLeft(snakeList1[i]) && Canvas.GetTop(dufood) == Canvas.GetTop(snakeList1[i]) || Canvas.GetLeft(dufood) == Canvas.GetLeft(snakeList2[j]) && Canvas.GetTop(dufood) == Canvas.GetTop(snakeList2[j]))
{
Canvas.SetLeft(dufood, ran.Next(1, 50) * size);
Canvas.SetTop(dufood, ran.Next(1, 40) * size);
}
}
}
gameArea.Children.Add(dufood);
}
蛇1创建方法:
// 创建蛇1方法
private void CreateSnake1()
{
int lenght = 4; // 默认蛇长度
for (int i = 0; i < lenght; i++)
{
Border sna1 = new Border(); // 蛇对象
sna1.Width = sna1.Height = size; // 蛇宽度,高度
sna1.Tag = "Right";// 默认方法存储到Tag中
if (i == 0)
{
sna1.Background = Brushes.Thistle;
}
else
{
sna1.Background = Brushes.Purple;
}
Canvas.SetLeft(sna1, gameArea.Width / 2 - (size * i));
Canvas.SetTop(sna1, gameArea.Height / 2);
sna1.CornerRadius = new CornerRadius(20);
gameArea.Children.Add(sna1);
snakeList1.Add(sna1);
}
}
蛇2创建方法:
// 创建蛇2方法
private void CreateSnake2()
{
int length = 4;
for (int i = 0; i < length; i++)
{
Border sna2 = new Border();
sna2.Width = sna2.Height = size;
sna2.Tag = "Left";
if (i == 0)
{
sna2.Background = Brushes.Thistle;
}
else
{
sna2.Background = Brushes.Orange;
}
sna2.CornerRadius = new CornerRadius(20);
Canvas.SetLeft(sna2, gameArea.Width / 2 + (i * size));
Canvas.SetTop(sna2, gameArea.Width / 2);
gameArea.Children.Add(sna2);
snakeList2.Add(sna2);
}
}
蛇1移动
// 蛇1移动定时器
private void MoveTimer1_Tick(object sender, EventArgs e)
{
for (int i = 0; i < snakeList1.Count; i++)
{
if (snakeList1[i].Tag.ToString() == "Right") // 向右移动
{
Canvas.SetLeft(snakeList1[i], Canvas.GetLeft(snakeList1[i]) + size);
}
else if (snakeList1[i].Tag.ToString() == "Left") // 向左移动
{
Canvas.SetLeft(snakeList1[i], Canvas.GetLeft(snakeList1[i]) - size);
}
else if (snakeList1[i].Tag.ToString() == "Up") // 向上移动
{
Canvas.SetTop(snakeList1[i], Canvas.GetTop(snakeList1[i]) - size);
}
else if (snakeList1[i].Tag.ToString() == "Down") // 向下移动
{
Canvas.SetTop(snakeList1[i], Canvas.GetTop(snakeList1[i]) + size);
}
}
for (int i = snakeList1.Count - 1; i > 0; i--)
{
// 蛇身跟随蛇头,占蛇头位置
snakeList1[i].Tag = snakeList1[i - 1].Tag;
}
// 蛇碰到墙
if (Canvas.GetTop(snakeList1[0]) <= -1 || Canvas.GetTop(snakeList1[0]) == gameArea.Height || Canvas.GetLeft(snakeList1[0]) <= -1 || Canvas.GetLeft(snakeList1[0]) == gameArea.Width)
{
GameOver();
}
// 蛇1碰到蛇2
for (int x = 0; x < snakeList2.Count; x++)
{
if (Canvas.GetLeft(snakeList1[0]) == Canvas.GetLeft(snakeList2[x]) && Canvas.GetTop(snakeList1[0]) == Canvas.GetTop(snakeList2[x]))
{
GameOver();
}
}
// 吃到食物
if ( snakeList1.Count>0&&Canvas.GetTop(snakeList1[0]) == Canvas.GetTop(food) && Canvas.GetLeft(snakeList1[0]) == Canvas.GetLeft(food))
{
gameArea.Children.Remove(food); //删除吃的食物
CreateFood(); // 重新创建食物
EatFm.Play(); // 吃食物的音乐
//新创建的蛇身
Border Slimuse = new Border();//增添蛇身
Slimuse.Width = Slimuse.Height = size;
Slimuse.Tag = " ";
Slimuse.Background = Brushes.Purple;
Slimuse.CornerRadius = new CornerRadius(20); // 变圆
Canvas.SetLeft(Slimuse, Canvas.GetLeft(snakeList1[snakeList1.Count - 1])); // 获取到蛇尾的Left位置
Canvas.SetTop(Slimuse, Canvas.GetTop(snakeList1[snakeList1.Count - 1])); // 获取到蛇尾的Top位置
gameArea.Children.Add(Slimuse);
snakeList1.Add(Slimuse);
score++;
feng.Content = " 得分:" + score + "分";
}
//吃到毒食物
if (snakeList1.Count > 0 && Canvas.GetTop(snakeList1[0]) == Canvas.GetTop(dufood) && Canvas.GetLeft(snakeList1[0]) == Canvas.GetLeft(dufood))
{
EatDuFm.Play(); // 吃毒食物音乐
gameArea.Children.Remove(dufood);// 删掉吃的毒食物
CReateDufood(); // 重新创建毒食物
if (score > 0)
{
score--;
feng.Content = " 得分:" + score + "分";
}
gameArea.Children.Remove(snakeList1[snakeList1.Count - 1]); // 清除蛇身最后一节
snakeList1.Remove(snakeList1[snakeList1.Count - 1]); // 清除集合最后一节
}
// 蛇头碰到蛇身体
for (int i = 1; i < snakeList1.Count; i++)
{
// 蛇头碰到蛇身
if (Canvas.GetTop(snakeList1[0]) == Canvas.GetTop(snakeList1[i]) && Canvas.GetLeft(snakeList1[0]) == Canvas.GetLeft(snakeList1[i]))
{
GameOver();
}
}
}
蛇2移动
// 蛇2移动定时器
private void MoveTimer2_Tick(object sender, EventArgs e)
{
for (int i = 0; i < snakeList2.Count; i++)
{
if (snakeList2[i].Tag.ToString() == "Left") // 向左移动
{
Canvas.SetLeft(snakeList2[i], Canvas.GetLeft(snakeList2[i]) - size);
}
else if (snakeList2[i].Tag.ToString() == "Right") // 向右移动
{
Canvas.SetLeft(snakeList2[i], Canvas.GetLeft(snakeList2[i]) + size);
}
else if (snakeList2[i].Tag.ToString() == "Up") // 向上
{
Canvas.SetTop(snakeList2[i], Canvas.GetTop(snakeList2[i]) - size);
}
else if (snakeList2[i].Tag.ToString() == "Down") // 向下
{
Canvas.SetTop(snakeList2[i], Canvas.GetTop(snakeList2[i]) + size);
}
}
for (int i = snakeList2.Count - 1; i > 0; i--)
{
// 蛇身跟随蛇头移动
snakeList2[i].Tag = snakeList2[i - 1].Tag;
}
// 蛇2碰到墙
if (Canvas.GetLeft(snakeList2[0]) <= -1 || Canvas.GetLeft(snakeList2[0]) >= gameArea.Width || Canvas.GetTop(snakeList2[0]) <= -1 || Canvas.GetTop(snakeList2[0]) >= gameArea.Height)
{
GameOver();// 调用游戏结束方法
}
// 蛇2碰到蛇1
for (int x = 0; x < snakeList1.Count; x++)
{
if (Canvas.GetLeft(snakeList2[0]) == Canvas.GetLeft(snakeList1[x]) && Canvas.GetTop(snakeList2[0]) == Canvas.GetTop(snakeList1[x]))
{
GameOver();// 调用游戏结束方法
}
}
// 吃到食物
if (snakeList2.Count>0&& Canvas.GetLeft(snakeList2[0]) == Canvas.GetLeft(food) && Canvas.GetTop(snakeList2[0]) == Canvas.GetTop(food))
{
gameArea.Children.Remove(food); // 删除食物
CreateFood(); // 创建新食物
EatFm.Play();// 吃食物音乐
Border Slom = new Border();// 添加的蛇身 创建新蛇身
Slom.Tag = " ";
Slom.Width = Slom.Height = size;
Slom.Background = Brushes.Orange;
Slom.CornerRadius = new CornerRadius(20);
Canvas.SetLeft(Slom, Canvas.GetLeft(snakeList2[snakeList2.Count - 1]));
Canvas.SetTop(Slom, Canvas.GetTop(snakeList2[snakeList2.Count - 1]));
snakeList2.Add(Slom);
gameArea.Children.Add(Slom);
score++;
feng.Content = " 得分:" + score + "分";
}
// 吃到毒食物
if (snakeList2.Count > 0&&Canvas.GetLeft(snakeList2[0])==Canvas.GetLeft(dufood)&&Canvas.GetTop(snakeList2[0])==Canvas.GetTop(dufood))
{
EatDuFm.Play(); // 吃毒食物音乐
gameArea.Children.Remove(dufood); // 消除毒食物
CReateDufood(); // 创建新毒食物
if (score>0)
{
score--;
feng.Content = " 得分:" + score + "分";
}
gameArea.Children.Remove(snakeList2[snakeList2.Count - 1]);
snakeList2.Remove(snakeList2[snakeList2.Count - 1]);
}
// 蛇头碰到蛇身
for (int i = 1; i < snakeList2.Count; i++)
{
if (Canvas.GetLeft(snakeList2[0]) == Canvas.GetLeft(snakeList2[i]) && Canvas.GetTop(snakeList2[0]) == Canvas.GetTop(snakeList2[i]))
{
GameOver();// 调用游戏结束方法
}
}
}
游戏结束方法:
// 游戏结束方法
private void GameOver()
{
this.KeyDown -= MainWindow_KeyDown;
moveTimer1.Stop();
moveTimer2.Stop();
gameArea.Children.Clear(); // 清除游戏区子级
// Overm.Play(); // 游戏结束音乐
MessageBoxResult Out = MessageBox.Show("游戏结束,得分为:" + score + ",是否重新开始游戏", "游戏结束", MessageBoxButton.YesNo, MessageBoxImage.Asterisk);
if (Out == MessageBoxResult.Yes)
{
snakeList1.Clear(); // 清除存储蛇1的泛型
snakeList2.Clear(); // 清除存储蛇2的泛型
Pand = true;
score = 0;
feng.Content = " 得分:" + score + "分";
}
else
{
this.Close();
}
}
键盘事件
// 键盘事件
private void MainWindow_KeyDown(object sender, KeyEventArgs e)
{
switch (e.Key)
{
case Key.Left:
snakeList1[0].Tag = "Left";
break;
case Key.Right:
snakeList1[0].Tag = "Right";
break;
case Key.Up:
snakeList1[0].Tag = "Up";
break;
case Key.Down:
snakeList1[0].Tag = "Down";
break;
case Key.A:
snakeList2[0].Tag = "Left";
break;
case Key.D:
snakeList2[0].Tag = "Right";
break;
case Key.W:
snakeList2[0].Tag = "Up";
break;
case Key.S:
snakeList2[0].Tag = "Down";
break;
default:
break;
}
}