小斑swift小技巧 iOS SceneKit 开发

SceneKit 相关

2016-04-07  本文已影响3364人  童冀

SceneKit

SCNNode 结构图

SCNNode 1.png
SCNNode 2.png

通过两张图片,更好地了解SCNNode的结构

一个渲染循环

渲染循环内做的事


Render Cycle.png

SCNGeometry 的内建对象

内建对象1.jpg 内建对象2.jpg 内建对象3.jpg

.dae 文件全称Data Asset Exchange,是Collada 的输出文件

Collada file specifies.jpg

上帝说有光,于是SCNLight亮了

四种光照效果
1.jpg
2.jpg
光照的规则
光照规则.jpg
亮起来
func setupLighting(scene:SCNScene) {
        
        let ambientLight = SCNNode()
        ambientLight.light = SCNLight()
        ambientLight.light!.type = SCNLightTypeAmbient
        ambientLight.light!.color = UIColor(white: 0.3, alpha: 1.0)
        scene.rootNode.addChildNode(ambientLight)
        
        let lightNode = SCNNode()
        lightNode.light = SCNLight()
        lightNode.light!.type = SCNLightTypeSpot
        lightNode.light!.castsShadow = true
        lightNode.light!.color = UIColor(white: 0.8, alpha: 1.0)
        lightNode.position = SCNVector3Make(0, 80, 30)
        lightNode.rotation = SCNVector4Make(1, 0, 0, Float(-M_PI/2.8))
        lightNode.light!.spotInnerAngle = 0
        lightNode.light!.spotOuterAngle = 50
        lightNode.light!.shadowColor = UIColor.blackColor()
        lightNode.light!.zFar = 500
        lightNode.light!.zNear = 50
        scene.rootNode.addChildNode(lightNode)
        
        //Save for later
        spotLight = lightNode
    }

老板,你是土豪金的么SCNMaterial

八种不同的材质
蓝色贴图
pyramidNode.geometry?.firstMaterial?.diffuse.contents = UIColor.blueColor()
pyramidNode.geometry?.firstMaterial?.specular.contents = UIColor.blueColor()
pyramidNode.geometry?.firstMaterial?.shininess = 1.0
地球贴图
globeNode.geometry?.firstMaterial?.diffuse.contents = UIImage(named: "earthDiffuse")
globeNode.geometry?.firstMaterial?.ambient.contents = UIImage(named: "earthAmbient")
globeNode.geometry?.firstMaterial?.specular.contents = UIImage(named: "earthSpecular")
globeNode.geometry?.firstMaterial?.normal.contents = UIImage(named: "earthNormal")
globeNode.geometry?.firstMaterial?.diffuse.mipFilter = SCNFilterMode.Linear

相机走起 -- SCNCamera

添加一个cameraNode

cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.camera!.zFar = 500
cameraNode.position = SCNVector3Make(0, 30, 200)
cameraNode.rotation  = SCNVector4Make(1, 0, 0, Float(-M_PI_4*0.75))
scene.rootNode.addChildNode(cameraNode)
SCNCamera.jpg

添加动画

用CoreAnimation就好啦

直接上代码,绕y轴旋转

// Spin around the Y-Axis
rotation.fromValue = NSValue(SCNVector4:SCNVector4Make(0, 0, 0, 0))
rotation.toValue =  NSValue(SCNVector4:SCNVector4Make(0, 1, 0, Float(2.0*M_PI)))
rotation.duration = 5
rotation.repeatCount = .infinity
pyramidNode.addAnimation(rotation, forKey: "rotation")```
#####添加SCNAction 实现动画
实现上下跳动
```swift
//上下跳动
let moveGlobeUp = SCNAction.moveByX(0.0, y: 10.0, z: 0.0, duration: 1.0)
let moveGlobeDown = SCNAction.moveByX(0.0, y: -10.0, z: 0.0, duration: 1.0)
let sequence = SCNAction.sequence([moveGlobeUp, moveGlobeDown])
let repeateSequence = SCNAction.repeatActionForever(sequence)
globeNode.runAction(repeateSequence)

放大缩小

let scaleToZero = SCNAction.scaleTo(0.0, duration: 0)
let scaleUp = SCNAction.scaleTo(1.0, duration: 5)
let opacityToZero = SCNAction.fadeOutWithDuration(5)
let sequence = SCNAction.sequence([scaleToZero, scaleUp, opacityToZero])
let repeateSequence = SCNAction.repeatAction(sequence, count: 10)
cylinderNode.runAction(repeateSequence)

动起来

镜头动作

让镜头跟着移动

//follow the camera
let spaceman =  spaceManNode.presentationNode
let spacemanPosition = spaceman.position
let cameraDamping:Float = 0.05
let targetPosition =  SCNVector3Make(spacemanPosition.x, 30.0, spacemanPositio
var cameraPosition =  cameraNode.position
cameraPosition = SCNVector3Make(cameraPosition.x * (1.0 - cameraDamping) + tar
* cameraDamping,
    cameraPosition.y * (1.0 - cameraDamping) + targetPosition.y * cameraDampin
    cameraPosition.z * (1.0 - cameraDamping) + targetPosition.z * cameraDampin
cameraNode.position = cameraPosition
添加.dae 文件到scene
func setupEnemy(scene:SCNScene) -> SCNNode {
    
    let enemyScene = SCNScene(named: "art.scnassets/Enemy.dae")
    let enemyNode = enemyScene!.rootNode.childNodeWithName("enemy", recursively: false)
    enemyNode!.name = "enemy"
    enemyNode!.position = SCNVector3Make(40, 10, 30)
    enemyNode!.rotation = SCNVector4Make(0, 1, 0, Float(M_PI))
    scene.rootNode.addChildNode(enemyNode!)
    
    return enemyNode!
}
碰撞检测SCNPhysicsBody

三种碰撞体

三种碰撞体.jpg

在SceneKit 里面使用SpriteKit

绘制2d效果

import SpriteKit
import SceneKit
class GameOverlay: SKScene {
    required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

碰撞这一块实现的不是很好,暂时先不研究了


以上代码图像来自:Beginning Swift Games Development for iOS 一书,没搜到中文翻译版,建议做3D开发的童鞋自行下载此书,查词典看完(本书提供的source code 不太全,得配合着书进行完善)


Scenekit内容很丰富,后续应该还会继续补充...
待续...

上一篇下一篇

猜你喜欢

热点阅读