在第四节中我们实现了图形的拖拽功能,拖拽的图形最终需要被放置在网格的对应位置上。
先说一下实现思路:
使用拖拽图形上的左下角的位置作为图形位置,与整个网格的位置进行比对。如果图形位置与当前单元格的位置匹配,则根据图形的数据从当前的单元格开始填充,直到填充完整个图形为止。
看不懂?没关系。接着往下我会一步一步的进行拆解和分析。
# 计算拖拽图形左下角的位置作为图形的比对位置
如图,是要拖拽的图形,由四个正方形组成的“田字”形,每个正方形的边长是60,两个正方形之间的间隔是2。左下方的红色圆点为我们将会计算的图形位置。假设当前图形的中点位置(即坐标轴的中心)为(x,y),根据正方形的边长和间隔,可以计算出红色的点的位置是(x-31,y-31)。
在场景加入四个边长为60的正方形,将四个正方形同时选中,点击鼠标右键,选择“将选中图层组成容器”。将它们放在一个容器下。
如图,四个正方形被放在了“容器-1”中。坐标轴中心的位置即为“容器-1”的坐标位置。
在游戏中每个图形都是由多个正方形组成,我们会统一使用容器来打包这些正方形,作为图形使用。
容器中的四个正方形的坐标位置分别是这样的。
为什么要使用左下角的位置作为图形位置与网格位置进行比对呢?
理由一:便于确定图形想要放置的位置。
假设现在我们使用图形的中心位置作为比对位置。
如图,图形的中心位置位于第二行第二列的网格中,但是这个田字形的图形应该安放在哪里呢?不是很直观,也不太好判断。
现在我们将图形的左下方位置作为比对位置。
如图, 左下方的蓝点当前位于第一行第一列的格子中,可以很容易的看出当前图形是想要放在左下角的四个格子中,像下面这样。
最终的比对位置的计算可以进行“四舍五入”处理,这样能够容许一定的位置偏移和误差,即只要位置差不多的话,图形就应该被放置上去。
理由二:便于图形的绘制,我们将会总是从左下角的位置开始遍历绘制整个图形。后续会进行解释。
#用图形位置与网格位置进行比对
假设当前的“田字”图形位于网格的正中间。
在绘制网格一节中,我们已经讲过了如何计算网格左下角的起点位置。根据图形当前的位置(蓝点),网格起点(红点)位置以及单元格的边长,就能够计算出当前图形左下方的点(蓝点)位于网格中的行号和列号。图中当前蓝点位于第5行第5列的格子中,我们将会从这个格子开始绘制整个田字图形。
图形点(x,y),网格起点(a,b),单元格边长n
行号 = (y-b)/n + 1
列号 = (x-a)/n + 1
获取到行号和列号后,就可以进行下一步填充操作了。
#在网格上填充图形
实现思路:获取到当前图形在网格中的位置,也就是我们上一步的操作。从当前位置开始,根据图形的数据依次填充网格中的单元格。
依旧很难理解?没关系,接着看。
第一节中我们讲过,计算机只能够理解数据,我们所看到的图形,想要计算机能够理解,就需要映射成数据,像下面这样,第一个“田字”图形其实是由两行两列的“1”组成。
下面我们就为“田字”图形设置数据。选中“容器-1”,为其添加一个局部变量表格数据,命名“形状数据”。
在表格中增加两行两列数据,并且都设置为1。(图形由四个正方形组成,所以四个数值都是1)
接下来,为“容器-1”增加一些变量,在稍后实现逻辑时会使用。
“容器-1”的局部变量:
- 被按住:当前图形是否被按住,用于图形的拖拽。
- 网格位置X/Y: 记录当前图形位于整个网格的哪一行,哪一列。
- 行号/列号:用于田字图形的表格数据的遍历。
- 起点偏移X/Y:用于计算图形的左下角的点的位置。
全局变量:
- 全局-列号/行号:用于记录要填充的方格的行号和列号。
- 全局-单个格子边长:每个正方形单元格的边长。
- 全局-总行数/列数:网格一共多少行,多少列。
- 全局-起点X/Y坐标:整个网格的左下角的起点位置。
你可能注意到了,我在所有的全局变量前增加了前缀“全局-”,这样,当你在积木块中选择变量时可以很容易的将全局变量与局部变量区分开,尤其是当变量很多的时候,这是一个不错的习惯,推荐你使用。
接下来,我们先在场景中增加一个“填充方块”,用于在网格上进行填充。
如图,在场景中加入了一个填充方块,为了与红色的拖拽图形区分开,把它设置成绿色。
为其增加如下的积木逻辑。
逻辑不复杂,当自己被克隆出来后,将自己设置到网格中的对应位置。
接着,选择“容器-1”,为其增加如下的积木逻辑:
重点包含两部分的逻辑,被拖拽时,计算图形位于网格中的位置。手放开时,从当前的位置开始,遍历当前图形的数据,并在网格上对应的位置填充方块。
点击“预览场景”,看一下效果。
拖拽图形放置在网格上,就会在对应的位置上填充图形。观察一下,即使拖拽图形的位置与网格的位置有一些偏差,也会在正确的位置上进行填充。这样会给玩家带来比较良好的游戏体验:虽然你的手指头控制的不是很精准,但是没关系,我知道你其实是想放在那里的。
总结一下:
这一节我们了解了如何将拖拽的形状填充到网格中,包括实现思路以及具体的实现方法。虽然包含了比较多的计算,但是这些计算其实都不复杂,对照着图片在纸上画一下更容易理解。