问题标签 [gameplay-kit]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
151 浏览

ios - 在子类中使用 GKStateMachine 泄漏

我将向您展示我的实际代码。它具有三个元素: Helper:

具有某些游戏状态的助手的子类:

和美国。在这里,我介绍其中之一。另一个具有相同的结构:

问题是当我在 GameSceneHelper 的子类中定义 gameState 变量时出现泄漏。但是,如果我不使用子类,而是让 GameScene 成为 SKScene 的直接子类,那么一切正常。问题是对于我的项目,我需要帮助者,所以我不能把它排除在等式之外。有人有什么建议吗?

0 投票
1 回答
134 浏览

ios - Swift 3.0 在线教程错误键入 [String]

我一般是编程新手。

我决定通过在线教程学习,并一直在关注 Youtube 上的教程,创建了一个类似 (bootleg galaga) 的空间游戏。

我检查了所有内容,但不确定我做错了什么或者是否有 Xcode 更新。我该如何解决这个问题才能完成本教程?

代码:

错误:

“无法将 '(String, String, String)' 类型的值转换为预期的参数类型 '[Any]'

0 投票
2 回答
735 浏览

sprite-kit - GKEntity 是否应该具有访问组件功能的属性或方法?

我正在尝试围绕游戏实体系统并使用 GamePlayKit。我在以下情况下苦苦挣扎:

  • RenderComponent是一个GKComponent引用一个SKSpriteNode来显示我的实体。
  • MetaDataComponent是另一个包含有关实体的各种信息的组件(例如,在我的情况下,这将包含诸如MapX, MapY, ... 之类的属性)

我有一个CharacterEntity源自GKEntity.

为了初始化我的实体,我传递了用于精灵的纹理名称。这允许我创建RenderComponent.

要初始化MetaDataComponent我有三个选项,我想知道其中一个是否被认为是最佳实践(以及,哪一个是最差实践)?

  • 对于我的组件中的每个属性,添加一个参数到init()
  • 在类中公开属性,Character这将更新组件的属性。
  • 将模型对象传递给我的实体并从中初始化组件。

我的想法:

  • 第 1 点:我的实体拥有的组件越多,我得到的参数就越多……这不是我的偏好。
  • 第 2 点:一个实体应该是“愚蠢的”并且不携带任何数据。在最纯粹的形式中,实体只是一个数字。在那里添加道具“感觉”是错误的。
  • 第 3 点:拥有像MetaData我这样的模型对象感觉最好,但也是多余的,因为数据在组件模型对象中。也许让组件存储模型对象而不是其属性?

再举一个例子:如果我希望一个实体有一个RenderComponent,我可以查询那个组件并使用它。或者我可以向实体本身添加一个方法,例如setRenderPosition检查所需组件是否存在并更新它。再次的问题是,这样做是对还是错?

0 投票
1 回答
535 浏览

sprite-kit - GKEntity/组件更新周期最佳实践

主题

我的问题是关于在结合 Apple 的框架时更新周期的划分,以便尊重该主题的典型模式和良好实践,因为大多数文档和示例代码还没有适应 Swift(或者至少我可以)在任何地方都找不到)。

在 GameplayKit 中有很多方法可以管理更新周期,我不太确定什么是组合所有内容的好方法。

要素

首先也是最重要的:实体/组件中的每个类(GKComponentGKEntity(子)类)都有一个update()方法,您可以覆盖该方法以执行每帧更新。这必须来自当前GKScene/的更新周期SKScene

然后GKComponentSystem,您可以使用它来update()从已添加到其中的给定类型中启动每个组件的方法。我明白了,这很方便。

但我也想使用状态机系统,它也有自己的更新周期......结合所有让我感到困惑的东西。

我的情况

在我有一个在初始化时创建GKEntity的实例的子类的情况下。GKStateMachine状态机有几个状态(目前:“Spawn”、“Normal”、“Stunned”和“Death”。

状态循环

现在,我正在用我的子类创建一个大的“千篇一律”,GKEntity并创建它将在初始化期间使用的所有组件。但它变得非常不切实际。例如,我有一个MovementComponent,它是 的子类GKAgent2D。我创建了一个管理实体创建的单例,因此在创建实例后,if 循环遍历所有实体的组件并将它们添加到相关的GKComponentSystems. 单例有一个它自己的 update() 方法,更新将调用传递给GKComponentSystems. 我使用的一些组件不需要逐帧更新,因此没有GKComponentSystem为它们创建任何组件,我根据需要手动更新它们。

如果我回到我的实体,因为我一次创建所有内容并用于GKComponentSystems更新组件,我的组件的更新方法加载了guardif-let语句,因为我需要访问实体的状态机,检查它是否是实体可以移动的状态(正常状态)并做它的事情或逃避功能。这在我看来效率不高:移动组件在生成、眩晕或死亡时不需要更新。

最重要的是,GKStateMachine由于我的更新方法是空的,因此我完全使用了过度杀伤力:GKComponentSystem无论如何,组件都会被更新。

我的想法

  1. 完全GKComponentSystems简单地循环遍历我的所有实体(如果需要,可能在某个时候将它们分类到不同的集合中)并调用它们的update()方法。将更新发送到状态机,状态机将更新该状态中涉及的组件。

  2. 保留GKComponentSystems并使用状态机来处理组件,例如MovementComponent 在进入和退出 Normal 状态时在组件系统中添加和删除 。

选项 1很简单,但从长远来看,当我的结构变得更复杂时可能会导致问题,因为某些组件可能需要先于其他组件更新。让每个实体更新自己的组件会分散更新过程。

选项 2在某种程度上也会让人感到困惑,但我最关心的是组件的创建/删除。我是只将它们从GKComponentSystems实体中取出还是完全从实体中取出?最有效的方法是什么?

实际问题

我的哪个选项是最好的?有没有更好的方法呢。

0 投票
0 回答
92 浏览

ios - 使用 SpriteKit 和 GamePlayKit 与地图区域的约束和碰撞

我正在使用 SpriteKit 和 GamePlayKit 构建一个 2D 游戏,其中单位在地图上移动。我想要实现的一件事是在陆地单元进入地图的特定区域(点 1)时收到通知。第二件事是限制军舰只能在水上行驶。

在此处输入图像描述

所以我最初的想法是让我的地图上的整个土地都成为一个 SpriteNode(我们称之为 A),而有趣的绿色区域则是另一个 SpriteNode。因此,如果我向它们添加physicsBodies,我可以快速检查didBegin是否存在碰撞。但我不确定这将如何与引入它自己的物理的 GPK 实体系统一起工作。有人有这方面的经验吗?我在 Apple 的文档中发现了类似的内容:https ://developer.apple.com/reference/gameplaykit/gkpolygonobstacle

如果您已经在使用带有物理实体的节点来防止精灵进入这些区域,则可以重用这些节点。

所以这似乎是一个可行的选择。

0 投票
1 回答
580 浏览

sprite-kit - 从场景中移除实体 GKComponent

我正在使用 GamePlay kits Entity - 2d 游戏的组件系统。每个实体都有一系列 GKComponents - spriteComponent、physicComponent 等和一个 GKComponent (ChaseScrollMovement.swift),它接收一个 Entities spriteComponent 并将其在屏幕上移动。

将 ChaseScrollMovment 组件添加到 Enemy Enity

问题是当我从 GameScence 中移除 EnemyEnity 时(与 WeaponEnity 接触时):

.... EnemeyEnitiy 从 GameScene 中移除,GameScene 更新方法然后调用 Component 更新方法....

GameScene 中的组件

.....因此,ChaseScroll 组件无法找到 EnemyEntity 的 spriteCompnment,因为它已从场景中移除,并在此处引发异常......

我是 Enity-Compnent 系统的新手,所以我想知道当从场景中删除单个 EnemyEntity(场景中有很多)并允许组件在 GameScene 生命周期中成功更新时,最好的方法是防止异常.

提前致谢

更新:尝试从系统中删除组件,以便在游戏场景更新中不会调用组件 upDate 方法:

//在我们的游戏场景中

但是应该删除的组件仍然调用其更新,在此更新中,实体 spriteComponent 的初始化按预期失败,因为我们已从实体中删除了组件(并试图从系统中删除!):

所以似乎仍然无法从系统中删除组件,因为它的更新仍然被调用或无法从系统中删除实体。

0 投票
1 回答
374 浏览

swift - 如何从 SKScene 中删除实体

可以使用以下方法删除实体的组件:

如何从 SKScene 中删除实体?

有很多关于删除组件的教程,但我找不到任何关于删除实体的明确内容。有没有类似删除节点的东西?

0 投票
1 回答
76 浏览

ios - GKO障碍图不处理归档

我正在使用 GameplayKit 的 GKObstacleGraph 为我的 iOS 10.2 SpriteKit 游戏添加寻路支持。该游戏是一个自上而下的 2D 游戏,它具有我的“士兵”无法通过的不可逾越的障碍。

为我的游戏关卡创建一个包含大约 500 个障碍物的 GKObstacleGraph 大约需要 50 秒。这对我的用户来说太长了等待。

由于游戏地图布局在加载后永远不会动态变化,我决定创建一次图形:

归档到文件:

将文件从设备复制到我的笔记本电脑并将文件添加到我的包中。然后,当我加载我的游戏关卡时,我只是解压缩图形对象:

从理论上讲,这应该快得多,因为我不必计算图形,只需从文件中读取它(取消归档)。

但是,根据障碍物的数量及其相对位置,会发生以下三种情况之一:

  1. NSKeyedArchiver.archiveRootObject 崩溃。
  2. 存档工作,但 NSKeyedUnarchiver.unarchiveObject 崩溃。
  3. 存档和取消存档都有效,但我无法使用 GKObstacleGraph.findPath 找到绕过障碍物的路径

如果我跳过(取消)归档步骤,我可以完成所有这些工作:

成功寻路

此外,在模拟器 (iPhone 7) 上, (un)archive永远不会崩溃,但之后寻路总是失败

这里发生了什么?我已将其作为错误报告给 Apple,但我仍然希望我错过了一些东西。

我尝试了替代解决方案来解决我使用自己的格式写入/读取节点和文件障碍的问题。但是 GKObstacleGraph 的障碍属性是get only,这让我有了构造函数,然后我又回到等待 50 秒。

我创建了一个公共测试项目 git repo:

https://bitbucket.org/oixx/gkobstaclegraphcrashproof.git

它显示了在设备上运行时失败的三种不同场景。为简单起见,它将文件读/写到设备,而不是捆绑。

0 投票
1 回答
1232 浏览

ios - (Apple) 使用 SKScene 实现 GameplayKit 状态机

我已经阅读了 GameplayKit 状态机,并且文档 明确提到了游戏 UI 作为使用示例。我完全理解这个概念,但我不确定如何在使用 SpriteKit 时实现它。

可以说我想要 3 个状态。菜单、游戏玩法和游戏结束 - 所有这些都向 SKScene 显示内容。GameScene 类扩展了 SKScene。所以不可能把 GameScene 变成一个状态机,因为我们只能扩展一个类。

GameScene 是否应该有一个引用 SKScene 的状态机变量,还是有更好的解决方案?早些时候我使用了状态机协议,这很容易,但我想尝试一下 GameplayKit 的功能。

0 投票
3 回答
602 浏览

ios - Xcode 错误:语义问题,在对象类型“GKEntity *”上找不到属性“className”

最近我开始从 Xcode 收到这个错误:

错误截图

这个 'className' 属性属于 NSObject。这是官方文档。

为什么会发生这种情况,我该如何解决(不避免使用此属性)


奇怪的是,几天前完全相同的代码在 macOS 和 iOS 目标上都运行良好。然后它在构建成功完成后开始显示此错误(我可以很好地运行该项目),但现在 iOS 目标甚至不会构建......

我尝试(1)多次清除我的derivedData文件夹,(4)进行干净的结帐,(3)重新启动Xcode,(2)重新启动系统,所有这些都以正确的顺序进行,但没有成功......

我在macOS 10.12.3上使用Xcode 版本 8.2.1,我的部署目标是 iOS 10.2 和 macOS 10.12。