设置贪吃蛇的步骤:
step1:设置贪吃蛇的界面,包含一个menustrip,timer,panel和两个label,如下图所示。
menustrip的属性中有item,设置为 如下图所示
setp2:Form1窗体的代码为:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace 贪吃蛇
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static bool ifStart = false;//判断是否开始
public static int career = 400;//移动的速度
Snake snake = new Snake();//实例化Snake类
int snake_W = 20;//骨节的宽度
int snake_H = 20;//骨节的高度
public static bool pause = false;//是否暂停游戏
/// <summary>
/// 绘制游戏场景
/// </summary>
/// <param g="Graphics">封装一个GDI+绘图图面</param>
public void ProtractTable(Graphics g)
{
for (int i = 0; i <= panel1.Width / snake_W; i++)//绘制单元格的纵向线
{
g.DrawLine(new Pen(Color.Black, 1), new Point(i * snake_W, 0), new Point(i * snake_W, panel1.Height));
}
for (int i = 0; i <= panel1.Height / snake_H; i++)//绘制单元格的横向线
{
g.DrawLine(new Pen(Color.Black, 1), new Point(0, i * snake_H), new Point(panel1.Width, i * snake_H));
}
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
Graphics g = panel1.CreateGraphics();//创建panel1控件的Graphics类
ProtractTable(g);//绘制游戏场景
if (!ifStart)//如是没有开始游戏
{
Snake.timer = timer1;
Snake.label = label2;
snake.Ophidian(panel1, snake_W);//初始化场地及贪吃蛇信息
}
else
{
for (int i = 0; i < Snake.List.Count; i++)//绘制蛇身
{
e.Graphics.FillRectangle(Snake.SolidB, ((Point)Snake.List[i]).X + 1, ((Point)Snake.List[i]).Y + 1, snake_W - 1, snake_H - 1);
}
e.Graphics.FillRectangle(Snake.SolidF, Snake.Food.X + 1, Snake.Food.Y + 1, snake_W - 1, snake_H - 1);//绘制食物
if (Snake.ifGame)//如果游戏结束
//绘制提示文本
e.Graphics.DrawString("Game Over", new Font("宋体", 30, FontStyle.Bold), new SolidBrush(Color.DarkSlateGray), new PointF(150, 130));
}
}
private void 开始ToolStripMenuItem_Click(object sender, EventArgs e)
{
NoviceCortrol(Convert.ToInt32(((ToolStripMenuItem)sender).Tag.ToString()));
snake.BuildFood();
textBox1.Focus();
}
/// <summary>
/// 控制游戏的开始、暂停和结束
/// </summary>
/// <param n="int">标识</param>
public void NoviceCortrol(int n)
{
switch (n)
{
case 1://开始游戏
{
ifStart = false;
Graphics g = panel1.CreateGraphics();//创建panel1控件的Graphics类
g.FillRectangle(Snake.SolidD, 0, 0, panel1.Width, panel1.Height);//刷新游戏场地
ProtractTable(g);//绘制游戏场地
ifStart = true;//开始游戏
snake.Ophidian(panel1, snake_W);//初始化场地及贪吃蛇信息
timer1.Interval = career;//设置贪吃蛇移动的速度
timer1.Start();//启动计时器
pause = true;//是否暂停游戏
label2.Text = "0";//显示当前分数
break;
}
case 2://暂停游戏
{
if (pause)//如果游戏正在运行
{
ifStart = true;//游戏正在开始
timer1.Stop();//停止计时器
pause = false;//当前已暂停游戏
}
else
{
ifStart = true;//游戏正在开始
timer1.Start();//启动计时器
pause = true;//开始游戏
}
break;
}
case 3://退出游戏
{
timer1.Stop();//停止计时器
Application.Exit();//半闭工程
break;
}
}
}
private void 初级ToolStripMenuItem_Click(object sender, EventArgs e)
{
if (timer1.Enabled == false)//如果游戏没有开始
{
初级ToolStripMenuItem.Checked = false;//设置该项没有被选中
中级ToolStripMenuItem.Checked = false;//设置该项没有被选中
高级ToolStripMenuItem.Checked = false;//设置该项没有被选中
((ToolStripMenuItem)sender).Checked = true;//设置当前项被选中
switch (Convert.ToInt32(((ToolStripMenuItem)sender).Tag.ToString()))
{
case 1://高级
{
career = 400;//设置移动的速度
break;
}
case 2://中级
{
career = 200;
break;
}
case 3://初
{
career = 50;
break;
}
}
}
textBox1.Focus();//获得焦点
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
int tem_n = -1;//记录移动键值
if (e.KeyCode == Keys.Right)//如果按→键
tem_n = 0;//向右移
if (e.KeyCode == Keys.Left)//如果按←键
tem_n = 1;//向左移
if (e.KeyCode == Keys.Up)//如果按↑键
tem_n = 2;//向上移
if (e.KeyCode == Keys.Down)//如果按↓键
tem_n = 3;//向下移
if (tem_n != -1 && tem_n != Snake.Aspect)//如果移动的方向不是相同方向
{
if (Snake.ifGame == false)
{
//如果移动的方向不是相反的方向
if (!((tem_n == 0 && Snake.Aspect == 1 || tem_n == 1 && Snake.Aspect == 0) || (tem_n == 2 && Snake.Aspect == 3 || tem_n == 3 && Snake.Aspect == 2)))
{
Snake.Aspect = tem_n;//记录移动的方向
snake.SnakeMove(tem_n);//移动贪吃蛇
}
}
}
int tem_p = -1;//记录控制键值
if (e.KeyCode == Keys.F2)//如果按F2键
tem_p = 1;//开始游戏
if (e.KeyCode == Keys.F3)//如果按F3键
tem_p = 2;//暂停或继续游戏
if (e.KeyCode == Keys.F4)//如果按F4键
tem_p = 3;//关闭游戏
if (tem_p != -1)//如果当前是操作标识
NoviceCortrol(tem_p);//控制游戏的开始、暂止和关闭
}
private void timer1_Tick(object sender, EventArgs e)
{
snake.SnakeMove(Snake.Aspect);//移动贪吃蛇
}
}
}
step3:另外还要写一个Snake类:
using System;
using System.Collections;
using System.Drawing;
using System.Windows.Forms;
namespace 贪吃蛇
{
class Snake
{
public static int Condyle = 0;//设置骨节的大小
public static int Aspect = 0;//设置方向
public static Point[] Place = { new Point(-1, -1), new Point(-1, -1), new Point(-1, -1), new Point(-1, -1), new Point(-1, -1), new Point(-1, -1) };//设置个骨节的位置
public static Point Food = new Point(-1, -1);//设置食物的所在点
public static bool ifFood = false;//是否有食物
public static bool ifGame = false;//游戏是否结束
public static int Field_width = 0;//场地的宽度
public static int Field_Height = 0;//场地的高度
public static Control control;//记录绘制贪吃蛇的控件
public static Timer timer;//记录Timer组件
public static SolidBrush SolidB = new SolidBrush(Color.Red);//设置贪吃蛇身体的颜色
public static SolidBrush SolidD = new SolidBrush(Color.White);//设置背景颜色
public static SolidBrush SolidF = new SolidBrush(Color.Blue);//设置食物的颜色
//public static SolidBrush Solid = new SolidBrush(TextBox.DefaultBackColor);
//public static SolidBrush SolidE = new SolidBrush(Text."#");//设置食物的xingzhuang
public static Label label;//记录Label控件
public static ArrayList List = new ArrayList();//实例化ArrayList数组
Graphics g;//实例化Graphics类
/// <summary>
/// 初始化场地及贪吃蛇的信息
/// </summary>
/// <param Con="Control">控件</param>
/// <param condyle="int">骨节大小</param>
public void Ophidian(Control Con, int condyle)
{
Field_width = Con.Width;//获取场地的宽度
Field_Height = Con.Height;//获取场地的高度
Condyle = condyle;//记录骨节的大小
control = Con;//记录背景控件
g = control.CreateGraphics();//创建背景控件的Graphics类
SolidD = new SolidBrush(Con.BackColor);//设置画刷颜色
for (int i = 0; i < Place.Length; i++)//绘制贪吃蛇
{
Place[i].X = (Place.Length - i - 1) * Condyle;//设置骨节的横坐标位置
Place[i].Y = (Field_Height / 2) - Condyle;//设置骨节的纵坐标位置
g.FillRectangle(SolidB, Place[i].X + 1, Place[i].Y + 1, Condyle - 1, Condyle - 1);//绘制骨节
}
List = new ArrayList(Place);//记录每个骨节的位置
ifGame = false;//停止游戏
Aspect = 0;//设置方向为右
}
/// <summary>
/// 移动贪吃蛇
/// </summary>
/// <param n="int">标识,判断的移动的方向</param>
public void SnakeMove(int n)
{
Point tem_Point = new Point(-1, -1);//定义坐标结构
switch (n)
{
case 0://右移
{
tem_Point.X = ((Point)List[0]).X + Condyle;//蛇头向右移
tem_Point.Y = ((Point)List[0]).Y;
break;
}
case 1://左移
{
tem_Point.X = ((Point)List[0]).X - Condyle;//蛇头向左移
tem_Point.Y = ((Point)List[0]).Y;
break;
}
case 2://上移
{
tem_Point.Y = ((Point)List[0]).Y - Condyle;//蛇头向上移
tem_Point.X = ((Point)List[0]).X;
break;
}
case 3://下移
{
tem_Point.Y = ((Point)List[0]).Y + Condyle;//蛇头向下移
tem_Point.X = ((Point)List[0]).X;
break;
}
}
BuildFood();//生成食物
if (!EstimateMove(tem_Point))//如果没有向相反的方向移动
{
Aspect = n;//改变贪吃蛇的移动方向
bool aa = false;
tem_Point = GameAborted(tem_Point, ref aa);
if (!aa)//如果游戏没有结束
{
ProtractSnake(tem_Point);//重新绘制蛇身
EatFood();//吃食
}
g.FillRectangle(SolidF, Food.X + 1, Food.Y + 1, Condyle - 1, Condyle - 1);//绘制食物
Console.WriteLine(" " + ((Point)List[0]).X);
}
}
/// <summary>
/// 吃食
/// </summary>
public void EatFood()
{
if (((Point)List[0]) == Food)//如果蛇头吃到了食物
{
List.Add(List[List.Count - 1]);//在蛇的尾部添加蛇身
ifFood = false;//没有食物
BuildFood();//生成食物
label.Text = Convert.ToString(Convert.ToInt32(label.Text) + 5);//显示当前分数
}
}
/// <summary>
/// 游戏是否失败
/// </summary>
/// <param GameP="Point">设置文本的显示位置</param>
public Point GameAborted(Point GameP, ref bool isGameOver)
{
Point temp = GameP;
//bool tem_b = false;//游戏是否结束
bool tem_body = false;//记录蛇身是否重叠
for (int i = 1; i < List.Count; i++)//遍历所有骨节
{
if (((Point)List[0]) == ((Point)List[i]))//如是骨节重叠
{
tem_body = true;//游戏失败
break;
}
}
if (tem_body)
{
//绘制游戏结束的提示文本
g.DrawString("Game Over", new Font("宋体", 35, FontStyle.Bold), new SolidBrush(Color.DarkSlateGray), new PointF(150, 130));
ifGame = true;//游戏结束
isGameOver = true;
timer.Stop();//停止记时器
}
//判断蛇头是否超出游戏场地
if (GameP.X <= -20)
{
temp = new Point(((Point)List[0]).Y,0 ); ;
//Point temp = new Point(control.Width - 1, ((Point)List[0]).Y);
//List[0] = temp;//panel1.Width
}
else if (GameP.X >= control.Width - 1)
{
temp = new Point(0, ((Point)List[0]).Y);
//((Point)List[0]).X = -20;
//绘制游戏结束的提示文本
//g.DrawString("Game Over", new Font("宋体", 35, FontStyle.Bold), new SolidBrush(Color.DarkSlateGray), new PointF(150, 130));
//ifGame = true;//游戏结束
//timer.Stop();//停止记时器
//tem_b = true;
//tem_b = false;
}
else if (GameP.Y <= -20)
{
temp = new Point(0,((Point)List[0]).X);
//temp = new Point(control.Width - 1, ((Point)List[0]).Y);
//List[0] = temp;//panel1.Width
//((Point)List[0]).Y = ccontrol.Height - 1;
}
else if (GameP.Y >= control.Height - 1)
{
temp = new Point(((Point)List[0]).X, 0);
//temp = new Point(control.Width - 1, ((Point)List[0]).X);
//List[0] = temp;//panel1.Width
//((Point)List[0]).Y = -20;
}
return temp;
}
/// <summary>
/// 判断蛇是否向相反的方向移动
/// </summary>
/// <param Ep="Point">移动的下一步位置</param>
public bool EstimateMove(Point Ep)
{
bool tem_bool = false;//记录蛇头是否向相反的方向移动
if (Ep.X == ((Point)List[0]).X && Ep.Y == ((Point)List[0]).Y)//如果蛇头向相反的方向移动
tem_bool = true;
return tem_bool;
}
/// <summary>
/// 重新绘制蛇身
/// </summary>
public void ProtractSnake(Point Ep)
{
bool tem_bool = false;//是否清除移动后的蛇身
List.Insert(0, Ep);//根据蛇头的移动方向,设置蛇头的位置
Point tem_point = ((Point)List[List.Count-1]);//记录蛇尾的位置
List.RemoveAt(List.Count - 1);//移除蛇的尾部
//使骨节向前移动一位
for (int i = 0; i < List.Count - 1; i++)
{
if (tem_point == ((Point)List[i]))
tem_bool = true;
}
if (!tem_bool)//清除贪吃蛇移动前的蛇尾部份
g.FillRectangle(SolidD, tem_point.X + 1, tem_point.Y + 1, Condyle - 1, Condyle - 1);
for (int i = 0; i < List.Count; i++)//重新绘制蛇身
{
g.FillRectangle(SolidB, ((Point)List[0]).X + 1, ((Point)List[0]).Y + 1, Condyle - 1, Condyle - 1);
}
}
/// <summary>
/// 生成食物
/// </summary>
public void BuildFood()
{
if (ifFood == false)//如果没有食物
{
Point tem_p = new Point(-1, -1);//定义坐标结构
bool tem_bool = true;//是否计算出食物的合位置
bool tem_b = false;//判断食物是否和蛇身重叠
while (tem_bool)//计算食物的显示位置
{
tem_b = false;
tem_p = RectFood();//随机生成食物的位置
for (int i = 0; i < List.Count; i++)//遍历整个蛇身的位置
{
if (((Point)List[i]) == tem_p)//如果食物是否和蛇身重叠
{
tem_b = true;//记录重叠
break;
}
}
if (tem_b == false)//如果没有重叠
tem_bool = false;//退出循环
}
Food = tem_p;//记录食物的显示位置
}
ifFood = true;//有食物
}
/// <summary>
/// 随机生成食物的节点
/// </summary>
public Point RectFood()
{
int tem_W = Field_width / 20;//获取场地的行数
int tem_H = Field_Height / 20;//获取场地的列数
Random RandW = new Random();//实例化Random类
tem_W=RandW.Next(0, tem_W - 1);//生成食物的横向坐标
Random RandH = new Random();//实例化Random类
tem_H = RandH.Next(0, tem_H - 1);//生成食物的纵向坐标
Point tme_P = new Point(tem_W * Condyle, tem_H * Condyle);//生成食物的显示位置
return tme_P;
}
}
}
以上就是贪吃蛇的完整代码,可穿墙哦!!!