gpt4 book ai didi

architecture - SceneKit 游戏架构

转载 作者:行者123 更新时间:2023-12-03 17:07:34 33 4
gpt4 key购买 nike

我正在尝试为 SceneKit iOS 游戏设计架构。我在下面展示了两个粗略的高层我当前首选想法的对象图/图表。

我目前只关注高级架构,即管理 Menu/GameLevel/Config/Paused 应用程序状态之间的转换并使应用程序数据驱动,以便它可以处理多个级别等。一旦我开始工作,然后我将讨论较低级别的架构,例如对于 GameLevel 状态,我将有一个 GameLevelModel 对象来表示实际的游戏关卡逻辑。

很高兴听到哪个看起来更有希望,有什么明显的陷阱或要避免的事情吗?

版本 A) 基于 MVC,带有自定义容器和嵌套 VC

我试图在这个版本中保持接近 MVC 范式。

应用程序的行为在其不同状态(菜单/游戏级别/配置/等)之间发生显着变化,因此我将使用永久容器 View Controller ,该 Controller 将管理/转换多个嵌套 VC,按照 Apple 的父子关系“查看 iOS Controller 编程指南”。这些实际上是整个 MVC。

因为 Apple 的容器 Controller (UINavigation-、UISplitScreen-、UITabBar-)都不适合(我需要整个屏幕),所以我将拥有一个自定义容器 VC (RootViewController),它始终有一个嵌套的子 VC。每个子 VC 的 View 将始终完全覆盖容器的 View 。子 VC 之间的转换将由 RootVC 管理并由其 StateMachine 驱动。

每个子 VC(实际上是整个 MVC)在其对应的状态变为当前状态时创建,然后在被下一个状态替换且不再需要时释放。类似于 UINavigationController 如何处理它包含的 VC。

我对这种架构的唯一担心是它看起来有点沉重。 SceneKit 看起来像是设计用于 SCNView 并在我们需要更改 3D 内容时在多个 SCNScene 之间进行转换。这也提供了更多的过渡选项。

                         --------------------------
| RootViewController |
--------------------------
| | | | |
------------------ | | | | | ------------------
| GameLevelsData |----- | | | -------| SCNView |
------------------ | | | ------------------
------------------ | | |
| PlayerData |-------- | |
------------------ | |
| |
---------------- |
| StateMachine | |
---------------- |
| |
|-(*MenuState) |
|-(LevelState) |
|-(ConfigState) |
|
|
------------------------
| MenuViewController |
------------------------
----------------- | | ------------------
| MenuData |------ -------| MenuSCNView |
----------------- ------------------

(child VCs for other States, Level-/Config-/etc are created as needed)
|
------------------------
| LevelViewController |
------------------------
------------------ | | ------------------
| GameLevelModel |------ -------| LevelSCNView |
------------------ ------------------

版本 B) 基于场景(一个 VC,多个场景)

我将只有一个 View Controller (GameViewController) 及其 View (SCNView),它们将持续整个应用程序生命周期。
(我将 而不是 在这里有容器和嵌套的 VC。)

应用程序状态(Menu/GameLevel/Config/etc)之间的行为和内容的变化是通过场景和不同 TouchHandlers(每个状态的 UIResponder 子类)之间的唯一 View 转换来实现的,在相关时给予 First Responder 状态。

(Menu-、GameLevel- 等)TouchHandler 类只会覆盖 touchesBegan/Moved/EndedcanBecomeFirstResponder这样我就可以拦截触摸事件而不会使单个 Controller 和 View 膨胀。我的其他对象都不是 UIResponder。我还没有完全测试过这部分。

对于每个应用程序状态,将创建该状态所需的对象,例如相应的 Scene、TouchHandler、(在 GameLevelState 中具有游戏级别逻辑的 GameLevelModel)等,并在进入下一个状态时释放。

我目前的问题是,当使用 SKTransition 在单个 SCNView 上的多个 SCNScene 之间转换时,在 5-20 次转换后会出现内存泄漏。我尝试通过简化场景、在解除分配之前删除所有 Action 、节点来解决,但没有任何帮助。避免泄漏的唯一方法是避免 SKTransition 并直接将场景分配给 View 的场景属性 scnView.scene = scnScene .所以这将需要我为自己的过渡设置动画。
                         --------------------------
| GameViewController |
--------------------------
| | | |
------------------ | | | | ------------------
| GameLevelsData |----- | | -------| SCNView |
------------------ | | ------------------
------------------ | | |
| PlayerData |-------- | |
------------------ | |
| |
---------------- |
| StateMachine | |
---------------- |
| ------------------
|-(*MenuState)--------- | MenuSCNScene |
|-(LevelState) | | ------------------
|-(ConfigState) | |
| |
-------------------- | |
| MenuTouchHandler |---| |
-------------------- |
----------------- |
| MenuData |---------
-----------------

(When entering, each state creates objects of corresponding
dedicated subclasses for its Model, TouchHandler and Scene)
| | |
-------------------- | | -------------------
| LevelTouchHandler |---| | | LevelSCNScene |
-------------------- | -------------------
------------------ |
| GameLevelModel |---------
------------------

提前致谢。

最佳答案

我将根据 Apple 为 SceneKit 提供的示例代码的设计来解释我实际正在从事的真实游戏设计。

正如@HalMuelller 正确指出的那样,您需要将游戏逻辑提取到独立于平台的层中,即使您正在为一个平台编写游戏,这也是一个好主意,因为这将有助于您进行测试。

enter image description here

正如您在上面的类图中所见:

右侧是从 Game 开始的整个游戏逻辑。实际上作为场景和物理代理工作的类。这只是一个普通的旧 ObjC 或 Swift 类。
Game 的主要职责之一类是搭建场景SCNScene来自 SceneKit/Model IO 支持的文件或根据您的情况以编程方式。
Game类也指其他Model类如 Animation加载 3D 骨骼动画和 Player包含球员数据的类,例如他的统计数据,Player在这里指的是一些像棒球运动员一样的球员在比赛中。

还可以看到有PlayerEntityBatterComponent 组成的类,这是基于 GamePlayKit 中的实体组件设计.现在BatterComponent有一个 StateMachine它处理击球手在各种状态之间的转换。

另一个重要组成部分是 BatterControlComponent只有在用户击球时才添加到实体中。这也是一个依赖于平台的组件,因此您可以在 macOS/iOS 目标中独立编写它。同样,连击控制组件由状态机支持,因为状态机也可用于处理控制转换。此控件实现为 SpriteKit场景作为 SCNScene 顶部的叠加层.

如果您正在投球,那么您可以使用 PitcherComponent 配置玩家实体。由另一个状态机支持,依此类推。

在类图的左侧,您可以看到 GameViewController它设置了 SCNView并实例化一个 Game对象和此游戏对象的场景是您的游戏 View Controller 场景 View 呈现的内容。您还确保将场景 View 委托(delegate)设置为游戏对象。

您必须认真引用 Apple 的 SceneKit 示例代码和 GameKit 的示例。在 Apple 开发人员中,示例代码部分搜索:SceneKitGameplayKit .

总的来说,您必须使用普通的旧 Swift/ObjC 类和来自 GamePlayKit 的适当模式来设计一个独立于平台的游戏逻辑层。根据您的游戏要求。

关于生产使用的说明。见 this memory leak issueanimation issues ,所以我不确定 SceneKit 是否已经准备好迎接黄金时段,但 Google 是你的 friend 。话虽如此,如果您已经在Apple平台上工作,SceneKit真的很棒编程。我相信 SceneKit 每年都在改进,在接下来的 2 个版本(WWDC 17、18)中,它应该是一个非常适合 Apple 平台的游戏引擎。根据我的经验,这些是我的 2 美元,YMMV。

关于architecture - SceneKit 游戏架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43081988/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com