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

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


效果图:

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

​ 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;//设置窗体居中显示
            
        }

​ 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;

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

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

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

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

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

二、创建蛇

​ 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、因为食物的位置是随机的,所以这里要创建随机函数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、蛇移动这里我们用到计时器,让计时器控制蛇移动的频率,这里创建计时器与Winfron中创建计时器不同,需要先导包

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

​ 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、因为蛇移动是有方向的,当按下键盘上的某个键就改变方向,所以这里要添加键盘事件

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

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

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

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

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

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

​ 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、蛇移动吃食物实际上就是蛇头和食物碰撞,碰撞就是相等,就是蛇的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、是碰到自己的身体肯定就是蛇边长以后蛇头碰住蛇尾往前的位置,所以就可以用到刚刚的那么倒着遍历的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);//关闭应用程序
                    }
                }

​ 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、显示积分控件

​ (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面板中

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;

按钮事件

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

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

八、全部代码

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
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

御弟謌謌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值