3

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)

 1 year ago
source link: https://blog.51cto.com/u_15530520/5411797
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)

推荐 原创

嗨!大家好,我是小蚂蚁。

今天,我们来继续学习下一个模块:形状碰撞检测

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_俄罗斯方块

在游戏开发中,我们所说的“碰撞”经常指的是物理碰撞,什么是物理碰撞呢?一般的在游戏开发工具中都会包含一个叫做“物理引擎”的东西,它的作用就是在游戏中模拟出现实中的物理效果。例如,我们扔一个东西,这个东西会因为重力而下落,最终落到地上,与地面发生碰撞。在游戏中,我们可以借助物理引擎,来模拟出东西下落掉到地面上的效果。当东西掉到地面上时,我们就说这个东西与地面发生了碰撞

但是,在俄罗斯方块这个游戏中,是不需要使用物理引擎的,所以这里的“碰撞”指的并不是物理碰撞,而是通过计算来判断两个方块是否相邻,如果相邻,我们就说它们发生了“碰撞”。

在俄罗斯方块游戏中,“碰撞”一共包含下面的这 4 种情况:​

1.当形状达到最下方一行时,碰撞,形状停靠。

2.当形状下落时,任何一个位置碰到下方已有的方块,碰撞,形状停靠。

3.当形状向左/右移动时,两侧碰到任何一个已有方块,碰撞,形状不能再向两侧移动。

4.当形状切换时,如果新状态碰到任何一个已有方块,碰撞,形状不能切换到新状态。

今天这篇文章,我们先了解一下前两种情况。

下边界的碰撞

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_游戏开发_02

如图,当一个形状达到了最下方的第一行时,它就不能够再继续向下移动了。我们把这种情况叫做“下边界的碰撞”

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_俄罗斯方块_03

判断起来也很简单,红色圆点代表的是形状当前的位置,由于形状的状态不同,判断是否与下边界发生碰撞的距离也不同,如图,在 1,3 状态下,与下边界的碰撞距离是 1 个方块长度,在 2,4 状态下,与下边界的碰撞距离是1.5 个方块长度。

下落的碰撞

接着,来看一下在形状下落的过程中,如何检测是否发生碰撞。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_游戏开发教程_04

如图,下方的红色方块表示的是之前已经摆放的方块,上方的绿色方块是下落的“形状1”,此时,它们应该发生碰撞,绿色的形状应该停止向下移动,摆放在当前的位置上。

对于下边界的碰撞来说,由于下边界是固定不变的,所以我们只需要根据当前状态,判断与下边界的距离即可判断碰撞。但是在游戏中,那些已摆放的红色方块的位置是不确定的,这就导致了发生碰撞的情况也是不确定的。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_游戏开发教程_05

如图,所有的情况都会发生“碰撞”。

对于这样不确定的情况,该去如何检测碰撞呢?这时,我们就需要用到数据了。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_游戏开发_06

如图,右侧的图片是一个数据表格,这个数据表格与左侧的游戏界面是对应的。现在,我们用 0 表示空位置, 1 表示有方块,然后对照着左侧的游戏界面将右侧的表格填满。这样,我们就把当前的游戏抽象成了数据,这个就叫做数据抽象化。(之前专门写了一篇与数据抽象化有关的文章​ ​《所有消除游戏背后那些看不见的数字》​​,基本上所有的消除游戏都离不开它)

填充上数据之后,我们再来看一下各种情况的碰撞。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_俄罗斯方块_07

试着观察一下碰撞的规律:只要当前形状上的任何一个方块位置的下方是 1 ,那么当前就会发生碰撞。

现在,我们重新再描述一下碰撞检测的过程:

依次查看当前形状上的每一个方块,如果发现有任何一个方块下方的位置是 1,那就意味着当前形状与已堆叠的方块发生了碰撞。

接下来,我们就来实现这个碰撞检测的过程。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_游戏开发_08

如图,是“形状1”在 4 种不同状态下所对应的数据表格。如果,我们能够知道形状上的每一个方块在整个数据表格中的位置(行列号),那么,就能够依次的判断出下方的位置是否有 1 了。

在进行遍历的时候,我们一般都是习惯于从左往右,从上往下。所以,这里将左下方的位置当作遍历的起点。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_俄罗斯方块_09

如图,我们把红色的点叫做计算点,坐标轴的中心是当前形状的位置(x0,y0),根据图片可以很直观的看出来不同状态下的计算点的位置。

这里算出的计算点的位置是在游戏坐标空间中的位置,还需要将它们进行一次转换,因为我们需要知道的是计算点在数据表格中的哪一行哪一列。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_游戏开发_10

计算公式在这里了,已经讲过很多次了(所有的消除游戏里都会用到),就不再解释了。总之,我们能够获取到计算点在数据表格中的哪一行哪一列。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_游戏开发_11

在得到了计算点的行列号之后,接下来就只需要以计算点为起点,依次查看每一个格子下方的数值,只要有任何一个格子下方的数值为 1,就证明发生碰撞。

上方举的是“形状1”的例子,俄罗斯方块中一共有 7 种“形状”,按照其包围矩形的形状可以分为 3 种类型。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_游戏开发教程_12

形状1~5 是一种类型(2x3),形状6是一种类型(1x4),形状7是一种类型(2x2)。

不同的类型又对应着不同的计算点位置。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_俄罗斯方块_13

好了,以上就是理论基础了,接下来我们来看一下具体实现的积木逻辑。

首先,我们创建一个全局的表格变量,叫做“网格数据”,作用于整个俄罗斯方块游戏。0 表示没有方块,1表示有方块。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_游戏开发_14

接着,我们为“形状1”创建 4 个表格数据,对应的就是它的四个状态。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_俄罗斯方块_15

然后,根据形状状态在表格中添上对应的数据,有方块的位置是 1 ,没有方块的位置是 0。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_俄罗斯方块_16

接着,来看一下积木逻辑。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_游戏开发教程_17
俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_游戏开发教程_18

最后,看一下碰撞检测函数中的积木逻辑。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_游戏开发_19

这里比较难以理解的地方是同时对两个表格(一个全局数据表格,一个形状数据表格)进行遍历检查。我习惯于先在纸上画出来,进行推演。如果能够在纸上推演出整个过程话,使用程序来实现这个过程就会简单很多。

今天的内容就到这里了,稍微总结一下:我们了解形状碰撞检测中的两种情况,第一种“下边界的碰撞”,比较简单,第二种“下落的碰撞”,相对比较复杂,需要借助表格数据来进行碰撞的检测。

如果你对于消除游戏中的数据抽象化还不是很理解的话,借着这次机会可以好好研究一下。

有些东西是值得花时间深究的,因为它们有着以一当百的效果,搞定了一个就相当于搞定了一百个,数据抽象化就是这样的东西。


我是会做游戏也会教你做游戏的小蚂蚁,欢迎关注微信公众号【小蚂蚁教你做游戏】,领取全网最全的微信小游戏开发原创教程资料,每天学点儿游戏开发知识。

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)_游戏开发教程_20

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK