当前位置:   article > 正文

贪吃蛇游戏的编程思想(案例总结)_贪吃蛇程序设计总结

贪吃蛇程序设计总结

贪吃蛇游戏的编程思想(案例总结)


效果图:

贪吃蛇游戏效果图
案例要求:

​ 1、蛇在设定好的面板上移动

​ 2、食物在蛇的面板是随机位置

​ 3、当在键盘上按下上、下、左、右键的时候蛇改变移动方向

​ 4、当蛇吃到食物的时候自己长一节蛇身

​ 5、当蛇碰到自身和墙壁(自己设定好的区域)就弹出提示框

​ 6、并有按钮来控制游戏的开始和暂停或者说退出,以及蛇移动的速度

一、该如何布局

​ 1、在这里布局的话,可以选择用Canva面板来做这个容器,并给这个容器取一个name 叫做game

​ 2、然后我们可以设置窗口的大小以及属性

  public MainWindow()//公共主窗口构造方法
        {
            InitializeComponent();
            this.Title = "水果贪吃蛇大作战";//设置窗体的标题
            this.ResizeMode = ResizeMode.CanMinimize;//设置窗体最大化最小话和关闭按钮,其中最大化按钮处于关闭状态
            //设置窗体的大小
            this.Width = 1100;
            this.Height = 600;
            this.WindowStartupLocation = WindowStartupLocation.CenterScreen;//设置窗体居中显示
            
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

​ 3、设置Canvas的大小跟窗口的一样,并设置Canvas的属性

 //设置canvas的大小为窗口的大小
            game.Width = this.Width;
            game.Height = this.Width;
            //设置Canvas的背景图片
            ImageBrush image1 = new ImageBrush();
            image1.ImageSource = new BitmapImage(new Uri("E:/C#/C#文件/贪吃蛇游戏(终)/images/背景.jpg"));
            image1.Stretch = Stretch.Fill;//设置图片可以拉伸
            game.Background = image1;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

​ 4、划分游戏区域与控制区域,这里可以设置一个圆角的Border来将整个Canvas一分为二,当然,游戏区域要大于控制区域。

​ 5、创建蛇和食物以前我们要设置蛇和食物的精确坐标,那么,该如何精确呢?

​ 这里我们可以将Canva划分为网格,网格的大小这里我设置的是20,横坐标可以划分1100/20=55个网格,纵坐标可以划分为600/20=30个网格,其中,13个网格用作控制区域,42个网格用作游戏区域。

​ 所以,这里就要定义变量:一个网格的大小,游戏区域横坐标网格的数量,纵坐标网格的数量

	    int size = 20;//设置一个方格的大小
	    //定义格子数变量
        int yxgzsX = 42;
        int yxgzsY = 30;
  • 1
  • 2
  • 3
  • 4

二、创建蛇

​ 1、snake是为自己封装的方法,所以一定要在加载事件中调用

​ 2、因为蛇不可能只有一节,所以这里用for循环来遍历四节,为了区分蛇头和蛇身我插入了不同的图像

​ 3、最重要的就是蛇的位置,整个该如何计算?

​ (1)蛇的横坐标: Canvas.SetLeft(snake1, (yxgzsX/2) * size - i * size );

​ (yxgzsX/2)表示找到横坐标中心点的格子42/2=12;×size是找到第12个格子的位置, - i * size 就是说当i=0的时候蛇头的横坐标位置就12*20=240的位置上,当i=1的时候,让第二节蛇就在蛇头的左边摆放…

​ (2)纵坐标就是一个位置不变

		/// <summary>
        /// snake 是私有的,封装蛇的方法
        /// </summary>
        private void snake()//创建蛇的方法
        {
            for (int i = 0; i < 4; i++)
            {
                Border snake1 = new Border();
                snake1.Width = snake1.Height = size;
                snake1.Tag = "Right";//默认4节蛇的tag为Right
                if (i==0)
                {
                    ImageBrush image2 = new ImageBrush();
                    image2.ImageSource = new BitmapImage(new Uri("E:/C#/C#文件/贪吃蛇游戏(终)/images/橙子.png"));
                    image2.Stretch = Stretch.Fill;//设置可以拉伸
                    snake1.Background = image2;
                }
                else
                {
                    ImageBrush image2 = new ImageBrush();
                    image2.ImageSource = new BitmapImage(new Uri("E:/C#/C#文件/贪吃蛇游戏(终)/images/青柠.png"));
                    image2.Stretch = Stretch.Fill;//设置可以拉伸
                    snake1.Background = image2;
                }
                snake1.CornerRadius = new CornerRadius(size / 2);
                Canvas.SetLeft(snake1, (yxgzsX/2) * size - i * size );
                Canvas.SetTop(snake1, (yxgzsY/2) * size);
                game.Children.Add(snake1);
                a.Add(snake1);//将实例化的4节蛇存储到集合a中
            }
           
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

三、创建食物

​ 1、因为食物的位置是随机的,所以这里要创建随机函数ra

​ 2、随机的位置为游戏区域内,不能在游戏区域的边缘上随机

 /// <summary>
        /// foods 是私有的,封装食物的方法
        /// </summary>
        private void foods()//创建食物的方法
        {
           
            food.Width = food.Height = size;
            ImageBrush image3 = new ImageBrush();
            image3.ImageSource = new BitmapImage(new Uri("E:/C#/C#文件/贪吃蛇游戏(终)/images/食物1.png"));
            food.Background = image3;
            food.CornerRadius = new CornerRadius(size / 2);
            //位置随机
            Canvas.SetLeft(food, ra.Next(2*size,(yxgzsX)*size));
            Canvas.SetTop(food, ra.Next(2*size,(yxgzsY-1)*size));
            game.Children.Add(food) ;
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

四、蛇的移动

​ 1、蛇移动这里我们用到计时器,让计时器控制蛇移动的频率,这里创建计时器与Winfron中创建计时器不同,需要先导包

 DispatcherTimer timer1 = new DispatcherTimer();//计时器事件控制蛇的移动
 timer1.Interval = TimeSpan.FromMilliseconds(200);//计时器触发的频率
 timer1.Start();//开启计时器
 timer1.Tick += Timer1_Tick;//添加计时器事件
  • 1
  • 2
  • 3
  • 4

​ 2、因为如果说开启计时器的话,蛇会朝着一个方向移动,所以我们要设置键盘事件改变方向(下划线下为键盘事件)

​ 这里是计时器事件

​ 3、要用for遍历集合,如果说按下的方向键是左,那么蛇头的Tag就变为了Left,就让蛇头在现在位置的基础上减去一个方格的大小,如果是向右蛇头就像右移动一个方格的位置,如果是向上就让蛇头向上移动一个方格,向下就是向下移动一个方格的大小,这里只是让蛇头改变了位置

​ 4、如何让蛇身移动?

​ 这里我们可以再用一个for循环遍历,这次倒着遍历,从集合的最后一个索引上遍历,并且不遍历蛇头,所以说必须大于0,让遍历到的蛇节的Tag都等于上一节蛇的Tag,这样一直遍历,每一节蛇的Tag都变成了蛇头的Tag,当Tag都变成一个Tag的时候就进入第一个循环,来改变方向和位置

  private void Timer1_Tick(object sender, EventArgs e)//计时器控制蛇的移动
        {
            //通过for循环遍历集合中的控件,将集合中的控件拿出来
            for (int i = 0; i < a.Count; i++)
            {
                //先让蛇头移动
                if (a[i].Tag.ToString() == "Left")
                {
                    Canvas.SetLeft(a[i], Canvas.GetLeft(a[i]) - size);
                }
                else if (a[i].Tag.ToString() == "Right")
                {
                    Canvas.SetLeft(a[i], Canvas.GetLeft(a[i]) + size);
                }
                else if (a[i].Tag.ToString() == "Up")
                {
                    Canvas.SetTop(a[i], Canvas.GetTop(a[i]) - size);
                }
                else if (a[i].Tag.ToString() == "Down")
                {
                    Canvas.SetTop(a[i], Canvas.GetTop(a[i]) + size);
                }
            }
            for (int i = a.Count - 1; i > 0; i--)//蛇头移动后,让第二节蛇等于上一节蛇(蛇头)的tag,此时就跑到了上一个for循环
            {
                a[i].Tag = a[i - 1].Tag;
            }
       }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

​ 1、因为蛇移动是有方向的,当按下键盘上的某个键就改变方向,所以这里要添加键盘事件

this.KeyDown += MainWindow_KeyDown;//给窗体添加键盘事件
  • 1

​ 2、先让蛇头改变方向,蛇头改变方向后再依次改变蛇身的方向

​ 3、但是这里我们呢获取不到蛇,所以这里就使用到集合泛型List<>,取的时候跟数组一样是用索引的方式取

  List<Border> a = new List<Border>();//实例化泛型集合来存储每一节蛇
  • 1

​ 4、再创建蛇的过程中,每创建一节蛇就将它放进整个集合中,并用switch分支语句来判断是否按下的是键盘上的某个键

 a.Add(snake1);//将实例化的4节蛇存储到集合a中
  • 1

​ 5、那么如何区分蛇头和蛇节呢,所以这里用到Tag标记属性,创建出的蛇的Tag默认为Right,当按下上下左右键的时候,就改变蛇头的Tag为英文方向,并跳出switch分支语句

  private void MainWindow_KeyDown(object sender, KeyEventArgs e)//键盘的触发事件
        {
            switch (e.Key)//如果按下的是键盘上的某个键
            {
                //让第一节蛇先动,那如何获取第一际额蛇?可以用泛型集合来存储这4节蛇,并通过索引取出来
                //每一节蛇的tag默认为Right,通过改变第一节的方向来改变后边的方向
                case Key.Right:a[0].Tag = "Right";break;
                    //如果按下的键是Right,那么就改变第一节蛇的tag为Right,就退出swich分支语句
                case Key.Left: a[0].Tag = "Left";break;
                    //如果按下的键是Left,那么就改变第一节蛇的tag为Lift,就退出swich分支语句
                case Key.Up: a[0].Tag = "Up";break;
                    //如果按下的键是Up,那么就改变第一节蛇的tag为Up,就退出swich分支语句
                case Key.Down:a[0].Tag = "Down";break;
                    //如果按下的键是Down,那么就改变第一节蛇的tag为Down,就退出swich分支语句
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

五、蛇移动吃食物,并长一节蛇身

​ 1、因为蛇在移动的时候才吃食物,所以要在蛇移动的计时器中写接下来的代码

​ 2、蛇移动吃食物实际上就是蛇头和食物碰撞,碰撞就是相等,就是蛇的xy坐标等于食物的xy左边

​ 3、当碰撞后食物并没有消失,而是改变了位置,同时这个位置也是随机的

​ 5、改变位置后蛇长了一节身体,所谓长了一节身体就是创建了一个和蛇身一样的Border控件,并放在了最后一节蛇后边的位置,所以增长的蛇节的位置就是获取最后一节蛇的位置

​ 6、最后一定要将创建的这个蛇节放到集合a中,否则报错(索引超出范围)

 			  //改变食物的位置为随机
			   Canvas.SetLeft(food, ra.Next(yxgzsX) * size);
                Canvas.SetTop(food, ra.Next(yxgzsY) * size);
                //然后创建border控件,放到蛇的尾部
                Border jie = new Border();
                jie.Tag = "";//必须设置tag属性,否则报错
                jie.Width = jie.Height = size;
                jie.CornerRadius = new CornerRadius(size/2);
                //插入背景图片。和蛇身的背景图片一样
                ImageBrush image3 = new ImageBrush();
                image3.ImageSource = new BitmapImage(new Uri("E:/C#/C#文件/贪吃蛇游戏(终)/images/青柠.png"));
                image3.Stretch = Stretch.Fill;
                jie.Background = image3;
                //它的位置实际上就是最后一节蛇的位置
                Canvas.SetLeft(jie, Canvas.GetLeft(a[a.Count-1]));//count为长度是4,但是最后一节蛇的索引为3,所以-1
                Canvas.SetTop(jie, Canvas.GetTop(a[a.Count-1]));
                game.Children.Add(jie);
                a.Add(jie);//一定要添加到集合a中
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

六、当蛇碰到自己的身体和墙壁时死亡,出现窗口提示

​ 1、是碰到自己的身体肯定就是蛇边长以后蛇头碰住蛇尾往前的位置,所以就可以用到刚刚的那么倒着遍历的for循环

​ 2、就是说蛇头碰住了集合a中除了a[0]的所有Border控件的其中一个

for (int i = a.Count - 1; i > 0; i--)//蛇头移动后,让第二节蛇等于上一节蛇(蛇头)的tag,此时就跑到了上一个for循环
            {
                a[i].Tag = a[i - 1].Tag;
                //判断是否碰住蛇身,就是说蛇头的位置等于蛇身的位置就说明碰到了
                //因为舍身是除了蛇头往后的每一节,其中更不能从自己的蛇身传过去
                if (Canvas.GetLeft(a[0])==Canvas.GetLeft(a[i]) && Canvas.GetTop(a[0])==Canvas.GetTop(a[i]))
                {
                    //消息选择提示框
                  MessageBoxResult sule= MessageBox.Show("您已阵亡,是否重新开始?", "警告", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
                    // MessageBoxResult表示用户单击了哪个消息框按钮
                    if (sule== MessageBoxResult.Yes)//如果选择是
                    {
                        timer1.Stop();//关闭计时器
                        a.Clear();//必须移除集合泛型中的所有元素
                        game.Children.Clear();//最后移除canvas中的所有元素
                        snake();//调用创建蛇的方法
                        foods();//叫用创建食物的方法
                        timer1.Start();//开启蛇移动的计时器
                                       //Application.Current.Shutdown(-1);//关闭应用程序
                                       // Environment.Exit(-1);//强制结束进程
                        kzt();//调用控制区域
                    }
                    else
                    {
                        Application.Current.Shutdown(-1);//关闭应用程序
                    }
                }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

​ 3、碰撞到墙壁,就是碰到上下左右四个方向,左和上就是0,下为Canva的高度,右为分割游戏控制区域的位置

 if (Canvas.GetLeft(a[0])==0 || Canvas.GetTop(a[0])==0 || Canvas.GetLeft(a[0])>=Canvas.GetLeft(kzt1) || Canvas.GetTop(a[0])>=Canvas.GetTop(game))//判断是否碰到了墙壁
            {
                MessageBoxResult b= MessageBox.Show("您已阵亡,是否重新开始?", "警告", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
                if (b== MessageBoxResult.Yes)
                {
                    timer1.Stop();//关闭计时器
                    a.Clear();//必须移除集合泛型中的所有元素
                    game.Children.Clear();//最后移除canvas中的所有元素
                    snake();//调用创建蛇的方法
                    foods();//叫用创建食物的方法
                    timer1.Start();//开启蛇移动的计时器
                                   //Application.Current.Shutdown(-1);//关闭应用程序
                                   // Environment.Exit(-1);//强制结束进程
                    kzt();//调用控制区域的方法
                }
                else
                {
                    Environment.Exit(-1);//强制退出
                }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

七、控制区域

1、显示积分控件

​ (1)用Label控件来显示积分,定义一个初始变量为0,来记录积分,当蛇碰撞到食物后,就+1,最后就是设置这个控件的大小,位置。

 		   lab.Content = "   分数:"+x;//显示的文本
			//设置大小
            lab.Width = 80;
            lab.Height = 30;
            lab.Background = brush1;//插入的背景图片
			//设置位置
            Canvas.SetLeft(lab,Canvas.GetLeft(ks));
            Canvas.SetTop(lab, 100);
            game.Children.Add(lab);//添加到Canvas面板中
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2、开始和暂停按钮,就是创建Button控件,并设置事件,事件中关闭或打开计时器

 //开始按钮
            Button ks = new Button();
            ks.Content = "开始游戏";
            ks.Width = 80;
            ks.Height = 40;
            ImageBrush brush = new ImageBrush();
            brush.ImageSource = new BitmapImage(new Uri("E:/C#/C#文件/贪吃蛇游戏(终)/images/按钮背景.png"));
            ks.Background = brush;
            Canvas.SetLeft(ks, Canvas.GetLeft(kzt1) + 100);
            Canvas.SetTop(ks,200);
            game.Children.Add(ks);
            ks.Click += Ks_Click;
            //暂停游戏
            Button zt = new Button();
            zt.Content = "暂停游戏";
            zt.Width = 80;
            zt.Height = 40;
            ImageBrush brush1 = new ImageBrush();
            brush1.ImageSource = new BitmapImage(new Uri("E:/C#/C#文件/贪吃蛇游戏(终)/images/按钮背景.png"));
            zt.Background = brush1;
            Canvas.SetLeft(zt, Canvas.GetLeft(ks));
            Canvas.SetTop(zt, Canvas.GetTop(ks)+80);
            game.Children.Add(zt);
            zt.Click += Zt_Click;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

按钮事件

 private void Zt_Click(object sender, RoutedEventArgs e)//暂停游戏事件
        {
            timer1.Stop();关闭计时器
        }

        private void Ks_Click(object sender, RoutedEventArgs e)//开始游戏的事件
        {
            timer1.Start();//开启计时器
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

八、全部代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace 贪吃蛇游戏_终_
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        //初始化事件
        public MainWindow()
        {
            InitializeComponent();
            this.Title = "水果贪吃蛇大作战";//设置窗体的标题
            this.ResizeMode = ResizeMode.CanMinimize;//设置窗体最大化最小话和关闭按钮,其中最大化按钮处于关闭状态
            //设置窗体的大小
            this.Width = 1100;
            this.Height = 600;
            this.WindowStartupLocation = WindowStartupLocation.CenterScreen;//设置窗体居中显示
            
        }

 #region//定义的变量和控件以及集合

        int size = 20;//设置一个方格的大小
        //定义格子数变量
        int yxgzsX = 42;
        int yxgzsY = 30;
        int x = 0;
        Random ra = new Random();//随机数
        List<Border> a = new List<Border>();//实例化泛型集合来存储每一节蛇
        Border food = new Border();//创建食物的控件
        DispatcherTimer timer1 = new DispatcherTimer();//计时器事件控制蛇的移动
        Border kzt1 = new Border();//隔离区域
        Label lab = new Label();//积分控件
        MediaPlayer player = new MediaPlayer();
        
        #endregion
        #region 编程思想
        //将屏幕划分为25×25的网格,1100/20=55,可以划分55个网格,其中13个网格用作控制台,42个网格用作游戏
        //600/20=30个方格
        //所以,游戏区域的网格=33,控制台的网格=11
        //所以,可以在这11个网格中创建border控制台
        //设置窗体的加载事件
        #endregion
        #region 窗口的触发事件
        /// <summary>
        /// 窗口的触发事件
        /// </summary>
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //设置canvas的大小为窗口的大小
            game.Width = this.Width;
            game.Height = this.Width;
            //设置Canvas的背景图片
            ImageBrush image1 = new ImageBrush();
            image1.ImageSource = new BitmapImage(new Uri("E:/C#/C#文件/贪吃蛇游戏(终)/images/背景.jpg"));
            image1.Stretch = Stretch.Fill;//设置图片可以拉伸
            game.Background = image1;
            
            snake();//调用创建蛇的方法
            foods();//调用创建食物的方法
            this.KeyDown += MainWindow_KeyDown;//给窗体添加键盘事件
            
            timer1.Interval = TimeSpan.FromMilliseconds(200);//计时器触发的频率
            //timer1.Start();//开启计时器
            timer1.Tick += Timer1_Tick;//添加计时器事件
            kzt();
            player.Open(new Uri("E:/C#/C#文件/贪吃蛇游戏(终)/sound/背景音乐.mp3"));
            player.Play();
            player.MediaEnded += Player_MediaEnded;
        }

        private void Player_MediaEnded(object sender, EventArgs e)
        {
            player.Play();
        }

        /// <summary>
        /// Timer1_Tick表示计时器的触发事件
        /// </summary>
        private void Timer1_Tick(object sender, EventArgs e)//计时器控制蛇的移动
        {
            //通过for循环遍历集合中的控件,将集合中的控件拿出来
            for (int i = 0; i < a.Count; i++)
            {
                //先让蛇头移动
                if (a[i].Tag.ToString() == "Left")
                {
                    Canvas.SetLeft(a[i], Canvas.GetLeft(a[i]) - size);
                }
                else if (a[i].Tag.ToString() == "Right")
                {
                    Canvas.SetLeft(a[i], Canvas.GetLeft(a[i]) + size);
                }
                else if (a[i].Tag.ToString() == "Up")
                {
                    Canvas.SetTop(a[i], Canvas.GetTop(a[i]) - size);
                }
                else if (a[i].Tag.ToString() == "Down")
                {
                    Canvas.SetTop(a[i], Canvas.GetTop(a[i]) + size);
                }
            }
            for (int i = a.Count - 1; i > 0; i--)//蛇头移动后,让第二节蛇等于上一节蛇(蛇头)的tag,此时就跑到了上一个for循环
            {
                a[i].Tag = a[i - 1].Tag;
                //判断是否碰住蛇身,就是说蛇头的位置等于蛇身的位置就说明碰到了
                //因为舍身是除了蛇头往后的每一节,其中更不能从自己的蛇身传过去
                if (Canvas.GetLeft(a[0])==Canvas.GetLeft(a[i]) && Canvas.GetTop(a[0])==Canvas.GetTop(a[i]))
                {
                    //消息选择提示框
                  MessageBoxResult sule= MessageBox.Show("您已阵亡,是否重新开始?", "警告", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
                    if (sule== MessageBoxResult.Yes)//如果选择是
                    {
                        timer1.Stop();//关闭计时器
                        a.Clear();//必须移除集合泛型中的所有元素
                        game.Children.Clear();//最后移除canvas中的所有元素
                        snake();//调用创建蛇的方法
                        foods();//叫用创建食物的方法
                        timer1.Start();//开启蛇移动的计时器
                                       //Application.Current.Shutdown(-1);//关闭应用程序
                                       // Environment.Exit(-1);//强制结束进程
                        kzt();
                    }
                    else
                    {
                        Application.Current.Shutdown(-1);//关闭应用程序
                    }
                }
                
            }
            if (Canvas.GetLeft(a[0])==Canvas.GetLeft(food) && Canvas.GetTop(a[0])==Canvas.GetTop(food))
                //蛇头的xy坐标=食物的xy坐标那么就证明蛇和食物相撞了
            {
                x++;
                //如果碰撞了,那么就改变食物的位置
                Canvas.SetLeft(food, ra.Next(yxgzsX) * size);
                Canvas.SetTop(food, ra.Next(yxgzsY) * size);
                //然后创建border控件,放到蛇的尾部
                Border jie = new Border();
                jie.Tag = "";//必须设置tag属性,否则报错
                jie.Width = jie.Height = size;
                jie.CornerRadius = new CornerRadius(size/2);
                //插入背景图片。和蛇身的背景图片一样
                ImageBrush image3 = new ImageBrush();
                image3.ImageSource = new BitmapImage(new Uri("E:/C#/C#文件/贪吃蛇游戏(终)/images/青柠.png"));
                image3.Stretch = Stretch.Fill;
                jie.Background = image3;
                //它的位置实际上就是最后一节蛇的位置
                Canvas.SetLeft(jie, Canvas.GetLeft(a[a.Count-1]));//count为长度是4,但是最后一节蛇的索引为3,所以-1
                Canvas.SetTop(jie, Canvas.GetTop(a[a.Count-1]));
                game.Children.Add(jie);
                a.Add(jie);//一定要添加到集合a中
                lab.Content = "   积分:" + x;
            }
            if (Canvas.GetLeft(a[0])==0 || Canvas.GetTop(a[0])==0 || Canvas.GetLeft(a[0])>=Canvas.GetLeft(kzt1) || Canvas.GetTop(a[0])>=Canvas.GetTop(game))
            {
                MessageBoxResult b= MessageBox.Show("您已阵亡,是否重新开始?", "警告", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
                if (b== MessageBoxResult.Yes)
                {
                    timer1.Stop();//关闭计时器
                    a.Clear();//必须移除集合泛型中的所有元素
                    game.Children.Clear();//最后移除canvas中的所有元素
                    snake();//调用创建蛇的方法
                    foods();//叫用创建食物的方法
                    timer1.Start();//开启蛇移动的计时器
                                   //Application.Current.Shutdown(-1);//关闭应用程序
                                   // Environment.Exit(-1);//强制结束进程
                    kzt();
                }
                else
                {
                    Environment.Exit(-1);//强制退出
                }
            }
            
        }
        #endregion
        /// <summary>
        /// MainWindow_KeyDown表示在按下某个键触发的事件
        /// </summary>
        private void MainWindow_KeyDown(object sender, KeyEventArgs e)//键盘的触发事件
        {
            switch (e.Key)
            {
                //让第一节蛇先动,那如何获取第一际额蛇?可以用泛型集合来存储这4节蛇,并通过索引取出来
                //每一节蛇的tag默认为Right,通过改变第一节的方向来改变后边的方向
                case Key.Right:a[0].Tag = "Right";break;
                    //如果按下的键是Right,那么就改变第一节蛇的tag为Right,就退出swich分支语句
                case Key.Left: a[0].Tag = "Left";break;
                    //如果按下的键是Left,那么就改变第一节蛇的tag为Lift,就退出swich分支语句
                case Key.Up: a[0].Tag = "Up";break;
                    //如果按下的键是Up,那么就改变第一节蛇的tag为Up,就退出swich分支语句
                case Key.Down:a[0].Tag = "Down";break;
                    //如果按下的键是Down,那么就改变第一节蛇的tag为Down,就退出swich分支语句
            }
        }

        /// <summary>
        ///kzt表示控制台方法
        /// </summary>
        private void kzt() 
        {
            //实例化border来做一个父容器
            
            kzt1.Width = size*2;
            kzt1.Height = (yxgzsY-2)*size+3;
            kzt1.BorderThickness = new Thickness(1);
            kzt1.BorderBrush = Brushes.Black;
            kzt1.Background = Brushes.LightSteelBlue;
            kzt1.CornerRadius = new CornerRadius(20, 20, 20, 20);
            Canvas.SetLeft(kzt1, (yxgzsX+1) * size);
            game.Children.Add(kzt1);
            //开始按钮
            Button ks = new Button();
            ks.Content = "开始游戏";
            ks.Width = 80;
            ks.Height = 40;
            ImageBrush brush = new ImageBrush();
            brush.ImageSource = new BitmapImage(new Uri("E:/C#/C#文件/贪吃蛇游戏(终)/images/按钮背景.png"));
            ks.Background = brush;
            Canvas.SetLeft(ks, Canvas.GetLeft(kzt1) + 100);
            Canvas.SetTop(ks,200);
            game.Children.Add(ks);
            ks.Click += Ks_Click;
            //暂停游戏
            Button zt = new Button();
            zt.Content = "暂停游戏";
            zt.Width = 80;
            zt.Height = 40;
            ImageBrush brush1 = new ImageBrush();
            brush1.ImageSource = new BitmapImage(new Uri("E:/C#/C#文件/贪吃蛇游戏(终)/images/按钮背景.png"));
            zt.Background = brush1;
            Canvas.SetLeft(zt, Canvas.GetLeft(ks));
            Canvas.SetTop(zt, Canvas.GetTop(ks)+80);
            game.Children.Add(zt);
            zt.Click += Zt_Click;
            //积分
           
            lab.Content = "   分数:"+x;
            lab.Width = 80;
            lab.Height = 30;
            lab.Background = brush1;
            Canvas.SetLeft(lab,Canvas.GetLeft(ks));
            Canvas.SetTop(lab, 100);
            game.Children.Add(lab);



        }
        
        private void Zt_Click(object sender, RoutedEventArgs e)//暂停游戏事件
        {
            timer1.Stop();
        }

        private void Ks_Click(object sender, RoutedEventArgs e)//开始游戏的事件
        {
            timer1.Start();
        }

        /// <summary>
        /// snake 是私有的,封装蛇的方法
        /// </summary>
        private void snake()//创建蛇的方法
        {
            for (int i = 0; i < 4; i++)
            {
                Border snake1 = new Border();
                snake1.Width = snake1.Height = size;
                snake1.Tag = "Right";//默认4节蛇的tag为Right
                if (i==0)
                {
                    ImageBrush image2 = new ImageBrush();
                    image2.ImageSource = new BitmapImage(new Uri("E:/C#/C#文件/贪吃蛇游戏(终)/images/橙子.png"));
                    image2.Stretch = Stretch.Fill;//设置可以拉伸
                    snake1.Background = image2;
                }
                else
                {
                    ImageBrush image2 = new ImageBrush();
                    image2.ImageSource = new BitmapImage(new Uri("E:/C#/C#文件/贪吃蛇游戏(终)/images/青柠.png"));
                    image2.Stretch = Stretch.Fill;//设置可以拉伸
                    snake1.Background = image2;
                }
               
                //设置位置,yxgzsX取整后为17,yxgzsY/2取整数后为12
                snake1.CornerRadius = new CornerRadius(size / 2);
                Canvas.SetLeft(snake1, (yxgzsX/2) * size - i * size );
                Canvas.SetTop(snake1, (yxgzsY/2) * size);
                game.Children.Add(snake1);
                a.Add(snake1);//将实例化的4节蛇存储到集合a中
            }
           
        }
        /// <summary>
        /// foods 是私有的,封装食物的方法
        /// </summary>
        private void foods()//创建食物的方法
        {
           
            food.Width = food.Height = size;
            ImageBrush image3 = new ImageBrush();
            image3.ImageSource = new BitmapImage(new Uri("E:/C#/C#文件/贪吃蛇游戏(终)/images/食物1.png"));
            food.Background = image3;
            food.CornerRadius = new CornerRadius(size / 2);
            Canvas.SetLeft(food, ra.Next(2*size,(yxgzsX)*size));
            Canvas.SetTop(food, ra.Next(2*size,(yxgzsY-1)*size));
            game.Children.Add(food) ;
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329

九、总结

(1)这个案例的重点就是:蛇的移动、蛇的位置,控制蛇的方向,蛇吃食物长身体、蛇碰撞

(2)如果掌握了这个几点知识就是掌握了贪吃蛇中的精髓

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/1001553
推荐阅读
相关标签
  

闽ICP备14008679号