贪吃蛇代码
// Snake.cs Begin
//
using System;
using System.Collections; using System.Drawing;
using System.Windows.Forms; using System.Timers;
namespace GreedySnake
{
#region Snake 蛇身
///
/// Snake 的摘要说明。
///
public class Snake
{
private Control dcControl;
private static int iMoveDirection = 0x1000; // 蛇的运动方向 , 初始化为 right -
0x1000
private int iCount; // 骨节的总数
private int iRadius; // 骨节的半径
private static int iCurrentHeadX; // 当前蛇头的中心坐标 X private static int iCurrentHeadY; // 当前蛇头的中心坐标 Y
private static int iCurrentTrailX; // 当前蛇尾的中心坐标 X private static int iCurrentTrailY; // 当前蛇尾的中心坐标 Y
private static int iNextHeadX; // 下一时刻蛇头的中心坐标 X private static int iNextHeadY; // 下一时刻蛇头的中心坐标 Y
private static int iPreTrailX; // 前一时刻蛇尾的中心坐标 X private static int iPreTrailY; // 前一时刻蛇尾的中心坐标 Y
private static ArrayList alSnake; // 存放整条蛇
private bool bDisposing = true;
private bool bIsEatself = false; // 是否吃自己
private bool bIsOutOfRange = false; // 是否超出允许活动的范围
public Control DcControl {
set { dcControl = value; }
get { return dcControl;} }
public int MoveDirection
{
set { iMoveDirection = value; }
get { return iMoveDirection; } }
public int Count
{
set { iCount = value; }
get { return iCount; }
}
public int Radius
{
set { iRadius = value; }
get { return iRadius; }
}
public int CurrentHeadX
{
set { iCurrentHeadX = value; }
get { return iCurrentHeadX; } }
public int CurrentHeadY
{
set { iCurrentHeadY = value; }
get { return iCurrentHeadY; } }
public int CurrentTrailX
{
set { iCurrentTrailX = value; }
get { return iCurrentTrailX; } }
public int CurrentTrailY
{
set { iCurrentTrailY = value; }
get { return iCurrentTrailY; } }
public int NextHeadX
{
set { iNextHeadX = value; }
get { return iNextHeadX; } }
public int NextHeadY
{
set { iNextHeadY = value; }
get { return iNextHeadY; } }
public int PreTrailX
{
set { iPreTrailX = value; }
get { return iPreTrailX; } }
public int PreTrailY
{
set { iPreTrailY = value; }
get { return iPreTrailY; } }
public bool IsEatself
{
set { bIsEatself = value; }
get { return bIsEatself; } }
public bool IsOutOfRange {
set { bIsOutOfRange = value; }
get { return bIsOutOfRange;} }
public Snake() : this(null , 20 , 5) {
//
// TODO: 在此处添加构造函数逻辑
//
}
public Snake(Control control , int iCount , int iRadius)
{
DcControl = control;
Count = iCount;
Radius = iRadius;
CurrentHeadX = CurrentTrailX = PreTrailX = 5;
CurrentHeadY = CurrentTrailY = PreTrailY = 5;
Initialize();
}
~Snake()
{
Dispose(false);
}
// 初始化蛇
private void Initialize() {
alSnake = new ArrayList();
for (int i=0 ; i {
alSnake.Insert(0 , new SnakeNode(DcControl , CurrentHeadX , CurrentHeadY ,
Radius));
CurrentHeadX += 2 * Radius;
}
CurrentHeadX -= 2 * Radius;
NextHeadX = CurrentHeadX + 2 * Radius;
NextHeadY = CurrentHeadY; }
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this); }
public void Dispose( bool bDisposing )
{
if (bDisposing)
{
// 调用 Dispose 处理受控资源中的字段
MoveDirection = 0x1000;
CurrentHeadX = CurrentHeadY = NextHeadX = NextHeadY = 5;
alSnake.Clear();
}
// 清除非受控资源
}
// 加头
public void AddHead()
{
alSnake.Insert(0 , new SnakeNode(DcControl , NextHeadX , NextHeadY , Radius));
CurrentHeadX = NextHeadX;
CurrentHeadY = NextHeadY;
Count++;
}
// 加尾
public void AddTrail()
{
alSnake.Add(new SnakeNode(DcControl , PreTrailX , PreTrailY , Radius));
Count++;
((SnakeNode)alSnake[Count - 1]).Draw();
}
// 去尾
public void RemoveTrail()
{
if (alSnake.Count>1)
{
PreTrailX = ((SnakeNode)alSnake[Count - 1]).CenterX;
PreTrailY = ((SnakeNode)alSnake[Count - 1]).CenterY;
alSnake.RemoveAt(alSnake.Count - 1);
Count--;
CurrentTrailX = ((SnakeNode)alSnake[Count - 1]).CenterX;
CurrentTrailY = ((SnakeNode)alSnake[Count - 1]).CenterY;
}
}
// 移动到下一位置
public void MoveNext() {
// 加头
AddHead();
// 画头
((SnakeNode)alSnake[0]).Draw();
// 清除尾(将蛇尾用背景色填充)
((SnakeNode)alSnake[Count-1]).Clear();
// 去尾(将蛇尾从 ArrayList 中删除)
RemoveTrail();
}
// 画整条蛇
public void Draw() {
for (int i=0; i {
((SnakeNode)alSnake[i]).Draw();
}
}
// 清除整条蛇
public void Clear() {
for (int i=0; i {
((SnakeNode)alSnake[i]).Clear();
}
}
// 重设运动方向
public void ResetMoveDirection(string strKeyData)
{
// 获取键盘输入
int iKeyDirection;
switch (strKeyData)
{
case "W":
case "Up":
iKeyDirection = 0x0001;
break;
case "S":
case "Down":
iKeyDirection = 0x0010;
break;
case "A":
case "Left":
iKeyDirection = 0x0100;
break;
case "D":
case "Right":
iKeyDirection = 0x1000;
break;
default:
iKeyDirection = 0x0010;
break;
}
// 重设蛇的运动方向(综合按键方向和当前蛇的运动方向考虑)
int iDirection = iKeyDirection | MoveDirection;
if (iDirection == 0x0011 || iDirection == 0x1100)
MoveDirection = MoveDirection; // 运动方向保持不变
else
MoveDirection = iKeyDirection; // 运动方向等于按键方向 }
// 是否超出范围
public void Check()
{
GetNextHeadXY();
// 检查是否吃自己
foreach (SnakeNode sn in alSnake)
{
if (sn.CenterX == NextHeadX && sn.CenterY == NextHeadY)
{
IsEatself = true;
break;
}
}
// 检查是否超出允许活动的范围
IsOutOfRange = NextHeadX<0 || NextHeadX>DcControl.Width || NextHeadY<0
|| NextHeadY>DcControl.Height; }
// 预先算出下个位置坐标
private void GetNextHeadXY() {
switch (MoveDirection)
{
case 0x0001:
NextHeadX = CurrentHeadX;
NextHeadY = CurrentHeadY - 2 * Radius;
break;
case 0x0010:
NextHeadX = CurrentHeadX;
NextHeadY = CurrentHeadY + 2 * Radius;
break;
case 0x0100:
NextHeadX = CurrentHeadX - 2 * Radius;
NextHeadY = CurrentHeadY;
break;
case 0x1000:
NextHeadX = CurrentHeadX + 2 * Radius;
NextHeadY = CurrentHeadY;
break;
default:
break;
}
}
}
#endregion
#region SnakeNode 蛇的骨节
///
/// Snake Note
/// 蛇的骨节
///
public class SnakeNode
{
private Control dcControl; // 用于画图的控件
private int iCenterX; // 中心坐标 X
private int iCenterY; // 中心坐标 Y
private int iRadius; // 半径
private Color colorNode; // 颜色
public Control DcControl {
set { dcControl = value; }
get { return dcControl; } }
public int CenterX
{
set { iCenterX = value; }
get { return iCenterX; } }
public int CenterY
{
set { iCenterY = value; }
get { return iCenterY; } }
public int Radius
{
set { iRadius = value; }
get { return iRadius; } }
public Color ColorNode
{
set { colorNode = value; }
get { return colorNode; } }
private bool bDisposing = true;
public SnakeNode() : this(null , 0 , 0 , 5)
{
}
public SnakeNode(Control control , int iX , int iY , int iR)
{
DcControl = control;
CenterX = iX;
CenterY = iY;
Radius = iR;
}
~SnakeNode()
{
Dispose(false);
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this); }
public void Dispose( bool bDisposing )
{
if (bDisposing)
{
// 调用 Dispose 处理受控资源中的字段
CenterX = CenterY = 0;
Radius = 5;
}
// 清除非受控资源
}
// 画自身
public void Draw()
{
Draw(Color.Blue); }
public void Draw(Color color) {
// 以指定颜色画圆
ColorNode = color;
DrawCircle(ColorNode); }
// 清除
public void Clear()
{
// 以控件的背景色画圆
DrawCircle(DcControl.BackColor);
}
// 以骨节的中心画圆
public void DrawCircle(Color color)
{
using (Graphics dc = DcControl.CreateGraphics())
{
// 创建实心的笔刷
SolidBrush sbBrush = new SolidBrush(color);
// 创建圆的区间范围
float x = CenterX - Radius;
float y = CenterY - Radius;
float width = 2 * Radius;
float height = 2 * Radius;
// 创建开始和扫过的弧度
float fStartAngle = 0.0F;
float fSweepAngle = 360.0F;
// 画圆
dc.FillPie(sbBrush , x , y , width , height , fStartAngle , fSweepAngle);
}
}
}
#endregion
#region SnakeFood 蛇的食物
///
/// SnakeFood 的摘要说明。
///
public class SnakeFood
{
private Control dcControl;
private int iMaxCount; // 最多能剩下的食物总数
private int iCurrentCount; // 当前剩下的食物总数
private int iRadius; // 骨节的半径
private Color[] acolor = new Color[]{Color.Red , Color.Green , Color.Yellow}; // 新
点的颜色取值范围
private static ArrayList alSnakeFood; // 蛇的食物
private bool bDisposing = true;
public Control DcControl
{
set { dcControl = value; }
get { return dcControl;} }
public int MaxCount
{
set { iMaxCount = value; }
get { return iMaxCount; } }
public int CurrentCount
{
set { iCurrentCount = value;}
get { return iCurrentCount;} }
public int Radius
{
set { iRadius = value; }
get { return iRadius; }
}
public SnakeNode this[int index] {
get
{
if (index<0 || index>=CurrentCount)
{
throw new IndexOutOfRangeException();
}
return (SnakeNode)alSnakeFood[index];
}
}
public SnakeFood() : this(null , 5 , 5) {
}
public SnakeFood(Control control , int iMaxCount , int iRadius)
{
DcControl = control;
MaxCount = iMaxCount;
CurrentCount = 0;
Radius = iRadius;
alSnakeFood = new ArrayList(); }
~SnakeFood()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this); }
public void Dispose( bool bDisposing ) {
if (bDisposing)
{
// 调用 Dispose 处理受控资源中的字段
CurrentCount = 0;
alSnakeFood.Clear();
}
// 清除非受控资源
}
// 添加食物
public void AddFood()
{
Random random = new Random();
int iStep = Radius + Radius;
int iX = Radius + iStep * random.Next(0 , DcControl.Width/iStep);
int iY = Radius + iStep * random.Next(0 , DcControl.Height/iStep);
SnakeNode sn = new SnakeNode(DcControl , iX , iY , iRadius);
Random randomIndex = new Random();
Color color = acolor[randomIndex.Next(0 , acolor.Length)];
color = Color.Green;
sn.Draw(color);
alSnakeFood.Add(sn);
// 当前剩下的食物总数加1
CurrentCount++;
}
// 删除被吃掉的食物
public void RemoveFood(int iIndex)
{
if (CurrentCount>0)
{
alSnakeFood.RemoveAt(iIndex);
// 当前剩下的食物总数减1
CurrentCount--;
}
}
// 画所有食物
public void Draw() {
foreach (SnakeNode sn in alSnakeFood)
{
sn.Draw();
}
}
// 清除所有食物
public void Clear() {
foreach (SnakeNode sn in alSnakeFood)
{
sn.Clear();
}
}
}
#endregion
}
//
// Snake.cs End