俄罗斯方块
英文名:tetris
Github 另有视频,详见各视频平台。
参考资料
【正经科普向】什么是现代俄罗斯方块?(bilibili.com)
名词
俄罗斯方块准则(Tetris Guideline,中文也称俄罗斯方块基准、俄罗斯方块标准)是俄罗斯方块公司制定的一套游戏准则。
方块(Block):组成各个砖块的最小正方形基本单元。
四连方块(Tetromino):由若干个方块组成的形状,我称之为:砖块。放置于场地中的砖块,将被当做是普通砖块的堆叠,不再称之为砖块。
场地(Playfield):砖块放置的区域。
- 格子(Cell)场地中的一个单元格。
- 天花板(Ceiling):用于分割界内行和界外行的水平线。大部分游戏将天花板置于第20行的顶部,并与游戏区的可见部分的顶部相同。四连砖块从天花板正上方下落。也被称作天际线(skyline)。
- 缓冲区(Buffer Zone):在游戏区顶部的不可见区域,用于判定各种条件的游戏结束。缓冲区的大小与场地的大小相同。
- 消行(Line clear):锁定砖块后,形成完整的一行的操作。该行将会消失,其上面的一行将会向下填充。
活动砖块(Active Piece):活动砖块。
- 重力(Gravity):每隔多长时间下落一次。
- 锁定(Lock):当一个砖块降落到场地的底部或其他砖块上时,它将成为场地的一部分,不再受玩家的操作。
- 锁定延迟(Lock Delay):锁定延迟。砖块着陆与其锁定的时间间隔。
- 软降(Soft Drop):即增加方块下落速度(也即重力)的操作。
- 硬降(Hard Drop):瞬间落下,不会立即锁定方块。
- 瞬降(Firm Drop):瞬间落下,并立即锁定方块。
- 进入延迟(Entry Delay):独立于重力,赋予新砖块额外的滞空时长。这段时间内可以旋转,不会下落,但不能移动。
注意:
进入延迟(Entry Delay)在参考资料中的定义是:前一个砖块完成下落和后一个砖块进入的时间差。
我在实现中舍弃了瞬降(Firm Drop)这一概念,使得活动砖块每次都有锁定延迟,这样原本“进入延迟”的作用就显得微乎其微。重新设计后的“进入延迟”使得砖块可以在进入场地后有短暂的、不受重力影响的、能够调整姿势(即能旋转)的时间。
幽灵砖块(Ghost Piece):在场地中显示当前砖块下落着陆位置的标记。
砖块预览(Next Piece):即将进入场地的砖块。
暂存砖块(Hold Piece):玩家可将任何下落中的砖块储存到该序列中,以便日后使用。当被调用时,暂存的砖块与当前下落的砖块交换,并从其生成点开始下落。
超级旋转系统(Super Rotaion System):砖块旋转过程中,可能会碰到阻碍如:墙(此时称踢墙)、地(此时称踢地)还有场地里的方块。
随机器(Randomizer):根据算法提供砖块。
设计与实现
四连方块(Tetromino)
依照彩虹七色,依次是红、橙、黄、绿、青、蓝、紫。使用一个二维数组来表示,根据不同旋转姿态有着不同的二维数组。砖块对象只需要一个属性用来表示当前的姿态就好了。各姿态具体可见 旋转系统。
场地(Playfield)
21~23行被称之为缓冲区(Buffer Zone)。
场地用一个23行10列的二维数组存储方块(Block),方块自身仅有一个颜色属性。
它负责吞并活动方块、消行(Line clear)。
活动砖块(Active Piece)
活动砖块相较于四联砖块多了一个位置坐标。不同砖块的出场位置如下图。
它受重力(Gravity)影响,会下落(Fall)。它也是玩家交互的核心,处理玩家平移、旋转还有暂存操作。
幽灵砖块(Ghost Piece)
即活动砖块自由落体的最终位置。它会监听活动砖块的位置,当其放生变化时会重新计算自身位置。
它的颜色较浅于活动方块,并且当其自身位置与活动方块相同时则不绘制。
砖块预览(Next Piece)
自上而下依次显示3个未来的活动砖块,最上面的则为下一个活动砖块。它从随机器(Randomizer)中获取砖块。
暂存砖块(Hold Piece)
每个新的活动砖块入场后可以获得一次暂存(Hold)的机会。
暂存(Hold)操作后,如果已有暂存砖块则与其交换,交换后,活动砖块将回来到入场位置;如果没有则直接下一个砖块。
随机器(Randomizer)
根据算法提供未来将会入场的砖块。这里只实现了"7-Bag",即7个不同砖块随机顺序为一组,一组一组生成的算法。
超级旋转系统(Super Rotaion System)
各个砖块的姿态如下图。0
为初始态,R
为初始态右旋转90度,2
为初始态180度旋转,L
为初始态左旋转90度。砖块用一个二维数组存储,有3X3和4X4,元素只为0或1,1表示有方块,0表示没有方块。
以上图的R
形态的I
(第一行那个)为例,当它贴着左右墙壁旋转时,按照图例它将超出场地(Playfield)。在早期的俄罗斯方块中它无法旋转,现在在超级旋转系统的设定下,它多出4个测试点(加上原始的,共5个)。我们将依次对5个测试点做测试,当全部失败时则表示无法旋转。
说明:
下表中的数据表示坐标变换。如(-1, -2),则表示下降一行、左移两列。
目录结构
$ tree
.
├── icon.jpg
├── icon.jpg.import
├── logo.png
├── logo.png.import
├── project.godot
├── scene
│ ├── active_piece.gd
│ ├── active_piece.tscn
│ ├── arena.gd
│ ├── arena.tscn
│ ├── ghost_piece.gd
│ ├── ghost_piece.tscn
│ ├── hold_piece.gd
│ ├── hold_piece.tscn
│ ├── next_queue.gd
│ ├── next_queue.tscn
│ ├── play_field.gd
│ └── play_field.tscn
└── script
├── coordinates.gd
├── global.gd
├── randomizer.gd
├── rotation_system.gd
└── tetromino
├── block.gd
├── i.gd
├── j.gd
├── l.gd
├── o.gd
├── s.gd
├── t.gd
├── tetromino.gd
└── z.gd