加上重玩之后,游戏流程就完整了。我们抓紧开始吧。
01.判断游戏失败
我目前的设定是:方块下落完成后,扫描最顶端的一行,只要发现该行上有一个点,就认定游戏失败。
下面是代码:
// 检测游戏失败
bool CheckGameOver()
{
for (int list = 0; list < 10; list++)
{
if (_defaultLayer.IsCanSee(new MyPoint(19, list)))
{
// 游戏失败
return true;
}
}
return false;
}
02.如何清屏
记得砖块机上游戏失败后是如何清屏的吗?先从最底端向上一行一行填充,再从顶端向下一行一行消除,直到全部清除。
为了实现这个动画,我们先添加两个方法,一个填充行,一个消除行:
// 清屏 - 填充行
void FillLineForClearScreen()
{
}
// 清屏 - 消除行
void ClearLineForClearScreen()
{
}
这两个方法使用定时器驱动。
关于什么时候检测游戏失败,我的设定是:方块固定之后,判断是否游戏失败。
如果失败了,就启动定时器执行FillLineForClearScreen(),为了依次处理每一行,需要一个成员变量来记录已经处理到哪一行了,本次就接着上一次继续处理,如果发现所有行都填满了,那就停止执行填充行,然后启动定时器执行消除行。所有行都消除后,重置游戏数据(分数、关卡)后,开始执行核心逻辑。
03.实现清屏
先添加一个成员变量并初始化为0:
int _lineOfClearScreen; // 清屏 - 正在处理的行号
在核心逻辑中驱动清屏:
// 检测游戏失败
if (CheckGameOver())
{
InvokeRepeating("FillLineForClearScreen", 0, 0.02f);
return;
}
实现填充与消除两个方法:
// 清屏 - 填充行
void FillLineForClearScreen()
{
// 填充当前行
List<MyPoint> line = new List<MyPoint>();
for (int list = 0; list < 10; list++)
{
line.Add(new MyPoint(_lineOfClearScreen, list));
}
_defaultLayer.AddViewData(line);
_screenMainScript.RefreshScreen();
// 判断是否处理到顶行
if (_lineOfClearScreen < 19)
{
_lineOfClearScreen++;
}
else
{
// 如果已经处理到顶行,则开始消除行
CancelInvoke("FillLineForClearScreen");
InvokeRepeating("ClearLineForClearScreen", 0.02f, 0.02f);
}
}
// 清屏 - 消除行
void ClearLineForClearScreen()
{
// 消除当前行
for (int list = 0; list < 10; list++)
{
_defaultLayer.RemovePoint(_lineOfClearScreen, list);
}
_screenMainScript.RefreshScreen();
// 判断是否已处理到底端
if (_lineOfClearScreen > 0)
{
_lineOfClearScreen--;
}
else
{
CancelInvoke("ClearLineForClearScreen");
// 重置分数
_currentScore = 0;
_currentScoreScript.SetScore(_currentScore);
// 重置关卡
_level = 1;
_levelScript.SetLevel(0, _level);
// 清空所有屏幕
_blockLayer.ViewData.Clear();
_defaultLayer.ViewData.Clear();
_screenAttachedScript.GetLayer("DefaultLayer").ViewData.Clear();
// 添加初始方块
_blockLayer.Point = new MyPoint(20, 4);
EBlockType blockType = BlockCreator.GetInstance().RandomBlockType();
_blockLayer.ViewData = BlockCreator.GetInstance().CreateBlock(blockType);
// 生成下一个方块
_nextBlockType = BlockCreator.GetInstance().RandomBlockType();
_screenAttachedScript.GetLayer("DefaultLayer").ViewData = BlockCrea-tor.GetInstance().CreateBlock(_nextBlockType);
// 刷新屏幕
_screenMainScript.RefreshScreen();
_screenAttachedScript.RefreshScreen();
// 启动GameCore
CancelInvoke("GameCore");
InvokeRepeating("GameCore", 1 - (_level - 1) * 0.1f, 1 - (_level - 1) * 0.1f);
}
}
04.处理重复点
经过测试发现:在清屏的第二步(消除行)中,会有重置游戏前残留的方块数据:
这主要是因为,在添加显示数据至固定方块层时,添加了重复的点,我们需要修改图层类的添加显示数据方法,把重复的剔除掉:
// 添加显示数据
public void AddViewData(List<MyPoint> points)
{
foreach (var point in points)
{
if (ViewData.Contains(point)) continue;
ViewData.Add(point);
}
}
添加一行判断元素是否已存在的代码,就可以剔除重复了,下面是测试效果:
代码链接:https://pan.baidu.com/s/1e5AdR3bu9fSPejguEkB0kg
提取码:nmzt
网友评论