说到贪吃蛇,想必大家多多少少都玩过,而今天我们就用WPF来亲自做一个贪吃蛇的游戏
在XAML设计界面中将改为并取名name=“abc”
在window设计界面里面,通过Loaded="Canvas_Loaded"向界面添加加载事件
public MainWindow()
{
this.WindowStyle = WindowStyle.None;//窗体的边框样式为无边框
this.AllowsTransparency = true;//窗体的透明为可以透明
}
Random ra = new Random();//创建随机数
Border shiwu = new Border();//创建贪吃蛇食物
Border shiwuer = new Border();//创建贪吃蛇食物二
Border dushiwu = new Border();//创建贪吃蛇毒食物
List snake = new List();//创建一个集合用来存取蛇身
List snakeer = new List();//再创建一个集合用来存取蛇身二
DispatcherTimer timer = new DispatcherTimer();//创建一个计时器控制贪吃蛇的移动
double size = 20;//定义一个数size为20,就是定义一个格子为20个单位
Label fs = new Label();//创建label控件,用于记录所得分数
int zj = 0;//定义一个整形zj,设置初始分数为0
MediaPlayer media = new MediaPlayer();//创建媒体播放器
//定义两个数值,表示屏幕格子数的x和y的大小
int gzsx = 60;
int gzsy=40;
//Window_loaded意思是窗口加载完成以后执行
private void Canvas_Loaded(object sender, RoutedEventArgs e)
{
this.Background = Brushes.Transparent;//窗体的背景颜色完全透明
this.WindowState = WindowState.Maximized;//窗口最大化,全屏显示
abc.Background = new RadialGradientBrush(Colors.Red,Colors.Green);//设置显示时的颜色为渐变色
abc.Opacity = 0.5;//窗体的(不)透明度为0.5
//canvas的大小和窗体的大小一致
abc.Width = this.Width;
abc.Height = this.Height;
timer.Interval = TimeSpan.FromMilliseconds(300);//计时器频率设置为FromMilliseconds,每300毫秒移动一下
timer.Tick += Timer_Tick;//创建timer事件
Button ks = new Button();//创建开始按钮,用于控制游戏的开始
ks.Width = 100;
ks.Height = 50;
ks.FontSize = 30; //按钮中字体的大小
ks.Content = "冲冲冲!";//按钮的文本内容
//开始按钮在屏幕中的位置
Canvas.SetLeft(ks, abc.Width-200);
Canvas.SetTop(ks, abc.Height-700);
ks.Background = new RadialGradientBrush(Colors.White, Colors.Yellow);//设置按钮的背景颜色为渐变色
ks.Click += Ks_Click;//创建点击开始按钮触发的事件
abc.Children.Add(ks);//将开始按钮放到abc(canvas)中
Button js = new Button();//创建暂停按钮,用于控制游戏的暂停
js.Width = 100;
js.Height = 50;
js.FontSize = 30; //按钮中字体的大小
js.Content = "停停停!";//按钮的文本内容
//暂停按钮在屏幕中的位置
Canvas.SetLeft(js, abc.Width - 200);
Canvas.SetTop(js, abc.Height - 620);
js.Background = new RadialGradientBrush(Colors.White, Colors.Yellow);//设置按钮的背景颜色为渐变色
js.Click += Js_Click;//创建点击暂停按钮触发的事件
abc.Children.Add(js);//将暂停按钮放到abc(canvas)中
//设置下拉选项框在屏幕中的位置
Canvas.SetLeft(xxk, abc.Width - 200);
Canvas.SetTop(xxk, abc.Height - 460);
//label控件在总体布局里面
fs.Width = 100;
fs.Height = 50;
fs.Content = "得分;"+zj;//label(fs)的文本内容
fs.FontSize = 30;//字体
fs.Background = Brushes.Red;//颜色
//在屏幕中的位置
Canvas.SetLeft(fs, abc.Width - 200);
Canvas.SetTop(fs, abc.Height - 540);
abc.Children.Add(fs);//label添加到canvas中
this.KeyDown += MainWindow_KeyDown;//创建键盘触发事件
CreateSnake();//引用创建贪吃蛇封装的方法
CreateSnakeer();//引用创建贪吃蛇二封装的方法
CreateDouDou();//引用创建食物封装的方法
CreateDouDouer();//引用创建食物二封装的方法
CreateDouDoudu();//引用创建毒食物封装的方法
}
private void Js_Click(object sender, RoutedEventArgs e)//暂停按钮事件
{
timer.Stop();//停止计时器
media.Pause();//停止播放背景音乐
}
private void Ks_Click(object sender, RoutedEventArgs e)//开始按钮事件
{
media.Open(new Uri("../../yy/fengliange.mp3", UriKind.Relative));//给媒体播放器添加音乐路径
media.MediaEnded += Media_MediaEnded;//当媒体播放完成时发生事件
timer.Start();//开启计时器
media.Play();//开始播放音乐
}
private void Media_MediaEnded(object sender, EventArgs e)
{
//当媒体播放完成时重新进行播放音乐
media.Position = new TimeSpan(0);
media.Play();
}
private void MainWindow_KeyDown(object sender, KeyEventArgs e)
{
switch (e.Key)//键盘事件
{
case Key.Up://如果键盘按下的是上
snake[0].Tag = "1";//则蛇头的tag改为1
break;//终止返回
case Key.Down://下
snake[0].Tag = "2";
break;
case Key.Left://左
snake[0].Tag = "3";
break;
case Key.Right://右
snake[0].Tag = "4";
break;
case Key.W://如果键盘按下的是W
snakeer[0].Tag = "a";//则蛇头的tag改为a
break;//终止返回
case Key.S:
snakeer[0].Tag = "b";
break;
case Key.A:
snakeer[0].Tag = "c";
break;
case Key.D:
snakeer[0].Tag = "d";
break;
}
}
private void Timer_Tick(object sender, EventArgs e)
{
for (int i = 0; i < snake.Count; i++)//for循环遍历snake里面的数组数
{
if (snake[i].Tag.ToString() == "3")//如果snake数组的tag等于左(3)的话
{
Canvas.SetLeft(snake[i], Canvas.GetLeft(snake[i]) - size);//则向左移动一个size
}
else if (snake[i].Tag.ToString() == "4")//如果snake数组的tag等于右(4)的话
{
Canvas.SetLeft(snake[i], Canvas.GetLeft(snake[i]) + size);//则向右移动一个size
}
else if (snake[i].Tag.ToString()=="1")//如果snake数组的tag等于上(1)的话
{
Canvas.SetTop(snake[i], Canvas.GetTop(snake[i]) - size);//则向上移动一个size
}
else if (snake[i].Tag.ToString() == "2")//如果snake数组的tag等于下(2)的话
{
Canvas.SetTop(snake[i], Canvas.GetTop(snake[i]) + size);//则向下移动一个size
}
}
for (int i = 0; i < snakeer.Count; i++)
{
if (snakeer[i].Tag.ToString() == "c")//如果snakeer数组的tag等于左(c)的话
{
Canvas.SetLeft(snakeer[i], Canvas.GetLeft(snakeer[i]) - size);//则向左移动一个size
}
else if (snakeer[i].Tag.ToString() == "d")//如果snakeer数组的tag等于右(d)的话
{
Canvas.SetLeft(snakeer[i], Canvas.GetLeft(snakeer[i]) + size);//则向右移动一个size
}
else if (snakeer[i].Tag.ToString() == "a")//如果snakeer数组的tag等于上(a)的话
{
Canvas.SetTop(snakeer[i], Canvas.GetTop(snakeer[i]) - size);//则向上移动一个size
}
else if (snakeer[i].Tag.ToString() == "b")//如果snakeer数组的tag等于下(b)的话
{
Canvas.SetTop(snakeer[i], Canvas.GetTop(snakeer[i]) + size);//则向下移动一个size
}
}
for (int i = snake.Count - 1; i > 0; i--)//for循环遍历snake里面的数组数,倒着遍历
{
snake[i].Tag = snake[i - 1].Tag;//把上一个tag的值赋给现在这个tag,由此类推,一给二,二给三,三给四.所以四个tag随着蛇头tag的变化而变化
}
for (int i = snakeer.Count - 1; i > 0; i--)//第二条蛇和上一条一样
{
snakeer[i].Tag = snakeer[i - 1].Tag;
}
//食物一
if (Canvas.GetLeft(snake[0]) == Canvas.GetLeft(shiwu) && Canvas.GetTop(snake[0]) == Canvas.GetTop(shiwu))//如果蛇头的left和食物的left一样并且top也一样的话
{
//MessageBox.Show("123");测试
//那么原先的食物消失,蛇头和食物接触时,食物将重新进行随机定位
Canvas.SetLeft(shiwu, ra.Next(gzsx) * size);
Canvas.SetTop(shiwu, ra.Next(gzsy) * size);
zj += 1;//消失一次得分加一
fs.Content = "得分;" + zj;//label也随之改变
//吃一口长一节
Border newbrd = new Border();//创建一个border
//大小颜色tag和蛇头一模一样
newbrd.Width = newbrd.Height = size;
newbrd.Background = Brushes.Blue;
newbrd.Tag = "4";
newbrd.CornerRadius = new CornerRadius(20);
//并且让他跟在贪吃蛇的后面
//实现吃一节长一节
Canvas.SetLeft(newbrd, Canvas.GetLeft(snake[snake.Count - 1]) - size);
Canvas.SetTop(newbrd, Canvas.GetTop(snake[snake.Count - 1]));
abc.Children.Add(newbrd);//把创建的border放在canvas(abc)中
snake.Add(newbrd);//把创建的border存入集合snake中
}
//食物二与食物一一致,只需要改一下命名
if (Canvas.GetLeft(snakeer[0]) == Canvas.GetLeft(shiwuer) && Canvas.GetTop(snakeer[0]) == Canvas.GetTop(shiwuer))
{
Canvas.SetLeft(shiwuer, ra.Next(gzsx) * size);
Canvas.SetTop(shiwuer, ra.Next(gzsy) * size);
zj += 1;
fs.Content = "得分;" + zj;
//吃一口长一节
Border newbrder = new Border();
newbrder.Width = newbrder.Height = size;
newbrder.Background = Brushes.White;
newbrder.Tag = "d";
newbrder.CornerRadius = new CornerRadius(20);
Canvas.SetLeft(newbrder, Canvas.GetLeft(snakeer[snakeer.Count - 1]) - size);
Canvas.SetTop(newbrder, Canvas.GetTop(snakeer[snakeer.Count - 1]));
abc.Children.Add(newbrder);
snakeer.Add(newbrder);
}
//第一个蛇吃毒食物
if (Canvas.GetLeft(snake[0]) == Canvas.GetLeft(dushiwu) && Canvas.GetTop(snake[0]) == Canvas.GetTop(dushiwu))//如果蛇头的left和毒食物的left一样并且top也一样的话
{
//那么原先的毒食物消失,蛇头和毒食物接触时,毒食物将重新进行随机定位
Canvas.SetLeft(dushiwu, ra.Next(gzsx) * size);
Canvas.SetTop(dushiwu, ra.Next(gzsy) * size);
zj -= 1;//吃一口减一分
fs.Content = "得分;" + zj;//label也随之改变
//吃一口少一节
//蛇吃毒食物以后,最后一个索引不显示,但是保留控件,然后将控件移除集合snake,真正做到蛇吃一个毒食物以后减到一个蛇身
snake[snake.Count - 1].Visibility = Visibility.Collapsed;
snake.RemoveAt(snake.Count - 1);
}
//第二个蛇吃毒食物和上一个基本一致,改一下命名就好
if (Canvas.GetLeft(snakeer[0]) == Canvas.GetLeft(dushiwu) && Canvas.GetTop(snakeer[0]) == Canvas.GetTop(dushiwu))
{
Canvas.SetLeft(dushiwu, ra.Next(gzsx) * size);
Canvas.SetTop(dushiwu, ra.Next(gzsy) * size);
zj -= 1;
fs.Content = "得分;" + zj;
//吃一口少一节
snakeer[snakeer.Count - 1].Visibility = Visibility.Collapsed;
snakeer.RemoveAt(snakeer.Count - 1);
}
//当贪吃蛇蛇头与墙壁(屏幕)碰撞到的时候
if (Canvas.GetLeft(snake[0])+size >= abc.Width|| Canvas.GetLeft(snake[0]) <= 0|| Canvas.GetTop(snake[0]) >= abc.Height|| Canvas.GetTop(snake[0]) <= 0)
{
zj = 0;//得分归零
fs.Content = "得分;" + zj;
zhunagqiang();//引用封装撞墙方法
}
//贪吃蛇二也是一样
if (Canvas.GetLeft(snakeer[0]) + size >= abc.Width || Canvas.GetLeft(snakeer[0]) <= 0 || Canvas.GetTop(snakeer[0]) >= abc.Height || Canvas.GetTop(snakeer[0]) <= 0)
{
zj = 0;
fs.Content = "得分;" + zj;
zhunagqiang();
}
for (int i = 1; i < snake.Count; i++)//for循环遍历snake中的数量
{
//如果蛇头的left和top和蛇身一致
if (Canvas.GetLeft(snake[0])==Canvas.GetLeft(snake[i])&& Canvas.GetTop(snake[0]) == Canvas.GetTop(snake[i]))
{
zj = 0;//那么得分归零
fs.Content = "得分;" + zj;
czj();//引用封装自食方法
}
}
//贪吃蛇集合二与贪吃蛇集合一一样
for (int i = 1; i < snakeer.Count; i++)
{
if (Canvas.GetLeft(snakeer[0]) == Canvas.GetLeft(snakeer[i]) && Canvas.GetTop(snakeer[0]) == Canvas.GetTop(snakeer[i]))
{
zj = 0;
fs.Content = "得分;" + zj;
czj();
}
}
}
private void zhunagqiang()//封装撞墙方法
{
timer.Stop();//停止计时器
abc.Children.Clear();//移除所有元素控件
//撞墙以后出现提示框让其选择yes或者No
MessageBoxResult xz = MessageBox.Show("小伙子,你还太年轻,要不要再来一次?","提示;你输啦!", MessageBoxButton.YesNo,MessageBoxImage.Hand);
if(xz==MessageBoxResult.Yes)//如果选择的是yes
{
//那么一切重新开始
timer.Start();
snake.Clear();
snakeer.Clear();
CreateSnake();//引用创建贪吃蛇封装的方法
CreateSnakeer();//引用创建贪吃蛇二封装的方法
CreateDouDou();//引用创建食物封装的方法
CreateDouDouer();//引用创建食物二封装的方法
CreateDouDoudu();//引用创建毒食物封装的方法
}
else//否则
{
this.Close();//关闭游戏
}
}
private void czj()//封装自食方法
{
timer.Stop();//停止计时器
abc.Children.Clear();//移除所有元素控件
//自食以后出现提示框让其选择yes或者No
MessageBoxResult xz = MessageBox.Show("小伙子,电子游戏,菜便是原罪!", "提示;你终究还是输啦!", MessageBoxButton.YesNo, MessageBoxImage.Hand);
if (xz == MessageBoxResult.Yes)//如果选择的是yes
{
//那么一切重新开始
timer.Start();
snake.Clear();
snakeer.Clear();
CreateSnake();//引用创建贪吃蛇封装的方法
CreateSnakeer();//引用创建贪吃蛇二封装的方法
CreateDouDou();//引用创建食物封装的方法
CreateDouDouer();//引用创建食物二封装的方法
CreateDouDoudu();//引用创建毒食物封装的方法
}
else//否则
{
this.Close();//关闭游戏
}
}
private void CreateSnake()//创建贪吃蛇封装的方法
{
for (int i = 0; i < 4; i++)//for循环四次,贪吃蛇四节
{
Border brd = new Border();//创建一个新的控件
brd.Background = Brushes.Red;//设置控件的颜色
//设置控件的宽和高
brd.Width = size;
brd.Height = size;
brd.Tag = "4";//最开始移动方向为右(4)
if (i == 0)//如果i=0时
{
brd.Background = Brushes.Yellow;//那么该小节的颜色为黄色
}
else//否则
{
brd.Background = Brushes.Blue;//小节的颜色为绿色
}
Canvas.SetLeft(brd, (gzsx/2)*size- i * size);//设置贪吃蛇的四节的位置和高度
Canvas.SetTop(brd, (gzsy/2)*size);
brd.CornerRadius = new CornerRadius(20);//画圆
abc.Children.Add(brd);//将创建的贪吃蛇添加到ABC就是canvas中去
snake.Add(brd);//将创建的贪吃蛇添加到snake集合中去
}
}
private void CreateSnakeer()//创建贪吃蛇二封装的方法
{
for (int i = 0; i < 4; i++)//for循环四次,贪吃蛇四节
{
Border brder = new Border();//创建一个新的控件
brder.Background = Brushes.Black;//设置控件的颜色
//设置控件的宽和高
brder.Width = size;
brder.Height = size;
brder.Tag = "d";//最开始移动方向为右(d)
if (i == 0)//如果i=0时
{
brder.Background = Brushes.Black;//那么该小节的颜色为黑色
}
else//否则
{
brder.Background = Brushes.White;//小节的颜色为白色
}
Canvas.SetLeft(brder, (gzsx / 2) * size - i * size-size*3);//设置贪吃蛇二的四节的位置和高度
Canvas.SetTop(brder, (gzsy / 2) * size-size*5);
brder.CornerRadius = new CornerRadius(20);//画圆
abc.Children.Add(brder);//将创建的贪吃蛇二添加到ABC就是canvas中去
snakeer.Add(brder);//将创建的贪吃蛇二添加到snake集合中去
}
}
private void CreateDouDou() //创建食物封装的方法
{
shiwu.Width = shiwu.Height = size;//设置食物的大小和贪吃蛇的蛇头一样大
shiwu.Background = new RadialGradientBrush(Colors.Red, Colors.Pink);//设置食物的颜色为渐变色
shiwu.CornerRadius = new CornerRadius(20);//食物半径为20
//食物的随机定位
Canvas.SetLeft(shiwu, ra.Next(gzsx) * size);
Canvas.SetTop(shiwu, ra.Next(gzsy) * size);
abc.Children.Add(shiwu);//将食物添加到canvas中去
}
private void CreateDouDouer()//创建食物二封装的方法
{
shiwuer.Width = shiwuer.Height = size;
shiwuer.Background = new RadialGradientBrush(Colors.Blue, Colors.Pink);
shiwuer.CornerRadius = new CornerRadius(20);
Canvas.SetLeft(shiwuer, ra.Next(gzsx) * size);
Canvas.SetTop(shiwuer, ra.Next(gzsy) * size);
abc.Children.Add(shiwuer);
}
//毒食物
private void CreateDouDoudu()//创建毒食物封装的方法
{
dushiwu.Width = dushiwu.Height = size;
dushiwu.Background = Brushes.Brown;
dushiwu.CornerRadius = new CornerRadius(20);//毒食物半径为20
//毒食物的随机定位
Canvas.SetLeft(dushiwu, ra.Next(gzsx) * size);
Canvas.SetTop(dushiwu, ra.Next(gzsy) * size);
abc.Children.Add(dushiwu);//将毒食物添加到canvas中去
}
private void xxk_SelectionChanged(object sender, SelectionChangedEventArgs e)//下拉列表框的触发事件
{
if (xxk.Text=="黄金")//当下拉列表中的文本内容为黄金时
{
timer.Interval = TimeSpan.FromMilliseconds(200);//计时器的频率加快
}
if (xxk.Text == "砖石")//当下拉列表中的文本内容为砖石时
{
timer.Interval = TimeSpan.FromMilliseconds(100);//计时器的频率加快
}
if (xxk.Text == "王者")//当下拉列表中的文本内容为王者时
{
timer.Interval = TimeSpan.FromMilliseconds(30);//计时器的频率加快
}
}