I'm working to implement a Zig Zag game and following a set of instructions from an on-line course. I have a swift UIViewController, and I am trying now to use also SCNSceneRenderer (to do the game logic of keeping the game character on the zig-zag path). The code looks like this:
import UIKit
import QuartzCore
import SceneKit
class GameViewController: UIViewController, SCNSceneRenderer{
let scene = SCNScene()
let cameraNode = SCNNode()
var person = SCNNode()
let firstBox = SCNNode()
var goingLeft = Bool()
var tempBox = SCNNode()
var boxNumber = Int()
var prevBoxNumber = Int()
override func viewDidLoad() {
print("Yes -- view did load")
self.createScene()
}
func renderer(render: SCNSceneRenderer, updateAtTime time: TimeInterval){
let deleteBox = self.scene.rootNode.childNode(withName: "\(prevBoxNumber)", recursively: true )
if (deleteBox?.position.x)! > (person.position.x + 1) || (deleteBox?.position.z)! > (person.position.z + 1) {
prevBoxNumber += 1
deleteBox?.removeFromParentNode()
createBox()
}
}
func createBox(){
tempBox = SCNNode(geometry: firstBox.geometry)
let prevBox = scene.rootNode.childNode(withName: "\(boxNumber)", recursively: true )
boxNumber += 1
tempBox.name = "\(boxNumber)"
let randomNumber = arc4random() % 2
switch randomNumber {
case 0:
tempBox.position = SCNVector3Make((prevBox?.position.x)! - firstBox.scale.x, (prevBox?.position.y)!, (prevBox?.position.z)!)
break
case 1:
tempBox.position = SCNVector3Make((prevBox?.position.x)! , (prevBox?.position.y)!, (prevBox?.position.z)! - firstBox.scale.z)
break
default:
break
}
self.scene.rootNode.addChildNode(tempBox)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if goingLeft == false {
person.removeAllActions()
person.runAction(SCNAction.repeatForever(SCNAction.move(by: SCNVector3Make(-100, 0, 0), duration: 20)))
goingLeft = true
} else {
person.removeAllActions()
person.runAction(SCNAction.repeatForever(SCNAction.move(by: SCNVector3Make(0, 0, -100), duration: 20)))
goingLeft = false
}
print("boxNumber is \(boxNumber)")
}
func createScene(){
boxNumber = 0
prevBoxNumber = 0
self.view.backgroundColor = UIColor.orange
let sceneView = self.view as! SCNView
sceneView.delegate = self
sceneView.scene = scene
//Create Person
let personGeo = SCNSphere(radius: 0.2)
person = SCNNode (geometry : personGeo)
let personMat = SCNMaterial()
personMat.diffuse.contents = UIColor.red
personGeo.materials = [personMat]
person.position = SCNVector3Make(0, 1.1, 0)
scene.rootNode.addChildNode(person)
//Create Camera
cameraNode.camera = SCNCamera()
cameraNode.camera?.usesOrthographicProjection = true
cameraNode.camera?.orthographicScale = 3
cameraNode.position = SCNVector3Make(20,20,20)
cameraNode.eulerAngles = SCNVector3Make(-45,45,0)
//let constraint = SCNLookAtConstraint(target: firstBox)
let constraint = SCNLookAtConstraint(target: person)
constraint.isGimbalLockEnabled = true
self.cameraNode.constraints = [constraint]
scene.rootNode.addChildNode(cameraNode)
person.addChildNode(cameraNode)
//Create Box
let firstBoxGeo = SCNBox(width: 1.0, height: 1.5, length: 1.0, chamferRadius: 0)
firstBox.geometry = firstBoxGeo
let boxMaterial = SCNMaterial()
boxMaterial.diffuse.contents = UIColor(red: 0.2, green: 0.8, blue: 0.9, alpha: 1.0)
firstBoxGeo.materials = [boxMaterial]
firstBox.position = SCNVector3Make(0,0,0)
scene.rootNode.addChildNode(firstBox)
firstBox.name = "\(boxNumber)"
for _ in 0...6{
createBox()
}
//Create light
let light = SCNNode()
light.light = SCNLight()
light.light?.type = SCNLight.LightType.directional
light.eulerAngles = SCNVector3Make(-45, 45, 0)
scene.rootNode.addChildNode(light)
//Create light2
let light2 = SCNNode()
light2.light = SCNLight()
light2.light?.type = SCNLight.LightType.directional
light2.eulerAngles = SCNVector3Make(45, 45, 0)
scene.rootNode.addChildNode(light2)
}
}
When I added SCNSceneRenderer I get the following error:
"Type 'GameViewController' cannot conform to protocol 'SCNSceneRenderer' because it has requirements that cannot be satisfied"
Since my GameViewController isn't recognized as a SCNSceneRenderer, I also get an error at this line:
sceneView.delegate = self
the error is "Cannot assign value of type 'GameViewController' to type 'SCNSceneRendererDelegate'
I'm new to swift programming, but this seems like I am trying to implement an interface like in Java, I've been looking at the Swift documentation but don't see what I need to do to make my class be functional as an SCNSceneRenderer. I would appreciate help to solve this problem. Thanks!