就是用graphic画出来的,用个timer控制,我已经封装成一个类了。
public class Game
{
int _direction;
Random rnd;//随机数
LinkedList<Point> SnakeL;//表示蛇的坐标,注意里面存的不是蛇的像素坐标而是格子的位置坐标
/*格子数是0-39的*/
LinkedList<Point> FoodL;//表示食物的
Graphics g;
SolidBrush sb,sb2;
int EX;//每一个小方格的像素宽
int EY;
System.Timers.Timer timer;
public Game(Graphics _g, int x, int y)
{
this.g = _g;
this.EX = x / 40;//规定40个
this.EY = y / 40;
this.SnakeL = new LinkedList<Point>();
this.FoodL = new LinkedList<Point>();
this.sb = new SolidBrush(Color.Blue);
this.sb2 = new SolidBrush(Color.Red);
this._direction = -1;//一开始为-1防止一开始就在那里动
this.timer = new System.Timers.Timer(88);//计时器
this.timer.Elapsed += this.timer_e;
this.rnd = new Random(DateTime.Now.Millisecond);
for (int i = 0; i < 5; i++)//初始化蛇
{
this.SnakeL.AddFirst(new Point(i, 0));//位置坐标
}
for (int i = 0; i < 4; i++)//初始化食物
{
this.FoodL.AddFirst(new Point(this.rnd.Next(1, 39), this.rnd.Next(1, 39)));
//上下边距留空所以取1 - 39
}
}
public void GameStart()
{
this.timer.Enabled = true;
}
public void LetGameOver()
{
this.timer.Enabled = false;
}
public int direction//给外部用
{
get { return this._direction; }
set { this._direction = value; }
}
/*most important*/
private void timer_e(object s, EventArgs e)//间隔时间要做的事
{
this.draw();
this.move();
if (this.SnakeL.Count >= 11) //长度大于10 就删掉6个
{
this.CutSnake(6);
}
}
private void move()//移动函数
{
Point font = SnakeL.First.Value;
switch (this._direction)
{
case 1://向上
{
if (font.Y == 0) { font.Y = 40; }//下面还要-1所以写40
this.SnakeL.AddFirst(new Point(font.X,font.Y-1));
break;
}
case 2:
{
if (font.Y == 39) { font.Y = -1; }
this.SnakeL.AddFirst(new Point(font.X, font.Y + 1));
break;
}
case 3:
{
if (font.X == 0) { font.X = 40; }
this.SnakeL.AddFirst(new Point(font.X - 1, font.Y));
break;
}
case 4:
{
if (font.X == 39) { font.X = -1; }
this.SnakeL.AddFirst(new Point(font.X + 1, font.Y));
break;
}
default: return;
}
if (this.foodjudge(font))//如果前方为食物
{
this.setfood();//补充食物\
this.FoodL.Remove(font);
}
else//不是食物去掉蛇尾
{
this.SnakeL.RemoveLast();
}
}
private void draw()//重绘
{
g.Clear(Color.White);
foreach (Point p in SnakeL)//画射
{
g.FillRectangle(sb,p.X*10,p.Y*10,9,9);//每格子是10像素,绘图9像素这样画出来有间隔感
}
foreach(Point p in FoodL)
{
g.FillEllipse(sb2, p.X * 10, p.Y * 10, 9, 9);//每格子是10像素,绘图9像素这样画出来有间隔感
}
}
private bool foodjudge(Point p)//判断前方是否是食物
{
foreach (Point pp in this.FoodL)
{
if (p == pp) return true;
}
return false;
}
private void setfood()//设置食物,因为是demo且食物种类就一个,食物重叠就不考虑,反正也没影响
{
this.FoodL.AddFirst(new Point(this.rnd.Next(1, 39), this.rnd.Next(1, 39)));
}
private void CutSnake(int n)//剪短射的身体的函数n是数量
{
if (n >= this.SnakeL.Count) return;//大于范围。。
for (int i = 0; i < n; i++)
{
this.SnakeL.RemoveLast();
}
}
}
注意类里面的timer的t事件为一个新线程,如果类内要改变窗体上的某些资源的话是互斥的,需要用委托
http://download.csdn.net/detail/zhaozeyang/4339592 demo下载
做复杂了的话也可以做成我这样