基于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分成功。

时间: 2024-10-06 00:29:21

基于C#开发的简易贪吃蛇的相关文章

C - 简易贪吃蛇的编写

不多废话,直接进入正题--用C编写简易贪吃蛇.附上拙劣的源码 * c-snake * 首先说明使画面动起来的原理:通过 system("cls"); 清除当前控制台的显示,再printf下一步画面进行显示,以此循环形成动画效果(类似手翻书).因为这是在控制台,难免会有晃眼的感觉,并且不存在美工一说,所以就将就下吧. 有了使画面动起来的方法,接下来就是贪吃蛇游戏本体的制作思路了,可将游戏本体分解为以下3个部分: 1.边界,即墙:圈定一个范围,蛇只能在墙内移动,食物只能生成在墙内 2.蛇:

Java 开发简单的贪吃蛇游戏

public class Test { public static void main(String[] args) { Game game = new Game(); game.start(); } } public class Node { private int x ; private int y ; public Node(){} public Node(int x , int y){ this.x = x ; this.y = y ; } public int getX() { ret

基于C# WPF框架的贪吃蛇

游戏开始界面 游戏开始 共有两条蛇,吃到红色食物加1分,吃到绿色毒食物减1分,知道0不减: 碰到墙壁游戏结束,碰到对方游戏结束,碰到自己游戏结束 此游戏通过Canvas画布布局,通过C#代码实现 游戏主界面大小为1200*1000 <Window x:Class="贪吃蛇__.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="h

简易贪吃蛇[Java]

偶然来了兴趣,简单的制作了一下 需要的同学可以进行参考 后续的很多功能大家还可以继续完善  图片文件  自己更改 新建package - model   新建Cell.java package model; public class Cell { public int x; public int y; // d direction 方向 public int d; // 设定常量:L 0 R 1 T 2 B 3 public static final int L=0; public static

C语言实现贪吃蛇之全靠数组篇

贪吃蛇游戏的设计思路很简单,相信有过一些编程经验的同学都不至于束手无策,可在我刚刚接触编程时,这个小小的贪吃蛇游戏可是让我费了不少脑筋,如今学习编程已经快一年了,前几天又看了一遍K&R,打算写几个贪吃蛇程序巩固一下知识.我打算写若干篇贪吃蛇的博客,从简单粗糙的开始,不断改良,希望能给初学C语言的同学一点借鉴. 话不多说,我们现在就开始吧,首先我们整理一下思路.首先我们要明确,既然贪吃蛇游戏理论上可以无限继续下去,那么游戏主体一定就是一个循环.蛇的移动就在这个循环中完成.如果是初学编程的话,可能会

基于控制台实现贪吃蛇游戏

1).引言 学习编程,我个人觉得最好的办法就是根据自己的水平不断的给自己设定一个小目标.而这个小目标就是一个有意思的项目,通过完成这个项目,对自己的成果(也包括失败的)进行分析总结,从中提炼出对应的技术并分享出来,不断的往复,如此,为的就是让我们永远保持编写程序的兴趣和热情,完了,还提高我们的技术.而本文就是总结自己的一个小目标(基于控制台实现的贪吃蛇游戏而写的总结) 2).技术实现 大家小时候一定玩过贪吃蛇的游戏.贪吃蛇游戏的控制过程其实也不复杂.简单的可以概括为以下4个部分. 1.1  .组

游戏开发(一)——控制台 贪吃蛇

贪吃蛇游戏设计中主要需要注意的几点: 1:坐标的定义:定义为左上角为(0,0),向右为x正方向,向下为y正方向 2:蛇的设计, 蛇身:m_body,这里用的是链表(是之前写好的双链表),一个节点就是蛇身的一节 每节蛇身的属性包括x,y坐标:column_x,row_y,x表示在地图上的第几列,y表示在地图上的第几行 蛇有一个属性叫朝向,也就是当前在往上.下.左.右的哪个方向移动:m_forward 蛇的动作有:Turn,转向.转向有个判断,就是不能向相反的方向转,比如本来向上运动,按向下键,是无

《结对-贪吃蛇游戏-开发环境搭建过程》

贪吃蛇开发环境搭建 Python和pygame的安装过程 成员0:2015035107074-孔令辉 成员1:2015035107067-张旭 1.去官网下载python和pygame.(需注意自己电脑是32位的还是64位的,我的是64位的,就下了个64位的) 2.安装pythone 和 pygame. 3.安装完成后,查看环境变量配置情况:计算机->属性->高级系统设置->环境变量->系统变量->Path. 4.在命令提示符中输入:python,验证是否安装成功,若提示是无

GameBuilder开发游戏应用系列之100行代码实现贪吃蛇

在线预览:http://osgames.duapp.com/apprun.html?appid=osgames1-801422234293697 在线编辑:http://osgames.duapp.com/gamebuilder.php?appid=osgames1-801422234293697 微信扫描: 运行截图: 除了重力感应游戏,GameBuilder开发传统的游戏也毫不逊色,作为一个怀旧的人,总是对这类游戏情有独钟. 贪吃蛇主要靠一个[UICanvas]来实现,前面一片博客GameB