1.画背景格子
在for循环中利用Graphics.DrawLine方法绘制横线和竖线
2.如何画蛇
利用List数组存储蛇的位置
,为了更方便简洁,画蛇之前先封装画格子函数,画蛇时调用这个函数,只需给出蛇的坐标即可
3.清除蛇
原理原理同画蛇,只是颜色换成了背景色
4.蛇的移动
原理是将最后一个格子放到第一个,即实现移动
利用LIst数组 List.RemoveAt删除末尾的坐标, List.Insert在第0个位置插入新的坐标
5.蛇的生长
5.蛇的生长
定义一个全局变量用来记录蛇尾巴的坐标(蛇前进之前)蛇前进一格吃到食物时,在原来蛇尾巴位置添加一个格子,即完成蛇的一次生长
6.game over问题
当蛇咬到自身或者触碰到边界时,游戏结束
7.全部代码
namespace 贪吃蛇
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Graphics _Graphics = null;
//存蛇位置和形状
List<int> Xs = new List<int>();
List<int> Ys = new List<int>();
Random rd = new Random();
int _XFood;
int _YFood ; //食物的位置
int _XTail;//记录尾巴的位置
int _YTail;
private string _MoveDir = " ";
SoundPlayer _BGM = new SoundPlayer("music.wav"); //背景音乐
private void panel1_Paint(object sender, PaintEventArgs e)
{
Pen mypen = new Pen(Color.White, 1);
for (int i = 0; i < 31; i++) //绘制网格30*30
{
Point x1Point = new Point(0, i * 20);
Point y1Point = new Point(600, i * 20);
this._Graphics.DrawLine(mypen, x1Point, y1Point);
Point x2Point = new Point(i * 20,0);
Point y2Point = new Point( i * 20,600);
this._Graphics.DrawLine(mypen, x2Point, y2Point);
}
Xs.Add(2);
Ys.Add(4);
Xs.Add(2);
Ys.Add(3);
Xs.Add(2);
Ys.Add(2);
DrawSnake();
_BGM.Play(); //播放背景音乐
CreatFood();
}
private void Form1_Load(object sender, EventArgs e)
{
this._Graphics = panel1.CreateGraphics();
this.timer1.Interval = 250; //游戏间隔时间
this.timer1.Start();
}
/// <summary>
/// 随机产生食物
/// </summary>
private void CreatFood()
{
_XFood = rd.Next(0, 29);
_YFood = rd.Next(0, 29);
bool food_is_ok=true ;
for (int i = 0; i < this.Xs.Count; i++)
{
if (_XFood == this.Xs[i] && _YFood == this.Ys[i])
{
food_is_ok = false;
}
}
if (food_is_ok)
{
Brush mybrush = new SolidBrush(Color.Red); //填充红色
this._Graphics.FillRectangle(mybrush, _XFood * 20 + 1, _YFood * 20 + 1, 19, 19);
}
}
/// <summary>
/// 判断是否吃到食物
/// </summary>
private void IsEatFood()
{
if (this.Xs[0] == _XFood && this.Ys[0] == _YFood)
{
this.Xs.Add(this.Xs[_XTail]);
this.Ys.Add(this.Ys[_YTail]);
ClearSnake();
DrawSnake();
CreatFood();
}
}
/// <summary>
/// 判断是否触碰边界
/// </summary>
private void IsBorder()
{
if (this.Xs[0] < 0 || this.Xs[0] > 29 || this.Ys[0] < 0 || this.Ys[0] > 29)
{
_BGM.Stop();//停止
Application.Exit();
}
}
/// <summary>
/// 判断是否咬到自身
/// </summary>
private void IsEatSelf()
{
for(int i=1;i<this.Xs.Count;i++)
{
if (this.Xs[0] == this.Xs[i] && this.Ys[0] == this.Ys[i])
{
_BGM.Stop();//停止
Application.Exit();//退出窗体
}
}
}
/// <summary>
/// 清除蛇
/// </summary>
private void ClearSnake()
{
for (int i = 0; i < this.Xs.Count; i++)
{
clear_gezi(this.Xs[i], this.Ys[i]);
}
}
/// <summary>
/// 画蛇
/// </summary>
private void DrawSnake()
{
for (int i = 0; i < this.Xs.Count; i++)
{
draw_gezi(this.Xs[i], this.Ys[i]);
}
_XTail = this.Xs.Count - 1;
_YTail = this.Ys.Count - 1;
}
/// <summary>
/// 画格子
/// </summary>
/// <param name="m"></param>
/// <param name="n"></param>
private void draw_gezi(int m, int n)
{
Brush mybrush = new SolidBrush(Color.FromArgb(204, 255, 153)); //填充青色
this._Graphics.FillRectangle(mybrush, m * 20 + 1, n * 20 + 1, 19, 19);
}
/// <summary>
/// 清除格子
/// </summary>
/// <param name="m"></param>
/// <param name="n"></param>
private void clear_gezi(int m, int n)
{
//Graphics.CompositingMode = CompositingMode.SourceCopy;
Brush mybrush = new SolidBrush(Color.Black); //填充黑色
this._Graphics.FillRectangle(mybrush, m * 20 + 1, n * 20 + 1, 19, 19);
}
/// <summary>
/// 点击按钮蛇向下移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)//下
{
this._MoveDir = "down";
}
private void AutoDown()
{
ClearSnake();
if (this.Ys[0] >= this.Ys[1])
{
this.Ys.RemoveAt(this.Ys.Count - 1);
this.Xs.RemoveAt(this.Xs.Count-1);
this.Ys.Insert(0, this.Ys[0] + 1);
this.Xs.Insert(0, this.Xs[0]);
}
DrawSnake();
IsEatFood();
IsEatSelf();
IsBorder();
}
/// <summary>
/// 点击按钮蛇向右移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)//右
{
this._MoveDir = "right";
}
/// <summary>
/// 蛇自动向右移动
/// </summary>
private void AutoRight()
{
ClearSnake();
if (this.Xs[0] >= this.Xs[1])
{
this.Ys.RemoveAt(this.Ys.Count - 1);
this.Xs.RemoveAt(this.Xs.Count - 1);
this.Ys.Insert(0, this.Ys[0]);
this.Xs.Insert(0, this.Xs[0] + 1);
}
DrawSnake();
IsEatFood();
IsEatSelf();
IsBorder();
}
/// <summary>
/// 点击按钮蛇向左移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnLeft_Click(object sender, EventArgs e) //左
{
this._MoveDir = "left";
}
/// <summary>
/// 蛇自动向左移动
/// </summary>
private void AutoLeft()
{
ClearSnake();
if (this.Xs[0] <= this.Xs[1])
{
this.Ys.RemoveAt(this.Ys.Count - 1);
this.Xs.RemoveAt(this.Xs.Count - 1);
this.Ys.Insert(0, this.Ys[0]);
this.Xs.Insert(0, this.Xs[0] - 1);
}
DrawSnake();
IsEatFood();
IsEatSelf();
IsBorder();
}
/// <summary>
/// 点击按钮蛇向上移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnRight_Click(object sender, EventArgs e) //上
{
this._MoveDir = "up";
}
/// <summary>
/// 蛇自动向上移动
/// </summary>
private void AutoUp()
{
ClearSnake();
if (this.Ys[0] <= this.Ys[1])
{
this.Ys.RemoveAt(this.Ys.Count - 1);
this.Xs.RemoveAt(this.Xs.Count - 1);
this.Ys.Insert(0, this.Ys[0] - 1);
this.Xs.Insert(0, this.Xs[0]);
}
DrawSnake();
IsEatFood();
IsEatSelf();
IsBorder();
}
/// <summary>
/// 时间事件触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void timer1_Tick(object sender, EventArgs e)
{
switch (this._MoveDir)
{
case "down":
AutoDown();
break;
case "right":
AutoRight();
break;
case "left":
AutoLeft();
break;
case "up":
AutoUp();
break;
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.W:
btnRight_Click(sender, e);
break;
case Keys.A:
btnLeft_Click(sender, e);
break;
case Keys.D:
button2_Click(sender, e);
break;
case Keys.S:
button1_Click(sender, e);
break;
}
}
}
}
(ps:本人目前大三非计算机专业,讲的不是很清楚的地方,见谅,仅作为学习小结记录并分享)