第二十六节 实现旋转方块

想到我开发的第一版俄罗斯方块,处理旋转的代码也是非常粗暴,就是所有方块的旋转都单独写一段代码来处理,而不像现在的,使用一个通用的算法就搞定所有方块的旋转。

01.旋转图形算法

最出名的就是矩阵旋转,看了下介绍和实现流程后,果断放弃了,我相信绝对有超级简单的几行代码就能搞定方块旋转的算法。毕竟我只是旋转90度,根本用不到矩阵里面的各种角度计算。然后,我就寻找到了一段旋转数组的代码,经过几个小时的探索后,成功敲出了属于我这个项目的旋转方块代码:

// 旋转方块
void RotateBlock()
{
    // 获取方块宽
    int blockWidth = _blockLayer.Size._width;
    // 存储旋转后的方块数据
    List<MyPoint> rotatedBlockData = new List<MyPoint>();
    // 开始旋转
    foreach (var item in _blockLayer.ViewData)
    {
        MyPoint rotated = new MyPoint();
        rotated._list = item._line;
        rotated._line = blockWidth - item._list - 1;
        rotatedBlockData.Add(rotated);
    }
    // 替换成旋转后的方块数据
    _blockLayer.ViewData = rotatedBlockData;

    _screenMain.RefreshScreen();
}

添加按键处理代码:

// 按键 - 上方向键
if (Input.GetKeyDown(KeyCode.UpArrow))
{
    // 立即旋转一次
    RotateBlock();
    InvokeRepeating("RotateBlock", 0.2f, 0.2f);
}
if (Input.GetKeyUp(KeyCode.UpArrow))
{
    CancelInvoke("RotateBlock");
}

不出意外的话,你可以成功看到方块的旋转效果。顺便提一下,我的方块旋转后都是停靠在左下角的,就是说,旋转后的图形,坐标是没有任何变化的(为了说明这个问题,我打了很多字,后来感觉还不如用图片解释方便):



如图所示,左侧的是我目前的旋转方式,旋转完成后,方块依然是以左下角对齐的。而右侧的旋转方式会导致方块的纵坐标下降。
之所以我使用左侧的方式是因为:屏幕本来就很小,如果因旋转而导致方块被迫下降的话,感觉对玩家不公平,当然,你可以旋转完成之后调整纵坐标,这些都是很灵活的修改的。我主要目的还是为了说明我是如何旋转方块的。

02.旋转算法原理

其实上面代码中,核心代码就是那两行调整坐标的代码:

rotated._list = item._line;
rotated._line = blockWidth - item._list - 1;

我觉得有必要来解释下转换的原理。



第一行代码是计算旋转之后的列号。如上图所示,旋转后的方块(右侧)的第一列(从左往右数)就是旋转前的方块(左侧)的第一行(从下往上数),第二列就是旋转前的方块的第二行。



第二行代码是计算旋转之后的行号。如上图所示,第一、二、三列分别转换为第三、二、一行。可能第一眼看过去,不知道如何找到一个通用的公式来转换,其实很简单:红色点与左侧的偏移为0,旋转后,红色点与顶端的偏移为0;黄色点与左侧的偏移为1,旋转后与顶端的偏移为1;绿色点与左侧偏移为2,旋转后与顶端偏移为2。旋转之后,方块的宽则变成高度,左侧方块的列号 = 方块的宽 - 列偏移,旋转之后,行号 = 方块高 - 行偏移,因为方块高与旋转前的方块宽一样,行偏移与旋转前的列偏移一样,所以公式为:

旋转后的行号 = 方块的宽度 - 列偏移距离

红色点列偏移为0,旋转后,与顶端的偏移就是3 - 0 = 3
黄色点列偏移为1,旋转后,与顶端的偏移就是3 - 1 = 2
绿色点列偏移为2,旋转后,与顶端的偏移就是3 - 2 = 1
当然,这是错误的结果,因为下标是从0开始,所以最终还要再减1,那么最终公式就是:

旋转后的行号 = 方块的宽度 - 列偏移距离 - 1

怎么样,是不是很简单。好了,下一节,来处理旋转的碰撞。

代码链接:https://pan.baidu.com/s/1XJgOGIbBGIeD3_cDwhfUoQ
提取码:uloj

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容