第三十节 添加消除动画
2019-06-25 本文已影响0人
安静的程序员
其实也不是什么高深的动画,就是那种加个定时器,一个一个的消除像素点而已。
本节需要做两段动画:
01.消除动画
02.填补消除后的空行动画
01.消除的动画
目前消除是没有动画的,所有点会在一瞬间消除,我想要的动画是每次只消除一个点,用定时器控制,比如每0.1秒消除一个点,这样看起来就会给人连贯的感觉,而不是突然之间就完成了。
01.01 实现流程

其中,消除点是一个方法,由定时器反复调用。
01.02 添加成员,并收集需要消除的点
List<MyPoint> _needClearPoints; // 存储需要消除的点
在InitGame()中初始化:
_needClearPoints = new List<MyPoint>();
在GameCore()中收集需要消除的点:
// 如有需要消除的行
if (_needClearLines.Count > 0)
{
// 收集需要消除的点
foreach (var line in _needClearLines)
{
for (int list = 0; list < 10; list++)
{
_needClearPoints.Add(new MyPoint(line, list));
}
}
...
01.03 添加消除点方法
// 消除一个点
void ClearOnePoint()
{
// 如果有未处理完的点
if (_needClearPoints.Count > 0)
{
// 取出第一个点
MyPoint point = _needClearPoints[0];
// 移除该点
_defaultLayer.RemovePoint(point._line, point._list);
// 删除处理完的点
_needClearPoints.Remove(point);
_screenMain.RefreshScreen();
}
else
{
// 先停止定时器
CancelInvoke("ClearOnePoint");
// 填补消除后的行
FillUpClearedLine();
// 创建新方块
CreateNewBlock();
// 启动核心逻辑
InvokeRepeating("GameCore", 0, 1);
}
}
01.04 修改核心逻辑
// 如有需要消除的行
if (_needClearLines.Count > 0)
{
// 停止核心逻辑,进入消除阶段
CancelInvoke("GameCore");
// 收集需要消除的点
foreach (var line in _needClearLines)
{
for (int list = 0; list < 10; list++)
{
_needClearPoints.Add(new MyPoint(line, list));
}
}
// “消除点”启动
InvokeRepeating("ClearOnePoint", 0, 0.1f);
}
else
{
// 创建新方块
CreateNewBlock();
}
修改完之后,运行游戏。如果没有问题,当有满行的时候,就会一个一个得消除点了。
02.填补空行的动画
同样,我们来添加一个方法:填补单行
// 填补一行被消除的
void FillUpOneLineByCleared()
{
if (_needClearLines.Count > 0)
{
int line = _needClearLines[_needClearLines.Count - 1];
List<MyPoint> fixedPoints = _defaultLayer.ViewData;
for (int index = 0; index < fixedPoints.Count; index++)
{
// 将高于当前行的点下移一格
if (fixedPoints[index]._line > line)
{
fixedPoints[index] = new MyPoint(fixedPoints[index]._line - 1, fixedPoints[index]._list);
}
}
_needClearLines.RemoveAt(_needClearLines.Count - 1);
_screenMain.RefreshScreen();
}
else
{
// 先停止定时器
CancelInvoke("FillUpOneLineByCleared");
// 创建新方块
CreateNewBlock();
// 启动核心逻辑
InvokeRepeating("GameCore", 0, 1);
}
}
修改ClearOnePoint()中的else块:
else
{
// 先停止定时器
CancelInvoke("ClearOnePoint");
// “填补单行”启动
InvokeRepeating("FillUpOneLineByCleared", 0, 0.1f);
}
再次运行游戏,你可以看到消除和填补都有了一个简单的过渡,至少看起来不像上一节那么生硬了。你可以把速度改快一点,看起来更流畅。
然后,上一节的两个方法已经没有作用了,删除即可:
- ClearFullLines()
- FillUpClearedLine()
关于游戏核心逻辑部分,除了重玩之外,几乎都完成了,但是重玩功能关系到许多数据的重置,现在还有许多核心逻辑外的东西没写,所以重玩放到后面再写。
接下来,我们需要好好整理一下代码和思路,准备下一阶段的开发。
代码链接:https://pan.baidu.com/s/10C0__VA0aadb6AF3Uli6zg
提取码:1nca