zoukankan      html  css  js  c++  java
  • 基于C#开发的简易贪吃蛇

    最近一直忙着11月份软考的复习,一直没有练习C#。觉得对于一个新手,长时间不练肯定不行,所以觉得敲敲代码练练手。刚好电脑磁盘里有以前Down的C#开源游戏,于是挑中了贪吃蛇,来练练手。

    贪吃蛇游戏界面如下:

    为了实现贪吃蛇,一共写了四个类,分别是:

    1)Bean:食物类,就是玩家要吃的那个食物,里面实现了两个方法:食物的显示与食物的消失(因为食物被吃了以后应该消失)

    2)Block:蛇块类,就是组成蛇的单元,玩家吃到食物,蛇的蛇块增加一节。

    3)Snake:蛇类,游戏中的主角,玩家通过上下左右四个键来控制蛇的运动。

    4)Map:地图类,用于画出游戏主界面,通过定时器来控制,每个单元时间重新画一幅地图,用于动态显示

    以下是代码的实现

     1 //食物类
     2     public class Bean
     3     {
     4         //用于画食物的顶端坐标
     5         private Point _origin;
     6 
     7         public Point Origin
     8         {
     9             get { return _origin; }
    10             set { _origin = value; }
    11         }
    12 
    13         //显示食物
    14         public void ShowBean(Graphics g)
    15         {
    16             //定义红色的画笔
    17             SolidBrush brush = new SolidBrush(Color.Red);
    18             //画实心矩形表示食物
    19             g.FillRectangle(brush,Origin.X,Origin.Y,15,15);
    20         }
    21 
    22         public void UnShowBean(Graphics g)
    23         {
    24             //定义系统背景颜色的画笔
    25             SolidBrush brush = new SolidBrush(Color.Silver);
    26             //画实心矩形颜色为系统背景颜色,相当于食物被吃掉了
    27             g.FillRectangle(brush,Origin.X,Origin.Y,15,15);
    28         }
    29     }
    //蛇身体的每一单元,简称块
        public class Block
        {
            //是否为蛇头
            private bool _isHead;
    
            public bool IsHead
            {
                get { return _isHead; }
                set { _isHead = value; }
            }
            //蛇块的编号
            private int _blockNumber;
    
            public int BlockNumber
            {
                get { return _blockNumber; }
                set { _blockNumber = value; }
            }
            //蛇块的左上角位置
            private Point _origin;
    
            public Point Origin
            {
                get { return _origin; }
                set { _origin = value; }
            }
    
            //根据指定位置画蛇块
            public void ShowBlock(Graphics g)
            {
                Bitmap bitMap;
                if (IsHead)
                {
                    //蛇头
                    bitMap = new Bitmap(Image.FromFile("Blue.gif"));                
                }
                else
                {
                    bitMap = new Bitmap(Image.FromFile("Yellow.gif"));
                }
                g.DrawImage(bitMap,Origin.X,Origin.Y,15,15);
            }
    
            //消除蛇块
            public void UnShowBlock(Graphics g)
            {
                SolidBrush brush = new SolidBrush(Color.Silver);
                g.FillRectangle(brush,Origin.X,Origin.Y,15,15);
            }
        }
      1 public class Snake
      2     {
      3         //用于存放蛇的集合
      4         private List<Block> blocksList;
      5         //0-上,1-右,2-下,3-左
      6         private int direction = 1;
      7         //蛇头的编号,蛇的长度
      8         private int headNumber;
      9         //蛇头左上角坐标
     10         private Point headPoint;
     11         private Point mapLeft;
     12         //游戏开始时,初始的蛇
     13         public Snake(Point map, int count)
     14         {
     15             mapLeft = map;
     16             Block blockSnake;
     17             //定义蛇的起始位置(蛇尾)
     18             Point p = new Point(map.X + 15, map.Y + 15);
     19             blocksList = new List<Block>();
     20             //循环画蛇块用于填充蛇集合
     21             for (int i = 0; i < count; i++)
     22             {
     23                 //x坐标加15
     24                 p.X += 15;
     25                 //实例化蛇块
     26                 blockSnake = new Block();
     27                 //定义蛇块的左上角位置 
     28                 blockSnake.Origin = p;
     29                 //定义蛇块的编号1,2,3...
     30                 blockSnake.BlockNumber = i + 1;
     31                 if (i == count - 1)
     32                 {
     33                     //蛇头
     34                     //给蛇头位置赋值
     35                     headPoint = blockSnake.Origin;
     36                     blockSnake.IsHead = true;
     37                 }
     38                 blocksList.Add(blockSnake);
     39 
     40             }
     41             //蛇的长度赋值
     42             headNumber = count;
     43         }
     44         //蛇头坐标的只读属性
     45         public Point HeadPoint
     46         {
     47             get { return headPoint; }
     48         }
     49         //蛇的运动方向的属性
     50         public int Direction
     51         {
     52             get { return direction; }
     53             set { direction = value; }
     54         }
     55         /// <summary>
     56         /// 蛇的转换方向
     57         /// </summary>
     58         /// <param name="pDirection">想要改变的方向</param>
     59         public void TurnDirection(int pDirection)
     60         {
     61             switch (direction)
     62             {
     63                 //原来向上运动
     64                 case 0:
     65                     //希望向左运动
     66                     if (pDirection == 3)
     67                         direction = 3;
     68                     //希望向右运动
     69                     else if (pDirection == 1)
     70                         direction = 1;
     71                     break;
     72                 //原来向右运动
     73                 case 1:
     74                     //
     75                     if (pDirection == 2)
     76                         direction = 2;
     77                     //
     78                     else if (pDirection == 0)
     79                         direction = 0;
     80                     break;
     81                 case 2:
     82                     if (pDirection == 1)
     83                         direction = 1;
     84                     else if (pDirection == 3)
     85                         direction = 3;
     86                     break;
     87                 case 3:
     88                     if (pDirection == 0)
     89                         direction = 0;
     90                     else if (pDirection == 2)
     91                         direction = 2;
     92                     break;
     93 
     94 
     95             }
     96         }
     97 
     98         public Point getHeadPoint //只读蛇头位置属性
     99         {
    100             get { return headPoint; }
    101         }
    102         //蛇吃到食物后变长,蛇头+1
    103         public void SnakeGrowth()
    104         { 
    105             //找到蛇头的坐标
    106             Point head = blocksList[blocksList.Count - 1].Origin;
    107             int x = head.X;
    108             int y = head.Y;
    109             //判断蛇的运动方向,改变蛇头的位置
    110             switch (direction)
    111             {
    112                 case 0:
    113                     //向上运动
    114                     y -= 15;
    115                     break;
    116                 case 1:
    117                     x += 15;
    118                     break;
    119                 case 2:
    120                     y += 15;
    121                     break;
    122                 case 3:
    123                     x -= 15;
    124                     break;
    125             }
    126             //把原先蛇头的块变为普通块
    127             blocksList[blocksList.Count - 1].IsHead = false;
    128             //实例化新蛇头
    129             Block headNew = new Block();
    130             headNew.IsHead = true;
    131             headNew.BlockNumber = blocksList.Count + 1;
    132             headNew.Origin = new Point(x,y);
    133             blocksList.Add(headNew);
    134             headNumber++;
    135             headPoint = headNew.Origin;
    136         }
    137 
    138         //蛇向前运动(没有吃到食物的情况),蛇尾移除,蛇头移位+1
    139         public void Go(Graphics g)
    140         {
    141             Block snakeTail = blocksList[0];
    142             //消除蛇尾块
    143             snakeTail.UnShowBlock(g);
    144             //集合中移除设为块
    145             blocksList.RemoveAt(0);
    146             foreach (var item in blocksList)
    147             {
    148                 item.BlockNumber--;
    149             }
    150             //由于SnakeGrowth中仅仅使蛇头+1,但是headNumber++了。但是此值并没有改变,所以先--
    151             headNumber--;
    152             SnakeGrowth();
    153         }
    154 
    155         //画出蛇
    156         public void ShowSnake(Graphics g)
    157         {
    158             foreach (var item in blocksList)
    159             {
    160                 item.ShowBlock(g);
    161             }
    162         }
    163         //隐藏蛇
    164         public void UnShowSnake(Graphics g)
    165         {
    166             foreach (var item in blocksList)
    167             {
    168                 item.UnShowBlock(g);
    169             }
    170         }
    171         //重置蛇
    172         public void Reset(Point map, int count)
    173         {  
    174             Block blockSnake;
    175             //定义蛇的起始位置(蛇尾)
    176             Point p = new Point(mapLeft.X + 15, mapLeft.Y + 15);
    177             blocksList = new List<Block>();
    178             //循环画蛇块用于填充蛇集合
    179             for (int i = 0; i < count; i++)
    180             {
    181                 //x坐标加15
    182                 p.X += 15;
    183                 //实例化蛇块
    184                 blockSnake = new Block();
    185                 //定义蛇块的左上角位置 
    186                 blockSnake.Origin = p;
    187                 //定义蛇块的编号1,2,3...
    188                 blockSnake.BlockNumber = i + 1;
    189                 if (i == count - 1)
    190                 {
    191                     //蛇头
    192                     //给蛇头位置赋值
    193                     headPoint = blockSnake.Origin;
    194                     blockSnake.IsHead = true;
    195                 }
    196                 blocksList.Add(blockSnake);
    197 
    198             }
    199             //蛇的长度赋值
    200             headNumber = count;
    201             direction = 1;
    202         }
    203         //是否碰到自己
    204         public bool IsTouchMyself()
    205         {
    206             bool isTouched = false;
    207             for (int i = 0; i < blocksList.Count-1; i++)
    208             {
    209                 if (headPoint == blocksList[i].Origin)
    210                 {
    211                     isTouched = true;
    212                     break;
    213                 }
    214             }
    215             return isTouched;
    216         }
    217     }
      1 public class Map
      2     {
      3         private Point mapLeft;
      4         private static int unit = 15;
      5         //定义地图长,为28个蛇块的长度
      6         private readonly int length = 30 * unit;
      7         //定义地图宽,为20个蛇块的宽度
      8         private readonly int width = 25 * unit;
      9         //定义分数
     10         public int score = 0;
     11         //定义蛇
     12         private readonly Snake snake;
     13         public bool victory = false;
     14         public Snake Snake
     15         {
     16             get { return snake; }
     17         } 
     18 
     19         Bean food;
     20         public Map(Point start)
     21         {
     22             //把地图左上角的点的值赋值给全局变量
     23             mapLeft = start;
     24             //实例化蛇
     25             snake = new Snake(start,5);
     26             //实例化食物
     27             food = new Bean();
     28             food.Origin = new Point(start.X+30,start.Y+30);
     29         }
     30         //显示新食物
     31         public void ShowNewFood(Graphics g)
     32         {
     33             //消除原先食物
     34             food.UnShowBean(g);
     35             //产生随机位置的食物
     36             food = FoodRandom();
     37             //显示食物
     38             food.ShowBean(g);
     39         }
     40         //随机产生一个新食物
     41         private Bean FoodRandom()
     42         {
     43             Random d=new Random ();
     44             int x = d.Next(0, length / unit);
     45             int y = d.Next(0, width / unit);
     46             Point origin = new Point(mapLeft.X+x*15,mapLeft.Y+y*15);
     47             Bean food = new Bean();
     48             food.Origin = origin;
     49             return food;
     50         }
     51         //画地图
     52         public void ShowMap(Graphics g)
     53         {
     54             //创建一支红笔
     55             Pen pen = new Pen(Color.Blue);
     56             //画出地图的框
     57             g.DrawRectangle(pen,mapLeft.X,mapLeft.Y,length,width);
     58             //显示食物
     59             food.ShowBean(g);
     60             if (CheckBean())
     61             {
     62                 //吃到了食物
     63                 //显示新食物
     64                 ShowNewFood(g);
     65                 //蛇变长
     66                 snake.SnakeGrowth();
     67                 //分数增加
     68                 score += 10;
     69                 //if (score >= 100)
     70                 //{
     71                 //    victory = true;
     72                 //}
     73                 //显示蛇
     74                 snake.ShowSnake(g);
     75             }
     76             else
     77             {
     78                 snake.Go(g);
     79                 snake.ShowSnake(g);
     80             }
     81         }
     82         //判断是否吃到了食物
     83         public bool CheckBean()
     84         {
     85             
     86             return food.Origin.Equals(snake.HeadPoint);
     87         }
     88 
     89         //检查蛇是否撞墙
     90         public bool CheckSnake()
     91         {
     92             return !(snake.getHeadPoint.X > mapLeft.X-5 && snake.getHeadPoint.X < (mapLeft.X + length-5) && snake.getHeadPoint.Y > mapLeft.Y-5 && snake.getHeadPoint.Y < (mapLeft.Y + width -5));
     93         }
     94 
     95         //重新开始
     96         public void Reset(Graphics g)
     97         {
     98             snake.UnShowSnake(g);
     99             snake.Reset(mapLeft,5);
    100         }
    101     }
      1 这是窗体的代码
      2 public frmMain()
      3         {
      4             InitializeComponent();
      5             //定义地图
      6             map = new Map(new Point(50,50));
      7             BackColor = Color.Silver;
      8         }
      9         private readonly Map map;
     10         private int gradeNum = 100;
     11         private int pink;
     12         private void frmMain_Load(object sender, EventArgs e)
     13         {
     14             SetStyle(
     15                ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
     16             UpdateStyles();
     17         }
     18 
     19         private void timer1_Tick(object sender, EventArgs e)
     20         {
     21             //this.BackgroundImage = Image.FromFile(pink+".jpg");
     22             开始ToolStripMenuItem.Text = "重新开始";           
     23             lblScore.Text = map.score.ToString();
     24             if (map.score >= 500)
     25             {
     26                 timer1.Enabled = false;
     27                 MessageBox.Show("恭喜,成功!!!");
     28             }
     29             Bitmap bmp = new Bitmap(Width, Height);
     30             //Image face = Image.FromFile("1.jpg");
     31             BackgroundImage = bmp;
     32             Graphics g = Graphics.FromImage(bmp);
     33             map.ShowMap(g);
     34             if (map.CheckSnake()||map.Snake.IsTouchMyself())
     35             {
     36                 timer1.Enabled = false;
     37                 MessageBox.Show("很遗憾,失败了!!!");
     38             }
     39             
     40         }
     41         //键盘响应事件
     42         private void frmMain_KeyDown(object sender, KeyEventArgs e)
     43         {
     44             int k, d = 0;
     45             k = e.KeyValue;
     46             if (k == 37) //
     47                 d = 3;
     48             else if (k == 40) //
     49                 d = 2;
     50             else if (k == 38) //
     51                 d = 0;
     52             else if (k == 39) //
     53                 d = 1;
     54             map.Snake.TurnDirection(d);
     55         }
     56 
     57         private void 开始ToolStripMenuItem_Click(object sender, EventArgs e)
     58         {
     59             if (lblGrade.Text == "")
     60             {
     61                 MessageBox.Show("请先选择级别");
     62                 return;
     63             }
     64             if (开始ToolStripMenuItem.Text == "开始")
     65             {                
     66                 开始ToolStripMenuItem.Text = "重新开始";
     67                 timer1.Enabled = true;
     68             }
     69             else if (开始ToolStripMenuItem.Text == "重新开始")
     70             {
     71                 开始ToolStripMenuItem.Text = "开始";
     72                 继续ToolStripMenuItem.Text = "暂停";
     73                 timer1.Enabled = true;
     74                 map.Reset(CreateGraphics());
     75                 map.score = 0;
     76             }
     77 
     78         }
     79 
     80         private void 继续ToolStripMenuItem_Click(object sender, EventArgs e)
     81         {
     82             if (继续ToolStripMenuItem.Text == "继续")
     83             {
     84                 继续ToolStripMenuItem.Text = "暂停";
     85                 timer1.Enabled = true;
     86             }
     87             else if(继续ToolStripMenuItem.Text == "暂停")
     88             {
     89                 继续ToolStripMenuItem.Text = "继续";
     90                 timer1.Enabled = false;
     91             }
     92         }
     93 
     94         private void 低级ToolStripMenuItem_Click(object sender, EventArgs e)
     95         {
     96             gradeNum = 200;
     97             lblGrade.Text = "菜鸟";
     98             timer1.Interval = gradeNum;
     99         }
    100 
    101         private void 中级ToolStripMenuItem_Click(object sender, EventArgs e)
    102         {
    103             gradeNum = 150;
    104             lblGrade.Text = "平民";
    105             timer1.Interval = gradeNum;
    106         }
    107 
    108         private void 高级ToolStripMenuItem_Click(object sender, EventArgs e)
    109         {
    110             gradeNum = 100;
    111             lblGrade.Text = "高手";
    112             timer1.Interval = gradeNum;
    113         }
    114 
    115         private void 大神ToolStripMenuItem_Click(object sender, EventArgs e)
    116         {
    117             gradeNum = 50;
    118             lblGrade.Text = "大神";
    119             timer1.Interval = gradeNum;
    120         }
    121 
    122         private void 肤色1ToolStripMenuItem_Click(object sender, EventArgs e)
    123         {
    124             this.BackgroundImage = Image.FromFile("1.jpg");
    125             pink = 1;
    126         }
    127 
    128         private void 肤色2ToolStripMenuItem_Click(object sender, EventArgs e)
    129         {
    130             this.BackgroundImage = Image.FromFile("2.jpg");
    131             pink = 2;
    132         }
    133     }

    编程过程借鉴了网路大神的帮忙。

    还有一个问题,希望看到的大神可以帮忙解决:原本希望把选择级别菜单下的几个级别都注册成一个点击事件,再通过switch判断点击的级别的text属性,再作出相应操作,但是不知道在代码中怎么得到被点击的级别的对象,所以方法实现不了。

    也就是说,我想实现的效果是把菜单中的几个按钮的点击事件注册成一个事件,但是在写代码的过程中,不知道怎么才能得到被点击按钮(Button clickedBtn=sender as Button 不对,但也不知道还有什么其他的方法)的对象,也就无法确定点击的是哪个按钮。

    肤色的单元还没有实现,有待优化。

    游戏方法:点击菜单栏中的选择级别,选择一个级别,按F2开始游戏,游戏过程中可以按F4暂停,继续游戏,每吃到一个食物加10分,达到500分成功。

  • 相关阅读:
    python 代码片段17
    python 代码片段15
    python 代码片段14
    python 代码片段13
    python 代码片段12
    RBAC模型
    2、服务注册与发现-电影服务
    1、通过eureka创建注册中心
    prop与attr
    位运算,效率高
  • 原文地址:https://www.cnblogs.com/pushudepu/p/5962150.html
Copyright © 2011-2022 走看看