一,界面显示
二,界面功能介绍
按键 up:小蛇移动方向向上;
按键 down:小蛇移动方向向下;
按键 left:小蛇移动方向向左;
按键 right:小蛇移动方向向右;
按键 stop/continue:小蛇移动暂停/继续;
右下角显示的两个数据是小蛇的实时对应二维坐标,右上角显示小蛇的得分,每吃一个红球得分加一。
三,代码详解
1,小蛇类:
public class Snake
{
public Snake()
{
Body = new List<int[]>();
int[] firstBody = new int[] { 50, 50 };//初始化小蛇 第一个身体位置
Body.Add(firstBody);
}
private List<int[]> body = null;
/// <summary>
/// 身体
/// </summary>
public List<int[]> Body
{
get { return body; }
set { body = value; }
}
private string moveState = "right";
/// <summary>
/// 移动方向 状态
/// </summary>
public string MoveState
{
get { return moveState; }
set { moveState = value; }
}
private int upLimit = 10;
/// <summary>
/// 位置限值(上)
/// </summary>
public int UpLimit
{
get { return upLimit; }
set { upLimit = value; }
}
private int downLimit = 180;
/// <summary>
/// 位置限值(下)
/// </summary>
public int DownLimit
{
get { return downLimit; }
set { downLimit = value; }
}
private int leftLimit = 10;
/// <summary>
/// 位置限值(左)
/// </summary>
public int LeftLimit
{
get { return leftLimit; }
set { leftLimit = value; }
}
private int rightLimit = 180;
/// <summary>
/// 位置限值(右)
/// </summary>
public int RightLimit
{
get { return rightLimit; }
set { rightLimit = value; }
}
private int score = 0;
/// <summary>
/// 得分
/// </summary>
public int Score
{
get { return score; }
set { score = value; }
}
}
2,主界面窗体:
全局变量区
#region ##变量区###
Snake snake = null;//小蛇
Timer BackGrounfTimer = null;//界面刷新 定时器
int BG_x = 10, BG_y = 10, BG_w = 200, BG_h = 200;//背景框 位置
bool IsEat = false;//是否吃到食物
int Food_x = 100, Food_y = 100;//食物位置
bool GameState = true;//游戏状态
#endregion
控件事件区:
#region 控件事件
private void Form1_Load(object sender, EventArgs e)
{
InitBackGroundTimer();
snake = new Snake();
lab_Score.Text = "0";
}
//up
private void btn_Up_Click(object sender, EventArgs e)
{
if (snake.MoveState != "down")
{
snake.MoveState = "up";
}
}
//down
private void btn_Down_Click(object sender, EventArgs e)
{
if (snake.MoveState != "up")
{
snake.MoveState = "down";
}
}
//left
private void btn_Left_Click(object sender, EventArgs e)
{
if (snake.MoveState != "right")
{
snake.MoveState = "left";
}
}
//right
private void btn_Right_Click(object sender, EventArgs e)
{
if (snake.MoveState != "left")
{
snake.MoveState = "right";
}
}
//start
private void btn_Start_Click(object sender, EventArgs e)
{
if(GameState)
{
btn_Start.Text = "continue";
BackGrounfTimer.Enabled = false;
GameState = false;
}
else
{
btn_Start.Text = "stop";
BackGrounfTimer.Enabled = true;
GameState = true;
}
//DrawBody();
}
#endregion
背景刷新 定时器:
#region ###背景刷新 定时器###
private void InitBackGroundTimer()
{
BackGrounfTimer = new Timer();
BackGrounfTimer.Enabled = true;
BackGrounfTimer.Interval = 300;
BackGrounfTimer.Tick += new EventHandler(BackGroundTimer_Tick); ;
}
private void BackGroundTimer_Tick(object sender, EventArgs e)
{
using (Graphics g = this.CreateGraphics())
{
g.Clear(this.BackColor);
}
Graphics graphics = this.CreateGraphics();//创建 Graphics对象
Pen pen = new Pen(Color.Green, 10);
graphics.DrawRectangle(pen, BG_x, BG_y, BG_w, BG_h);//背景
Brush brush2 = new SolidBrush(Color.Red);
Random r = new Random();
if (snake.Body.FirstOrDefault()[0] >= Food_x - 20 && snake.Body.FirstOrDefault()[0] <= Food_x + 20 && snake.Body.FirstOrDefault()[1] >= Food_y - 20 && snake.Body.FirstOrDefault()[1] <= Food_y + 20)
{
IsEat = true;
snake.Score++;
lab_Score.Text = snake.Score.ToString();
Grow();
}
if (IsEat)
{
Food_x = r.Next(10, 180);
Food_y = r.Next(10, 180);
IsEat = false;
}
graphics.FillEllipse(brush2, Food_x, Food_y, 30, 30);
Brush brush = new SolidBrush(Color.Green);
switch (snake.MoveState)
{
case "up":
if (snake.Body.FirstOrDefault()[1] != snake.UpLimit)
{
RefreshBody();
snake.Body.FirstOrDefault()[1] -= 10;
}
else
{
RefreshBody();
snake.Body.FirstOrDefault()[1] = snake.DownLimit - 10;
}
break;
case "down":
if (snake.Body.FirstOrDefault()[1] != snake.DownLimit)
{
RefreshBody();
snake.Body.FirstOrDefault()[1] += 10;
}
else
{
RefreshBody();
snake.Body.FirstOrDefault()[1] = snake.UpLimit + 10;
}
break;
case "left":
if (snake.Body.FirstOrDefault()[0] != snake.LeftLimit)
{
RefreshBody();
snake.Body.FirstOrDefault()[0] -= 10;
}
else
{
RefreshBody();
snake.Body.FirstOrDefault()[0] = snake.RightLimit - 10;
}
break;
case "right":
if (snake.Body.FirstOrDefault()[0] != snake.RightLimit)
{
RefreshBody();
snake.Body.FirstOrDefault()[0] += 10;
}
else
{
RefreshBody();
snake.Body.FirstOrDefault()[0] = snake.LeftLimit + 10;
}
break;
default:
break;
}
foreach (var body in snake.Body)
{
graphics.FillEllipse(brush, body[0], body[1], 30, 30);//画椭圆
}
if (snake.Body.Count>1)
{
if (snake.Body.FirstOrDefault()[0] == snake.Body.LastOrDefault()[0] && snake.Body.FirstOrDefault()[1] == snake.Body.LastOrDefault()[1] )
{
using (Graphics g = this.CreateGraphics())
{
g.Clear(this.BackColor);
}
BackGrounfTimer.Enabled = false;
MessageBox.Show("游戏失败");
}
}
graphics.Dispose();//释放使用的资源
lab_X.Text = snake.Body.FirstOrDefault()[0].ToString();
lab_Y.Text = snake.Body.FirstOrDefault()[1].ToString();
}
#endregion
方法区:
#region ###方法区#####
private void Grow()
{
int[] nextBody = new int[] { snake.Body.Last()[0], snake.Body.Last()[1] };
snake.Body.Add(nextBody);
}
private void RefreshBody()
{
if (snake.Body.Count > 1)
{
for (int i = (snake.Body.Count - 1); i > 0; i--)
{
int x = snake.Body.ElementAt(i-1)[0];
int y = snake.Body.ElementAt(i-1)[1];
snake.Body.ElementAt(i)[0] = x;
snake.Body.ElementAt(i)[1] = y;
}
}
}
#endregion