前几天有个学生做了一个贪吃蛇的小游戏,他原来考虑使用线程实现,由于课堂上没有给他们讲过线程,所以指导他改用了定时器来实现了这个小游戏。
游戏使用C#语言描述实现,里面主要用到了以下知识点:
1、 循环
2、 定时器
3、 动态生成控件
4、 逻辑控制处理
5、 游戏规则模拟处理
游戏时的截图:

后面附具体源码
部分具体实现代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
namespace Snake
{
enum DIR { L, R, U, D }//L, R, U, D,分别代表左移、右移、上移、下移
public partial class Snake : Form
{
int level = 1;
int xold, yold;//记录蛇头的初始位置
DIR direction = DIR.R;//默认移动方向
//Keys dir = Keys.Right;//默认移动方向
int snakeBody = 4;//蛇身长度
int snakeX;//蛇身初始的x轴坐标
int snakeY;//蛇身初始的y轴坐标
Label lblFood;//生成的蛇食
Label lbl;
List<Label> list = new List<Label>();
public Snake()
{
InitializeComponent();
}
private void Snake_Load(object sender, EventArgs e)
{
lblSnakeHead.BackColor = Color.FromArgb(0, 255, 0);
AddBody();
GenerrationFood();
timer1.Enabled = true;
timer1.Start();
}
/// <summary>
/// 键盘按键按下事件,判断获取蛇头的方向信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Snake_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyData)
{
case Keys.A:
direction = DIR.L;
break;
case Keys.Left:
direction = DIR.L;
break;
case Keys.D:
direction = DIR.R;
break;
case Keys.Right:
direction = DIR.R;
break;
case Keys.W:
direction = DIR.U;
break;
case Keys.Up:
direction = DIR.U;
break;
case Keys.S:
direction = DIR.D;
break;
case Keys.Down:
direction = DIR.D;
break;
default:
break;
}
}
/// <summary>
/// 生成蛇食
/// </summary>
private void GenerrationFood()
{
lblFood = new Label();
lblFood.BackColor = Color.DeepPink;
lblFood.Size = new System.Drawing.Size(10, 10);
lblFood.BorderStyle = BorderStyle.FixedSingle;
Random random = new Random();
int x = random.Next(0, 79);
int y = random.Next(0, 59);
x = x * 10;
y = y * 10;
lblFood.Location = new System.Drawing.Point(x, y);
this.Controls.Add(lblFood);
}
/// <summary>
/// 生成蛇身
/// </summary>
private void AddBody()
{
snakeX = lblSnakeHead.Left;
snakeY = lblSnakeHead.Top;
for (int i = 0; i < snakeBody; i++)
{
lbl = new Label();
lbl.Size = new System.Drawing.Size(10, 10);
lbl.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
lbl.Location = new System.Drawing.Point(snakeX + 20 * i, snakeY);
lbl.Name = i.ToString();
lbl.BackColor = Color.DarkMagenta;
this.Controls.Add(lbl);
list.Add(lbl);
}
}
/// <summary>
/// 通过蛇头来移动蛇身位置
/// </summary>
private void MoveBody()
{
int x, y;//用来接收除蛇头外的其余lbl移动前的坐标
for (int i = 0; i < list.Count; i++)
{
x = list[i].Left;
y = list[i].Top;
list[i].Left = xold;
list[i].Top = yold;
xold = x;
yold = y;
}
}
/// <summary>
/// 移动蛇头,根据方向来调整蛇头就位置
/// </summary>
/// <returns>是否移动成功,即是否游戏触碰边界,游戏失败</returns>
private bool MoveHead()
{
bool bFailed = false;
xold = lblSnakeHead.Left;
yold = lblSnakeHead.Top;
switch (direction)
{
case DIR.U:
lblSnakeHead.Top -= 10;
snakeY -= 10;
if (lblSnakeHead.Top <= 0)
{
bFailed = true;
}
break;
case DIR.D:
lblSnakeHead.Top += 10;
snakeY += 10;
if (lblSnakeHead.Top >= 600)
{
bFailed = true;
}
break;
case DIR.L:
lblSnakeHead.Left -= 10;
snakeX -= 10;
if (lblSnakeHead.Left <= 0)
{
bFailed = true;
}
break;
case DIR.R:
lblSnakeHead.Left += 10;
snakeX += 10;
if (lblSnakeHead.Left >= 800)
{
bFailed = true;
}
break;
}
return bFailed;
}
private void timer1_Tick(object sender, EventArgs e)
{
bool bFailed = MoveHead();
if (bFailed)
{
timer1.Enabled = false;
timer1.Stop();
DialogResult choice = MessageBox.Show("您失败了,游戏结束。是否重新开始?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (choice == System.Windows.Forms.DialogResult.Yes)
{
//游戏失败后重新开始游戏,初始化游戏设置参数
this.Text = string.Format("贪吃蛇:第1关");
level = 1;
snakeBody = 4;
timer1.Interval = 200;
direction = DIR.R;
lblSnakeHead.Top = 220;
lblSnakeHead.Left = 220;
lblSnakeHead.BackColor = Color.FromArgb(0, 255, 0);
foreach (Label lbl in list)
{
this.Controls.Remove(lbl);
}
list.Clear();
AddBody();//重新生成蛇身
//重新生成食物位置
Random random = new Random();
int x = random.Next(1, 77);
int y = random.Next(1, 54);
x = x * 10;
y = y * 10;
lblFood.Location = new System.Drawing.Point(x, y);
timer1.Enabled = true;
timer1.Start();
}
}
else
{
MoveBody();//移动身体
//判断是否吃到食物
if (lblSnakeHead.Location == this.lblFood.Location)
{
timer1.Enabled = false;
timer1.Stop();
MessageBox.Show(string.Format("恭喜,你经过了第{0}关", level), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
timer1.Enabled = true;
timer1.Start();
level++;
this.Text = string.Format("贪吃蛇:第{0}关", level);
snakeBody += 1;
timer1.Interval -= 10;
//过关时改变蛇头的颜色
if (level >= 21)
{
lblSnakeHead.BackColor = Color.FromArgb(255, 0, 0);
}
else
{
lblSnakeHead.BackColor = Color.FromArgb(150 + level * 5, 0, 0);
}
lblSnakeHead.Top = 220;
lblSnakeHead.Left = 220;
foreach (Label lbl in list)
{
this.Controls.Remove(lbl);
}
list.Clear();
AddBody();//蛇身增加后重新生成蛇身
//重新生成食物位置
Random random = new Random();
int x = random.Next(1, 79);
int y = random.Next(1, 59);
x = x * 10;
y = y * 10;
lblFood.Location = new System.Drawing.Point(x, y);
}
}
}
}
}
实现的具体源码: