15.游戏场景-蛇长身体
15.1 知识点
创建蛇长身体方法。获得当前蛇尾,new出新长出的身体,新长出的身体初始化位置在在蛇尾。 但是先不画出来,下一帧再画,吃完食物后的下一帧再画。下一帧画之前会执行蛇移动方法,在蛇移动方法中添加长身体逻辑,其实就是从蛇尾开始,不停的让后一个的位置等于前一个的位置。残影不用管,移动方法前面写了擦屁股的逻辑。
#region Lesson7 蛇移动
/// <summary>
/// 蛇的移动方向
/// </summary>
enum E_MoveDir
{
/// <summary>
/// 上
/// </summary>
Up,
/// <summary>
/// 下
/// </summary>
Down,
/// <summary>
/// 左
/// </summary>
Left,
/// <summary>
/// 右
/// </summary>
Right,
}
#endregion
//蛇类 继承绘制接口
class Snake : IDraw
{
//蛇的身体数组
SnakeBody[] bodys;
//当前蛇的长度
int snakeBodysLength;
//当前移动的方向
E_MoveDir dir;
//蛇类构造函数
public Snake(int x, int y)
{
//粗暴的 申明200个空间 游戏中 基本不会出现蛇长度达到200个身体
bodys = new SnakeBody[200];
//声明蛇头
bodys[0] = new SnakeBody(E_SnakeBody_Type.Head, x, y);
//初始时只有蛇头 初始化为1
snakeBodysLength = 1;
//初始化默认移动的方向向右
dir = E_MoveDir.Right;
}
//蛇类绘制方法
public void Draw()
{
//遍历蛇身体数组 逐个绘制蛇身体
for (int i = 0; i < snakeBodysLength; i++)
{
bodys[i].Draw();
}
}
#region Lesson7 蛇的移动
//蛇移动方法
public void Move()
{
//蛇移动前 擦除蛇尾 也就是最后一个位置 否则有残影
SnakeBody lastBody = bodys[snakeBodysLength - 1];
Console.SetCursorPosition(lastBody.pos.x, lastBody.pos.y);
Console.Write(" ");//擦屁股
#region Lesson11 长身体后 蛇身体移动
//在蛇头移动之前 从蛇尾开始 不停的 让后一个的位置 等于前一个的位置
//遍历蛇身体
for (int i = snakeBodysLength - 1; i > 0; i--)
{
bodys[i].pos = bodys[i - 1].pos;
}
#endregion
//蛇头移动
switch (dir)
{
case E_MoveDir.Up:
--bodys[0].pos.y;
break;
case E_MoveDir.Down:
++bodys[0].pos.y;
break;
case E_MoveDir.Left:
bodys[0].pos.x -= 2;
break;
case E_MoveDir.Right:
bodys[0].pos.x += 2;
break;
}
}
#endregion
#region Lesson8 改变蛇的方向
//蛇改变移动方向方法
public void ChangeDir(E_MoveDir dir)
{
//蛇只有头部的时候 可以直接左转右 右转左 上转下 下转上
//蛇有身体时 这种情况就不能直接转
if(
//假如传进来的方向就等于现在的方向
dir == this.dir
||
//或者 蛇长度大于0且想要直接180度转向
(
snakeBodysLength > 1
&&
(this.dir == E_MoveDir.Left && dir == E_MoveDir.Right ||
this.dir == E_MoveDir.Right && dir == E_MoveDir.Left ||
this.dir == E_MoveDir.Up && dir == E_MoveDir.Down ||
this.dir == E_MoveDir.Down && dir == E_MoveDir.Up)
)
)
{
//直接return
return;
}
//只要没有return 就记录外面传入的方向 之后就会按照这个方向去移动
this.dir = dir;
}
#endregion
#region Lesson9 撞墙撞身体结束逻辑
//检测蛇是否撞墙撞身体后 结束游戏
//在update中每次绘制完检测 要传入地图
public bool CheckEnd( Map map )
{
//是否和墙体位置重合
for (int i = 0; i < map.walls.Length; i++)
{
if( bodys[0].pos == map.walls[i].pos )
{
return true;
}
}
//是否和自己的身体重合
for (int i = 1; i < snakeBodysLength; i++)
{
if(bodys[0].pos == bodys[i].pos)
{
return true;
}
}
return false;
}
#endregion
#region Lesson10 吃食物相关
//判断是否和蛇重合方法
//通过传入一个位置 来判断这个位置 是不是和蛇重合
public bool CheckSamePos(Position p)
{
for (int i = 0; i < snakeBodysLength; i++)
{
if(bodys[i].pos == p)
{
return true;
}
}
return false;
}
//蛇吃食物方法
public void CheckEatFood(Food food)
{
//判断蛇
if( bodys[0].pos == food.pos )
{
//吃到了 就应该让食物 位置再随机 增加蛇身体的长度
food.RandomPos(this);
//长身体
AddBody();
}
}
#endregion
#region Lesson11 长身体
//蛇长身体方法
private void AddBody()
{
//获得当前蛇尾的蛇身子类变量
SnakeBody frontBody = bodys[snakeBodysLength - 1];
//吃完食物后 先长出身体 但是先不画出来 下一帧再画
bodys[snakeBodysLength] = new SnakeBody(E_SnakeBody_Type.Body, frontBody.pos.x, frontBody.pos.y);
//增加蛇身体的总长度
++snakeBodysLength;
}
#endregion
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com