// 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
//