UE4-小练习-俄罗斯方块

  1. 1. 搭建棋盘
  2. 2. 构建方块
  3. 3. 旋转方块
  4. 4. 控制消除
  5. 5. 总结
  6. 999. Ref

做了一个俄罗斯方块。纯蓝图。本文记录制作过程中一些有意思的东西。

完成度还可以,能玩,难度挺高的,有兴趣的朋友不妨试试。(想着逻辑可能会比较简单,所以用纯蓝图来做了,结果连线有些乱)

演示视频:https://www.bilibili.com/video/BV1iU4y1A7qc/

项目地址:https://github.com/tiax615/Tetris

关于俄罗斯方块的游戏介绍资料很多不再赘述,发现一个 Tetris Wiki,十分详尽和专业:https://tetris.wiki/Tetris.wiki

1. 搭建棋盘

刚好UE4默认的材质就是棋盘格,只需要调整好尺寸,就能能搭建棋盘。

但都用UE4了,不该搞个3D俄罗斯方块吗?想啊,一开始就准备这么做,但有问题。俄罗斯方块的棋盘是10x20,即10行20列。10行还行,但20列是比较高的,使用透视相机的话,边缘存在很大的畸变

尝试通过调整相机的视场角fov来降低畸变。默认的相机fov是90°,我调整至60°,然后将相机放在合适的位置(对准棋盘中心并相距合适的距离)。效果如下,畸变依然不能忽略,不够好看。底部的方块看起来十分变形,然而底部却是游戏中最常见最重要的区域,万丈高楼平地起。

于是我使用了正交相机,降维打击,变成2D。

2. 构建方块

俄罗斯方块有9种方块,对应字母I、J、L、O、S、T、Z。

我使用BP_Tetris作为父蓝图,各种形状的方块继承自他。

对于父蓝图BP_Tetris,他由4个Cube组成,每个俄罗斯方块都包含4个Cube。

每个俄罗斯方块种4个Cube的排列方式不同,也就是位置不同。使用一个结构体,来记录4个Cube的位置。

俄罗斯方块是需要变形旋转的,旋转规则下一节会介绍,不是围绕中心旋转。因为最多也只有4种旋转形态,所以这里直接把每种形态的Cube位置信息记录下来,方便起见。

在构造脚本种执行SetCube方法,设定每个方块的相对位置和颜色。颜色是使用动态材质,修改材质实例中的颜色参数来实现的。

3. 旋转方块

那么,要怎么旋转呢?围绕中心吗,那中心在哪里呢?

查阅资料,俄罗斯方块有多种旋转系统。例如下面的 Arika Rotation System (ARS),定义了方块初始生成时 Initial Spawn 的位姿,和每种旋转状态。并且随着游戏的发展,这些旋转模式还有特殊的规则,可以用于比赛中。例如 Kicks,在方块旋转时如果格子被占用了,这个方块会移动到基本旋转的左侧或右侧。类似的旋转系统还有 Super Rotation System (SRS)。

既然这么复杂,我也不想面向比赛开发,所以就使用了一种简单的旋转系统:Nintendo Rotation System。这种旋转系统给人的感觉,就像小时候玩的掌上小游戏机。(Games using this rotation system generally have no wall kick and no lock delay.)

确定了旋转系统,知道了每种俄罗斯方块的位姿状态,就可以给第2节中每个方块子蓝图写入信息。

4. 控制消除

再仔细思考下要做什么:

  • 生成和下落:方块从 Spawn 开始下落,一直下落到下方格子被占用为止
  • 左右移动、快速落下、旋转:例如左移,先判断方块能否左移,如果左边要去的位置被占用或超过边界,就不能左移。其他方向的移动类似
  • 消除:
    • 一块俄罗斯方块下落完成后,需要知道是否有行的每一列都充满了小格子,是则消除此行。
    • 每次最多消除4行,因为最长的I是4行。不可能消除更多的行,这不是开心消消乐,不会在一次下落中额外落下方块。
    • 消除后,上面行中的方块需要下行n行。
    • 如果一个俄罗斯方块中的4个小方块都被消除了,那这个俄罗斯方块应该被 destroy,否则对象数量无限增加。

我使用一个字典来记录棋盘中格子是否被占用了,字典的类型是 {int : USceneComponent*}。

key 表示第几行第几列,因为蓝图没有二维数组,恰好这个10x20的棋牌又可以规则的用一维数组来替代二维。例如第0行表示最底部的行,第19行表示最顶部的行,第3行第7列的 key 是37。同时这个 key 值也对应了方块的坐标,例如37的世界坐标是 (0, 300, 700),方便设置方块的移动。

value 是小方块的对象引用,为什么这里不直接用一个 bool 值表示格子有没有东西,而要使用引用呢?因为消除的时候,需要消除这一行中的每个小方块,而又不能消除大的俄罗斯方块。

完成消除的蓝图如下。

5. 总结

  • 我的做法舍弃了射线检测和碰撞检测,使用数组(字典)来进行各种判断
  • 逻辑稍微复杂一点的话,蓝图连线就会变乱
  • 主要是部分是方块的生成,能否移动的判断,消除时候要做的事情

999. Ref

  1. 百度贴吧-【求助】俄罗斯方块的旋转系统:https://tieba.baidu.com/p/1380321204?red_tag=2618065064
  2. Tetris Wiki - Arika Rotation System:https://tetris.wiki/Arika_Rotation_System
  3. Tetris Wiki - Nintendo Rotation System:https://tetris.wiki/Nintendo_Rotation_System

感谢阅读,欢迎讨论~


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 cdd@ahucd.cn

×

喜欢就点赞,疼爱就打赏

B站 cdd的庇护之地 github itch