Sul*_*vus 6 architecture game-engine scenekit
我正在尝试为SceneKit iOS游戏设计一个架构.我已经在下面展示了我目前偏好的两个粗略 的高级对象图/图表.
我目前只关注高级架构,即管理Menu/GameLevel/Config/Paused应用状态之间的转换,并使应用程序数据驱动,以便它可以处理多个级别等.一旦我开始工作,然后我将解决较低级别的体系结构,例如对于GameLevel状态,我将有一个GameLevelModel对象来表示实际的游戏级别逻辑.
很高兴听到哪一个看起来更有前途,任何明显的陷阱或要避免的事情?
我试图与这个版本保持接近MVC范式.
应用程序的行为在其不同状态(Menu/GameLevel/Config/etc)之间发生显着变化,因此我将使用永久容器视图控制器,该控制器将根据Apple的父子关系在多个嵌套的VC之间进行管理/转换"适用于iOS的View Controller编程指南".这些将是有效的整个MVC.
因为Apple的容器控制器(UINavigation-,UISplitScreen-,UITabBar-)都不合适(我需要整个屏幕),所以我将拥有一个自定义容器VC(RootViewController),它将始终具有一个嵌套子VC.每个孩子VC的视图将始终完全覆盖容器的一个.子VC之间的转换将由RootVC管理并由其StateMachine驱动.
每次子VC(实际上是整个MVC)在每次相应的状态变为当前状态时被创建,然后在被替换为下一状态且不再需要时被解除分配.类似于UINavigationController如何处理它包含的VC.
我唯一担心的是这种架构看起来有点沉重.SceneKit看起来像是设计用于单个 SCNView,并在我们需要更改3D内容时在多个SCNScenes之间进行转换.这也提供了更多的过渡选项.
--------------------------
| 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 |
------------------ ------------------
Run Code Online (Sandbox Code Playgroud)
我将只有一个View Controller(GameViewController)及其View(SCNView),它们将持续整个应用程序生命周期.(我这里不会有容器和嵌套的VC.)
应用状态(Menu/GameLevel/Config/etc)之间的行为和内容的变化是通过场景和不同的TouchHandler(每个州的UIResponder子类)之间的唯一View转换实现的,在相关时给予First Responder状态.
(Menu-,GameLevel-等)TouchHandler类只会覆盖touchesBegan/Moved/Ended,canBecomeFirstResponder因此我可以拦截触摸事件而不会使单个控制器和视图膨胀.我的其他任何对象都不是UIResponders.我还没有测试过这个部分.
对于每个app状态,将创建该状态所需的对象,如相应的Scene,TouchHandler,(GameLevelState中具有游戏级别逻辑的GameLevelModel)等,并在输入下一个状态时取消分配.
我目前的问题是,当使用SKTransition在单个SCNView上的多个SCNScenes之间进行转换时,在5-20个转换之后会出现内存泄漏.我尝试通过简化场景解决,在解除分配之前删除所有操作,节点但没有任何帮助.避免泄漏的唯一方法是避免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 |---------
------------------
Run Code Online (Sandbox Code Playgroud)
提前致谢.
我将解释一个我正在研究的真实游戏设计,它基于Apple为SceneKit提供的示例代码的设计.
正如@HalMuelller正确指出的那样,你需要将游戏逻辑提取到一个独立于平台的层,即使你正在为一个平台编写游戏,这也是一个好主意,因为它可以帮助你进行测试.
正如您在上面的类图中看到的:
在右侧是整个游戏逻辑,从一个Game实际上作为场景和物理代表的类开始.这只是一个普通的老ObjC或Swift类.
Game该类的主要职责之一是SCNScene根据SceneKit/Model IO支持的文件或根据具体情况以编程方式构建场景.
该Game班还引用其他Model类,如Animation它加载3D骨骼动画和Player类,它包含了玩家数据,如他的统计,Player在这里指的是一些玩家喜欢在游戏中的棒球运动员.
您还可以看到有一个PlayerEntity由哪个类组成BatterComponent,这是基于Entity-Component设计的GamePlayKit.现在BatterComponent有一个StateMachine处理面糊在各种状态之间转换的a.
另一个重要组件是BatterControlComponent仅在用户进行击球时才添加到实体中.这也是一个依赖于平台的组件,因此您可以在macOs/iOS目标中独立编写它.同样,电池控制组件由状态机支持,因为状态机也可用于处理控制转换.此控件实现为SpriteKit场景作为叠加在顶部SCNScene.
如果您正在投球,那么您可以使用PitcherComponent其他状态机支持配置播放器实体,依此类推.
在类图的左侧,您可以看到坐下GameViewController来设置一个SCNView并且还实例化一个Game对象,这个游戏对象的场景是您的游戏视图控制器场景视图呈现的内容.您还可以确保将场景视图委托设置为游戏对象.
您必须认真参考SceneKit的Apple示例代码和GameKit的示例.在Apple开发人员的示例代码部分中搜索:SceneKit和GameplayKit.
总的来说,您必须使用普通的Swift/ObjC类以及GamePlayKit基于您的游戏要求的相应模式来设计独立于平台的游戏逻辑层.
关于生产用途的说明.看到这个内存泄漏问题和动画问题,所以我不确定SceneKit是否已准备好迎接黄金时段,但谷歌是你的朋友.话虽如此,如果您已经在Apple平台上工作,SceneKit真的很棒,所以如果您没有使用任何游戏引擎并且将游戏作为业余爱好或者学习游戏,那么学习新游戏引擎的周转时间会更短节目.我相信SceneKit每年都在不断改进,在接下来的两个版本(WWDC 17,18)中,它应该是苹果平台真正优秀的游戏引擎.根据我的经验,这些是我的2美元,YMMV.