iOS9 每日学习第12天:GameplayKit 之 Behaviors 和 Goals

490 查看

在上一篇我们学习了利用 GameplayKit的 pathfinding API 来计算位于场景中的两点之间的路径,并避开指定的障碍物的算法。

在这一篇中,让我们来实现一种不同的在场景中移动的效果。GameplayKit 介绍了 Behaviours(行为) 和 Goals(目标) 的概念.他们提供了一种方式,让你能够依赖约束和目标把节点的放置在场景中某个特定位置。让我们先看一下视频,然后再来详细看一下。

上面的例子中(我们马上要创建它),你可以看到一个黄色的盒子代表一个用户。黄色的盒子随着用户点击场景中的任意一处来移动。特别基本的东西,对吧。有趣的是导弹部分,它能够寻找到player,并且总是试图通过player节点的中心。

这不需要任何的物理或者自定义代码来完成,这完全有一个行为可寻址目标来控制。

现在,让我们通过 Demo了解一下 behaviours 和 goals 是怎么工作的。

Creating a Behavior and Goal Example

使用默认的 SpriteKit 模版创建项目,打开 GameScene.swift

setup1.png

首先,我们定义一个实例

GKEntity 是一个通用的实体,可以给它添加组件和方法。在我们的例子中,我们有两个实例,一个代表 player,一个代表导弹。我们马上来看一下它的细节实现。

我们还需要创建一个组件系统的数组。这个组件系统是指符合同样类型的组件的一个集合。我们可以在需要时候的时候,再定义它(lazy var),因为我们仅需初始化它一次。我们有一个组件作为靶子(可以用来追踪player的位置,并添加冒烟的效果),另一个作为导弹。我们定义的顺序,会成为一会儿运动的顺序。所以我们先返回targeting 然后是 rendering. 因为我们希望根据目标的变化,来追踪显示他们的。

但什么才是一个 GameKit 组件呢?我们已经讨论了在场景中的实体的效果,但没讲具体做了什么。一个 GKComponent 在特定部分,囊括了数据和逻辑。组件和实体联系,一个实体可能对应多个组件。它们为组件提供可重用的行为。它们通过组件模型,来帮助解决大型游戏中可能出现的复杂而大型的继承树问题。

在这个场景中,两个实体都有渲染组件,导弹实体还有靶子组件。

设置实体

The Player Entity

下面代码是 player 类,它是一个简单的几成字 NodeEntity的类,拥有唯一一个组件。注意还有一个 GKAgent2D 的属性.

GKAgent2D 是 GKAgent的一个子类, 呈现为一个根据速度定位的本地坐标系统。

在本例中,代理其实是无言的。如果不是用户手动干预,它不会做任何事情,也不会对位置进行任何变化。我们需要一个代理,因为靶子组件必须有一个代理。

在初始化中,我们添加一个 RenderComponent 和一个PlayerNode. 我们不详细讲 PlayerNode 了,因为非常枯燥。这里我们仅简单画一个黄色的方盒。

我们把代理设为自己,通过把代理添加到实体上去。

我们还需要去生命 GKAgentDelegate 的代理方法。这样,当代理更新后,Node 的位置会自动更新,同时,当用户手动更新了位置后,代理也会通过计算更新位置。

The Missile Entity

missile 实体和 PlayerNode 略有不同。我们添加一个目标代理,让导弹去追踪。