作为一个Rogue Like游戏,随机生成地图的功能是必不可少的。在上一篇博文(Unity5 官方教程笔记(2D Rogue Like)01 —— Game Manager)中,我们知道了在此项目中,负责这项工作的类叫做“BoardManager”,而且同时它还要负责对地图的存储工作。下面笔者就来对这个类的功能进行介绍。
首先还是看一下代码的基本结构:
可以看到在这个类里面,我们:
- 规定了地图的尺寸
- 设定了墙壁(地图)单元和食物单元的生成数量(也就是在特定关卡中这些单元的数量范围)
- 保存了各类单元可以使用的图片(Sprite)类型
- 使生成的单位可以以随机顺序排列并且可以使用随机的图片显示
在这里,会被外接直接调用的方法只有SetupScene(),所以先来看看它:
在这个方法里,首先生成了地图内的墙壁和地面(BoardSetup),接下来初始化了用来随机选取位置的数组(InitializeList),之后又将墙壁单元、食物单元以及敌方单位随机放置在地图上,最后把出口放在了地图的右上角。
BoardSetup()方法:
在这里,出现了一个叫Instantiate()的方法,个人理解这个东西本质上就是c#中assembly中提供的功能:动态的实例化某个对象。里面用到的参数分别为:需要被实例化的对象,实例化后的坐标和实例化后的角度。为了增加游戏的随机性,所以我们在选择需要被实例化的对象的时候,是从事先设定好的范围中随机选取的一个。在本例中就是从outerWall(外墙)的候选数组outerWallTiles内随机选取了一张图片用作显示。
同时,将每一个创建出的实例标记为boardHolder的子对象,便可以使得他们共享一个坐标系,并便于管理,避免出现混乱。
InitiallizeList()方法,功能很简单,用于初始化一个之后将用来随机选取位置的候选数组。
这样通过在这个数组中选择某个单元的方法,比直接随机的效率会更高,同时也会避免两个单位同时被设定在了一个单元格内的可能。这一点从RandomPosition()方法中便可以看出来:
每选择了一个新的位置之后,这个位置便会被从gridPositions数组中被移出。
最后便是LayOutObjectAtRandom()方法:
这个方法便是把给定范围的数组中的内容(tileArray)选定随机的某个放置在地图上的随机位置,且放置的数量是指定范围中的随机数字(minimum 至 maximum)。
由于在代码中直接创建了“Board”对象(BoardSetup()方法),并且所有新添加的内容都是该对象的子对象,因此当创建完毕之后,整张地图便被添加到了游戏场景中。
可以看到的是,这里面所有的对象坐标使用的均为相对坐标(即并非以像素或英尺等绝对标准进行标注的坐标),且所有的图片资源尺寸一样,因此可以判断这种方法将更有利于匹配不同的屏幕尺寸,同时应该更符合unity的使用习惯。不过由于笔者对相对坐标和图片资源尺寸之间的匹配方式并不了解,所以暂时对于此处还有一些不太明白的地方,待今后学习之后将会在此补上或者单开一篇文章进行说明。