SceneKit一个3D场景角色的代码重构
2024-08-26 08:52:52
SuperSpaceMan3D是一个以SceneKit为基础的小游戏项目,作者展示了用SceneKit开发3D游戏的强大威力.不过在实际运行时会发现有一些小bug,这里我们依次尝试将其修复
首先,当spaceman接触到敌人的时候,游戏结束,弹出GameOver视图,然后当玩家再触摸屏幕时,开始新的游戏.在实际游戏中发现,spaceman接触敌人后GameOver视图很快闪过,游戏随即重新开始,不能达到等待用户触摸再开始的目的.
分析发现didBeginContact代码逻辑缺少区分条件,在GameViewController类中添加类级属性:
static var isGameOverViewShowing = false
之所以添加static属性是因为需要在GameView中修改该属性,当然这是一种比较差的重构,应该make一个实例变量.
在spaceman接触敌人的代码逻辑中添加如下代码:
GameViewController.isGameOverViewShowing = true
gameStarted = false
在didSimulatePhysicsAtTime方法的第一个判断条件中加上isGameOverShowing这个条件:
if sceneView.touchCount > 0 && !gameStarted && !GameViewController.isGameOverViewShowing{
}
进入GameView.swift中,在touchesBegan方法中添加以下一行:
if GameViewController.isGameOverViewShowing{
GameViewController.isGameOverViewShowing = false
}
这里是关键的一句,重新触发了游戏!
运行游戏,此时发现虽然大多数情况下逻辑正常,但是当多次连续点击屏幕时会发生spaceman重置位置不正确的情况.
进入setupSpaceMan方法,发现spaceManNode的物理对象类型是动态类型,但此游戏中spaceman位置全部都是通过代码手工调整,这里应该将其设置为Static类型,于是修改代码如下:
spaceManNode!.physicsBody = SCNPhysicsBody(type: .Static, shape: nil)
同时修改resetSpaceman方法为如下内容:
func resetSpaceman(){
spaceMan.removeAllActions()
spaceMan.position = SCNVector3(x: 0, y: 0, z: 200)
spaceMan.rotation = SCNVector4(x: 0, y: 1, z: 0, w: Float(M_PI))
}
再次运行游戏,这次基本达到了预期的效果(图片过大需要加载时间):
最新文章
- EBS中加载FORM使用的JavaBean的JAR包
- mac下限速
- 在Spring4中使用通用Mapper
- backbonejs中的集合篇(一)
- 判断一个面(Polygon)是不是矩形
- iOS自学之NSOperation、NSOperationQueue、Background
- MyEclipse2015 javaweb项目从svn检出后变成java项目,clean之后不能编译,解决办法是
- Objective-C中整数与字符串的相互转换
- CROS+node-basis+ajax
- python模块--zipfile文件压缩
- spring boot maven打包可运行jar包
- js call 理解
- Oracle Grid Infrastructure Installation Guide for Linux 以debug模式安装并记录日志
- Spanning Tree Protocol (STP) in NetScaler Appliance
- 聊聊JVM的年轻代(转)
- (转)高并发Web服务的演变——节约系统内存和CPU
- THINKPHP简单商品查询项目
- 设置tomcat配置文件,在Myeclipse中修改jsp文件之后不用重启tomcat
- python调用dll
- org/apache/hadoop/hbase/mapreduce/TableReducer:Unsupported major.minor version52.0