我正在尝试为一个SceneKit iOS游戏设计架构。下面展示了两个我目前首选的想法的草图,它们是当前高层次对象图。
目前我只关注高层次架构,即管理菜单/游戏等级/配置/暂停应用程序状态之间的转换,并使应用程序数据驱动,以便它可以处理多个等级等。一旦我完成这个,然后我将解决更低层次的架构,例如对于GameLevel状态,我将有一个GameLevelModel对象来表示实际的游戏等级逻辑。
很高兴听到哪个看起来更有前途,有什么明显的缺陷或需要避免的事情?
版本A)基于MVC,带自定义容器和嵌套视图控制器
我试图在此版本中保持接近MVC范例的模式。
应用程序在不同状态(菜单/游戏等级/配置等)之间的行为发生了显着变化,因此我将使用一个永久容器视图控制器,它将管理/转换几个嵌套的视图控制器,在父子关系中,如苹果的“iOS视图控制器编程指南”所述。这些将是完整的MVC。
由于苹果的任何容器控制器(UINavigation-, UISplitScreen-, UITabBar-)都不适用(我需要整个屏幕),因此我将有一个自定义的容器VC(RootViewController),它将始终具有一个嵌套的子VC。每个子VC的View将始终完全覆盖容器的View。子VC之间的转换将由RootVC管理,并由其状态机驱动。
每个子VC(实际上是完整的MVC)在其对应状态成为当前状态时创建,然后在它被下一个状态的VC替换并且不再需要时被解除分配。类似于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,多个场景)
我将只有一个视图控制器(GameViewController),它带有它的视图(SCNView),并且它们将持续整个应用程序的生命周期。 (这里不会有容器和嵌套的VC。)
在应用程序状态之间的行为和内容变化(菜单/游戏级别/配置等)是通过唯一的视图在场景和不同的TouchHandlers之间过渡实现的(每个状态的UIResponder子类)在相关时给予第一响应者状态。
(菜单,游戏级别等)TouchHandler类将仅覆盖touchesBegan/Moved/Ended
和canBecomeFirstResponder
,以便我可以拦截触摸事件而不会使单个控制器和视图膨胀。我的其他对象都不是UIResponders。我还没有测试这部分。
随着每个应用程序状态,将创建该状态所需的对象,例如相应的场景、TouchHandler、(当处于GameLevelState时具有游戏级别逻辑的GameLevelModel)等,并在进入下一个状态时进行解除分配。
我目前遇到的问题是,在使用SKTransition在单个SCNView上转换多个SCNScene时,经过5-20次转换后会出现内存泄漏。我尝试通过简化场景、在解除分配之前删除所有操作和节点来解决,但没有任何帮助。避免泄漏的唯一方法是避免使用SKTransition,并直接将场景分配给视图的场景属性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 |---------
------------------
感谢您提前阅读。