接上文.
已经实现了方块下落之后,可以意识到,平移变得非常简单.因为我们已经实现了边界检查的函数,只要把移动目标坐标放进去判断就可以了.
在UPDATE中增加如下代码
if (Input.GetKeyDown(KeyCode.RightArrow) && !CheckCollision(nowControlBlock, nowBlockPos + new Vector2(1, 0)))
{
MoveBlockTo(nowControlBlock, nowBlockPos + new Vector2(1, 0));
}
if (Input.GetKeyDown(KeyCode.LeftArrow) && !CheckCollision(nowControlBlock, nowBlockPos + new Vector2(-1, 0)))
{
MoveBlockTo(nowControlBlock, nowBlockPos + new Vector2(-1, 0));
}
就可以实现方块的自由左右移动.
在此基础上我们还可以添加快速下落的控制代码
if (Input.GetKeyDown(KeyCode.DownArrow))
{
DoFall();
}
重构DoFall,用返回的布尔值判断DoFall后是否直接落地
public bool DoFall()
{
Vector2 targetPos = nowBlockPos + new Vector2(0, 1);
if(!CheckCollision(nowControlBlock,targetPos))
{
MoveBlockTo(nowControlBlock, targetPos);
return true;
}
else
{
FallGround(nowControlBlock);
NextBlock();
return false;
}
}
然后在update中添加直接落地的按键控制代码
if (Input.GetKeyDown(KeyCode.LeftControl))
{
while (DoFall()){}
}
至此,旋转之外的控制已经完全结束.
需要注意的是,用Input.GetKeyDown,每次按下键盘案件只响应一次操作,而用GetKey则会每帧响应一次,若要实现固定时间响应一次操作,可以用GetKey结合timeCount的实现方式.因此内容是仅针对操作进行优化的过程,故而暂不在此进行讨论.
在我们想要制作旋转的时候,一般有两种思路.其一是根据我们现有的数据,用代码来计算每次旋转之后squareCoord的值.这种方式比较简单,顺时针旋转时,只要将每一个正方形坐标的x和y对调并让x乘以-1就能实现(逆时针则是y乘以-1),但是用这种方法进行旋转时,因为我们最小的单位是1个正方形,而方块的中心点可能不是整数,无法进行完美旋转,会使游戏进行中出现一些与玩家认知不协调的情况.处起来十分复杂(也就是所谓的Super Rotation System - SRS旋转系统)
在这里,我们不对方块的旋转方法进行更深入的讨论(可以搜到很多不同的旋转规则)
先用有现有实例的Arika Rotation System(ARS旋转系统)来实现
(图片引用自https://tieba.baidu.com/p/1380321204)
从这个系统来看,我们不需要找出方块的旋转规律用程序进行计算,而是把方块旋转的顺序,用不同的坐标list固化在blockBase中即可.
这种方式的好处是,游戏开发者可以较为自由的用我们自定义的编辑器来把握方块旋转的规则,减少程序修改计算公式的麻烦.