.NET C#贪吃蛇游戏课程设计项目
这是写了三天的小游戏,大家下载玩玩,自己暂未发现任何bug源码下载:
主要源码如下:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Media;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using 贪吃蛇.Entities;
using 贪吃蛇.Util;
using System.Runtime.InteropServices;// 使用MCI Command String多媒体设备程序接口
namespace 贪吃蛇.Controller
{
/// <summary>
/// 游戏控制器 用来控制整个游戏的逻辑
/// </summary>
class GameController
{
private Ground ground;//游戏控制器所控制的背景对象
public Snake snake;//游戏控制器所控制的蛇对象
private MainForm mForm;//主窗体类
private Thread snakeMoveThread;//线程控制
private Graphics graphics;//Gdi+对象
/// <summary>
/// 构造函数,初始化当前对象的背景字段和蛇字段
/// </summary>
public GameController(Graphics g, MainForm mForm)
{
this.mForm = mForm;
this.graphics = g;
this.ground = new Ground();
this.snake = new Snake();
}
/// <summary>
/// 初始化地图、蛇以及食物
/// </summary>
public void InitMap()
{
//绘制背景
this.ground.DrawMe(graphics);
//绘制蛇
this.snake.DrawMe(graphics);
//在地图上随机的产生一个食物
this.ground.MakeFood(graphics, snake);
}
/// <summary>
/// 开始新游戏的方法
/// </summary>
public void NewGame()
{
//让蛇动起来
snakeMoveThread = new Thread(SnakeAutoMoveThread);//创建线程
snakeMoveThread.IsBackground = true;//设置为后台线程
snakeMoveThread.Start();//开启线程
}
#region 蛇移动的线程方法
/// <summary>
/// 蛇移动的线程方法
/// </summary>
private void SnakeAutoMoveThread()
{
//判断蛇头是否能继续移动
//取出蛇头的坐标 判断蛇头的坐标是否越界
while (ground.IsMoveable(snake))
{
if (snake.IsEatSelf())//判断蛇头是否吃到自己
{
break;
}
if (ground.IsEatFood(snake))//判断一下蛇是否吃到了食物
{
snake.AddBody();//如果吃到了食物 增加蛇的身体
ground.MakeFood(graphics, snake);//再次随机的产生一个食物
CommonHelper.Score++;//加分数
mForm.ShowScore();
}
this.snake.AutoMove(graphics);
Thread.Sleep(CommonHelper.GetSpeed());
}
CommonHelper.SoundPlayer.Stop();
SoundPlayer sp = new SoundPlayer();
sp.SoundLocation = Directory.GetCurrentDirectory() + @"\sound\gameover.wav";
sp.Play();
graphics.DrawString("GameOver", new Font("宋体", 50), new SolidBrush(Color.Yellow), new Point(30, 30));
}
#endregion
#region 处理用户传递过来的按键
/// <summary>
/// 处理用户传递过来的按键
/// </summary>
/// <param name="keyData"></param>
public void ProcessDialogKey(Keys keyData)
{
switch (keyData)
{
case Keys.Up:
snake.SnakeHead.Dir = Direction.Up;
break;
case Keys.Down:
snake.SnakeHead.Dir = Direction.Down;
break;
case Keys.Right:
snake.SnakeHead.Dir = Direction.Right;
break;
case Keys.Left:
snake.SnakeHead.Dir = Direction.Left;
break;
}
}
#endregion
#region 暂停线程 暂停游戏
/// <summary>
/// 暂停线程 暂停游戏
/// </summary>
public void PauseThread()
{
try
{
CommonHelper.SoundPlayer.Stop();
snakeMoveThread.Suspend();
}
catch
{
}
}
#endregion
#region 恢复线程 恢复游戏
/// <summary>
/// 恢复线程 恢复游戏
/// </summary>
public void RecoverThread()
{
try
{
CommonHelper.SoundPlayer.PlayLooping();
snakeMoveThread.Resume();
}
catch
{
}
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using 贪吃蛇.Util;
namespace 贪吃蛇.Entities
{
/// <summary>
/// 贪吃蛇类 表示一条贪吃蛇
/// </summary>
class Snake
{
//蛇的身体单元集合,使用链表集合可以最快得到蛇头以及蛇尾
public LinkedList<SnakeUnit> body = new LinkedList<SnakeUnit>();
/// <summary>
/// 蛇头属性 取到body集合中的第一个元素
/// </summary>
public SnakeUnit SnakeHead
{
get
{
return this.body.First.Value;
}
}
/// <summary>
/// 构造函数,为body链表集合中新增3个身体单元
/// </summary>
public Snake()
{
//蛇头:
//1.创建一个身体单元对象
SnakeUnit unit = new SnakeUnit(CommonHelper.ColCount / 2, CommonHelper.RowCount / 2);
//2.将这个身体单元对象添加到链表集合中去,当做蛇头
body.AddFirst(unit);
AddBody();
AddBody();
}
/// <summary>
/// 为当前蛇对象新增一个身体单元
/// </summary>
public void AddBody()
{
//创建一个身体单元对象,这个身体单元对象的坐标应在最后1个身体单元的基础上行不变
//列加1
Position pos = body.Last.Value.Pos;//取到最后一个节点的坐标
//行不变,列+1 对pos的修改不会影响最后一个节点的位置,因为pos为结构体(值类型)
pos.colIndex++;
//创建身体1个单元对象,坐标就是pos
SnakeUnit unit = new SnakeUnit(pos,RandomMaker.GetRandomColor());
body.AddLast(unit);
}
/// <summary>
/// 蛇自己画自己的方法
/// </summary>
/// <param name="g"></param>
public void DrawMe(Graphics g)
{
//蛇自己画自己的方法,只需要遍历body链表集合中的每个元素
//调用每个元素的DrawMe方法
foreach (SnakeUnit u in body)
{
u.DrawMe(g);
}
}
/// <summary>
/// 蛇自动移动的方法
/// </summary>
public void AutoMove(Graphics g)
{
//擦除整条蛇
this.WipeMe(g);
//根据每一个单元的前进方法 改变身体单元的坐标
LinkedListNode<SnakeUnit> node = body.First;
while (node!=null)
{
//先将遍历出来的元素按照现在的方向更改坐标
switch (node.Value.Dir)
{
case Direction.Left:
node.Value.MoveToLeft();
break;
case Direction.Right:
node.Value.MoveToRight();
break;
case Direction.Down:
node.Value.MovetoDown();
break;
case Direction.Up:
node.Value.MoveToUp();
break;
default:
break;
}
//将刚才移动的方向保存起来
node.Value.OldDir = node.Value.Dir;
//设置下一次前进的方向
if (node.Previous!=null)
{
node.Value.Dir = node.Previous.Value.OldDir;
}
node = node.Next;
}
//根据坐标绘制整条蛇
this.DrawMe(g);
}
/// <summary>
/// 蛇自己擦除自己的方法
/// </summary>
/// <param name="g"></param>
private void WipeMe(Graphics g)
{
//遍历链表集合,调用每一个身体单元自己擦除自己的方法
foreach (SnakeUnit u in body)
{
u.WipeMe(g);
}
}
/// <summary>
/// 判断蛇头是否吃到了自己
/// </summary>
/// <returns></returns>
public bool IsEatSelf()
{
//取出蛇头的坐标
Position pos = this.SnakeHead.Pos;
//将其他身体单元遍历出来 做对比
LinkedListNode<SnakeUnit> node = body.First.Next;
while (node!=null)
{
if (node.Value.Pos.colIndex==pos.colIndex&&node.Value.Pos.rowIndex==pos.rowIndex)
{
return true;
}
node = node.Next;
}
return false;
}
}
}
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using 贪吃蛇.Util;
namespace 贪吃蛇.Entities
{
/// <summary>
/// 身体单元类 用来表示组成蛇的每一个身体单元
/// </summary>
class SnakeUnit
{
#region 身体单元的颜色 默认为红色
/// <summary>
/// 颜色
/// </summary>
private Color color = Color.Red;
public Color Color
{
get { return color; }
set { color = value; }
}
#endregion
#region 身体单元的坐标
/// <summary>
/// 坐标
/// </summary>
private Position pos;
internal Position Pos
{
get { return pos; }
set { pos = value; }
}
#endregion
#region 构造函数 用于各种方式创建对象
public SnakeUnit(int rowIndex, int colIndex)
{
this.pos.rowIndex = rowIndex;
this.pos.colIndex = colIndex;
}
public SnakeUnit(int rowIndex, int colIndex, Color color)
: this(rowIndex, colIndex)
{
this.color = color;
}
public SnakeUnit(Position pos)
{
this.pos = pos;
}
public SnakeUnit(Position pos, Color color)
: this(pos)
{
this.color = color;
}
#endregion
#region 将当前身体单元所在单元格的颜色填充为当前身体单元对象的颜色
/// <summary>
/// 当前身体单元根据自己的坐标和颜色将自己绘制出来
/// </summary>
/// <param name="g"></param>
public void DrawMe(Graphics g)
{
//将当前身体单元所在单元格的颜色填充为当前身体单元对象的颜色
Brush brush = new SolidBrush(this.color);
g.FillRectangle(brush, new Rectangle(
this.pos.colIndex * CommonHelper.SquLength + 1,
this.pos.rowIndex * CommonHelper.SquLength + 1,
CommonHelper.SquLength - 1,
CommonHelper.SquLength - 1
));
}
#endregion
#region 身体但单元的前进方向 默认向左
private Direction dir = Direction.Left;
internal Direction Dir
{
get { return dir; }
set { dir = value; }
}
#endregion
#region 身体单元向左移动
/// <summary>
/// 身体单元方向向走移动 其实就是身体单元的列坐标-1
/// </summary>
public void MoveToLeft()
{
this.pos.colIndex--;
}
#endregion
#region 身体单元向上移动
/// <summary>
/// 身体单元方向向上移动 其实就是身体单元的行坐标-1
/// </summary>
public void MoveToUp()
{
this.pos.rowIndex--;
}
#endregion
#region 身体单元向右移动
/// <summary>
/// 身体单元方向向右移动的方法 其实就是身体单元的列坐标+1
/// </summary>
public void MoveToRight()
{
this.pos.colIndex++;
}
#endregion
#region 身体单元向下移动
/// <summary>
/// 身体单元方向向下移动的方向 其实就是身体单元的行坐标+1
/// </summary>
public void MovetoDown()
{
this.pos.rowIndex++;
}
#endregion
#region 身体单元擦除自己的方法
/// <summary>
/// 身体单元自己擦除自己方法
/// </summary>
/// <param name="g"></param>
public void WipeMe(Graphics g)
{
//将当前身体单元所在的单元格的颜色填充为背景色
Brush brush = new SolidBrush(CommonHelper.GroundColor);
g.FillRectangle(brush, new Rectangle(
this.pos.colIndex * CommonHelper.SquLength + 1,
this.pos.rowIndex * CommonHelper.SquLength + 1,
CommonHelper.SquLength - 1,
CommonHelper.SquLength - 1
));
}
#endregion
#region 身体单元移动的旧方向
private Direction oldDir = Direction.Left;
internal Direction OldDir
{
get { return oldDir; }
set { oldDir = value; }
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using 贪吃蛇.Entities;
using System.Media;
namespace 贪吃蛇.Util
{
/// <summary>
/// 游戏帮助类 这个类中提供整个程序中需要被共享的数据
/// </summary>
static class CommonHelper
{
#region 初始化游戏环境
/// <summary>
/// 初始化游戏环境的方法
/// </summary>
/// <param name="panelWidth">游戏面板的宽度</param>
/// <param name="panelHeight">游戏面板的高度</param>
public static Size InitializeEnvironment(int panelWidth, int panelHeight)
{
//根据游戏面板的宽度和高度以及游戏面板的总行数和总列数为squLength赋值
int width = panelWidth / colCount;//小方格的宽度
int height = panelHeight / rowCount;//小方格的高度
//取较短的一边作为小方格的边长
squLength = width > height ? height : width;//取得小方格的边长
Size size = new Size();
size.Width = squLength * colCount+1;
size.Height = squLength * rowCount+1;
return size;
}
#endregion
#region 游戏面板的总行数 默认14行
private static int rowCount = 14;
public static int RowCount
{
get { return CommonHelper.rowCount; }
set { CommonHelper.rowCount = value; }
}
#endregion
#region 游戏面板的总列数 默认12列
private static int colCount = 12;
public static int ColCount
{
get { return CommonHelper.colCount; }
set { CommonHelper.colCount = value; }
}
#endregion
#region 小方格的边长
private static int squLength;
public static int SquLength
{
get
{
return CommonHelper.squLength;
}
}
#endregion
#region 线条颜色 默认是黑色
private static Color lineColor = Color.Black;
public static Color LineColor
{
get { return CommonHelper.lineColor; }
set { CommonHelper.lineColor = value; }
}
#endregion
#region 背景颜色 默认是天蓝色
private static Color groundColor = Color.SkyBlue;
public static Color GroundColor
{
get { return CommonHelper.groundColor; }
set { CommonHelper.groundColor = value; }
}
#endregion
#region 食物的颜色 默认是白色
private static Color foodColor = Color.White;
public static Color FoodColor
{
get { return CommonHelper.foodColor; }
set { CommonHelper.foodColor = value; }
}
#endregion
#region 玩家的分数
private static int score;
public static int Score
{
get { return CommonHelper.score; }
set { CommonHelper.score = value; }
}
#endregion
#region 玩家的等级
private static GameLevel level;
internal static GameLevel Level
{
get { return CommonHelper.level; }
set { CommonHelper.level = value; }
}
#endregion
#region 游戏速度
public static int GetSpeed()
{
int time=300;
switch (level)
{
case GameLevel.初级:
time = 300;
break;
case GameLevel.中级:
time = 200;
break;
case GameLevel.高级:
time = 100;
break;
}
return time;
}
#endregion
#region 存放多媒体播放对象
/// <summary>
/// 存放背景音乐多媒体播放对象
/// </summary>
private static SoundPlayer soundPlayer;
public static SoundPlayer SoundPlayer
{
get { return CommonHelper.soundPlayer; }
set { CommonHelper.soundPlayer = value; }
}
#endregion
}
}
做个沙发,虽然不懂 学习学习 楼主好厉害 这个必须赞一个 感谢分享啊!这代码 我只看得懂中文{:6_224:} 我要成品啊 下載來看看先~~~ 谢谢分享{:5_117:} 厉害了,可以学习学习。
页:
[1]
2