13.游戏场景-蛇撞墙撞身体结束游戏判定
13.1 知识点
蛇类创建判断是否撞墙撞身体后结束游戏方法,一次遍历地图的墙数组和自己的身体数组比较位置。
#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(" ");//擦屁股
//蛇头移动
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
}
游戏场景类中,每次update绘制完身体,用蛇变量判断是否撞墙撞身体,是的话切换到结束场景
using System;
using System.Collections.Generic;
using System.Text;
using 贪食蛇.Lesson1;
using 贪食蛇.Lesson4;
using 贪食蛇.Lesson5;
using 贪食蛇.Lesson6;
namespace 贪食蛇.Lesson2
{
//游戏场景类 继承游戏帧更新接口
class GameScene : ISceneUpdate
{
//地图类变量 管理所有墙壁
Map map;
//蛇类变量 管理蛇相关
Snake snake;
//while循环次数 判断当前while循环进了多少次
int whileLoopTimes = 0;
//游戏场景类构造函数
public GameScene()
{
//初始化地图类变量
map = new Map();
//初始化一个蛇
snake = new Snake(40, 10);
}
//实现游戏场景里的更新方法 在游戏类中的start方法中的while循环中调用
public void Update()
{
//while循环运行的太快 每次进一次while 绘制一次的话 游戏速度太快 要降速
//用while循环次数来判断 每当进入while循环10000次后 再进行一次绘制
//可以理解为每10000帧更新一次
if (whileLoopTimes % 10000 == 0)
{
//绘制地图类
map.Draw();
//蛇移动 先移动再绘制蛇
snake.Move();
//绘制蛇类
snake.Draw();
//检测是否撞墙
if(snake.CheckEnd(map))
{
//切换为结束场景
Game.ChangeScene(E_SceneType.End);
}
//实际update了 重写开始计数
whileLoopTimes = 0;
}
//每进一次while循环加一
++whileLoopTimes;
//检测输入输出 不能再间隔帧(就是while循环一万次)里面去处理 应该每次都检测 这样才准确 否则会有延迟
//假如检测玩家输入用 Console.ReadKey(true).Key 程序会卡住等待输入
//因为Console.ReadKey(true).Key会一直等
//想在控制台中 检测玩家输入 让程序不被检测卡住
//使用 Console.KeyAvailable
//判断 有没有键盘输入 如果有 才为true 否则一直false 就不会被卡住
if ( Console.KeyAvailable )
{
//根据输入
switch (Console.ReadKey(true).Key)
{
case ConsoleKey.W:
snake.ChangeDir(E_MoveDir.Up);
break;
case ConsoleKey.A:
snake.ChangeDir(E_MoveDir.Left);
break;
case ConsoleKey.S:
snake.ChangeDir(E_MoveDir.Down);
break;
case ConsoleKey.D:
snake.ChangeDir(E_MoveDir.Right);
break;
}
}
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com