带有Sprite Kit的过程图块贴图

我最近开始了一个新项目:建立一个城市建筑/模拟游戏。 我想使用SpriteKit及其SKTileMapNode类创建程序性地形。 我开始在网上寻找并阅读文档,但是关于如何以编程方式进行操作的内容并不多。 因此,我决定写本教程系列,介绍我在构建新游戏时所学的知识。 首先,按程序创建基本的瓷砖网格!

SpriteKit和图块

苹果公司创造了一种非常简单的方法来管理一整块瓷砖及其在SKScene中的放置,但是,这不允许我们(至少不是我发现的)以程序方式生成我们的瓷砖地图。 因此,我们必须更深入地研究它们的实现。

首先,让我们使用“游戏”模板创建一个新的Xcode项目,并将引擎设置为SpriteKit。

接下来,我们添加一个Apple的默认图块集。 所以我们去File-> New-> File。 然后转到“资源”部分,然后选择“ SpriteKit Tile Set”。 然后选择您要查找的任何图块类型(Apple支持Grid,Isometric和Hexagonal),在此示例中使用哪种类型都没关系。

这将创建一个SKTileSet,其中包含所有平铺图像。 然后将集合分成不同的SKTileGroups。 这些组将是不同的地形,因此水,草,沙等。在这些组中是SKDefinitions,它们定义了放置瓷砖的位置。 我们现在不需要为此担心很多,但有关更多信息,请参见WWDC 2016视频:“ SpriteKit的新功能,Session 610”。

GK噪声

该地图最重要的部分是它是按程序生成的,为了做到这一点,我们将使用GKNoise创建一个“地图”,以说明我们如何布局平铺的世界。 苹果有几种不同类型的预建噪声源(GKNoiseSource),但是对于我们的用例,我们将使用GKPerlinNoiseSource。 此来源旨在为我们提供自然的地形。

  func createNoiseMap()-> GKNoiseMap { 
//获取我们的噪声源,可以进一步自定义
let source = GKPerlinNoiseSource()//使用我们的源代码初始化GKNoise对象
let noise = GKNoise.init(source)//创建地图,
// sampleCount =到网格中的图块数(行,列)
let map = GKNoiseMap.init(噪声,大小:vector2(1.0,1.0),原点:vector2(0,0),sampleCount:vector2(50,50),Seamless:true)
返回地图
}

首先,我们基于GKPerlinNoiseSource创建噪声源。

然后使用我们的源代码创建一个新的GKNoise对象。

最后,我们使用该噪声对象创建地图。 确保将sampleCount参数设置为与稍后将用于SKTileMapNode的行和列数相同的数量。 有关其参数如何工作的更多信息,请参见GKNoiseMap。

SKTileMapNode

好了,现在我们终于可以制作地图了。 为了在SpriteKit中做到这一点,我们将使用SKTileMapNode,它将所有我们的单个磁贴精灵合并到一个节点中,从而使磁贴图基本上成为SKNode。 它还继承了SKNode可以执行的所有操作,因此您可以像使用SKSpriteNode一样,使用SKActions转换此切片地图。

让我们看一些代码

  //获取我们上面制作的噪声图 
让noiseMap = createNoiseMap()//定义我们的SKTileSet:
//这是.sks TileSet文件中Set的名称
让tileSet = SKTileSet(named:“ Sample Isometric Tile Set”)!//定义我们的Tile Size:
//这取决于设置,但等距设置使用128x64
让tileSize = CGSize(width:128,height:64)//定义我们的列和行
让行= 50,列= 50 //创建图块地图
让地图= SKTileMapNode(tileSet:tileSet,
列:列,
行:行,
tileSize:tileSize)
map.enableAutomapping = truefor col in 0 .. <cols {
对于0中的行。<行{
//从我们的“噪声贴图”中获取一个值,返回-1.0到1.0
令val = noiseMap.value(at:vector2(Int32(row),Int32(col)))
//然后我们将决定哪些图块对应于什么值
开关val {
情况-1.0 .. <(-0.5):
如果让g = tileSet.tileGroups.first(其中:{
($ 0.name ??“”)==“水”}){
map.setTileGroup(g,forColumn:col,row:row)
}
默认:
如果让g = tileSet.tileGroups.first(其中:{
($ 0.name ??“”)==“草”}){
map.setTileGroup(g,forColumn:col,row:row)
}
}
}
} self.addChild(地图)

我们的代码非常简单,我们生成了噪声贴图,图块集,图块大小和图大小。 然后,我们初始化SKTileMap节点并启用自动映射。 自动映射用于允许SpriteKit根据其周围的图块自动设置图块类型。 您可以在Xcode项目中创建的TileSet .sks文件中查看SKTileGroup时看到使用的不同类型的图块。

接下来,我们根据“噪波贴图”中指定的值来设置瓦组的位置。 由于“噪声贴图”返回的值介于-1.0到1.0之间,因此我们将使用“快速范围”来构建贴图。 您可以随意缩放该区域,但是在我的示例中,将任何值为-1.0到-0.5的瓷砖设置为水,其余的设置为草(默认的“等距”瓷砖设置也具有鹅卵石和沙子瓷砖,您也可以使用)。 最后,我们将地图添加为SKScene的子级。

摘要

现在,我们已经成功地创建了带有程序生成的地形的图块地图。 接下来的一些步骤是将您自己的图块添加到SKTileSet中,在我们的图块集中double for循环中修改switch语句,和/或使用GKNoiseMap对象。

要查看示例xcode项目,请查看我的github。

还需要成绩簿/成绩计算器,请在App Store上免费下载我的iOS应用Barely Passing。