打开应用程序时,SCNView需要两秒钟来显示场景

时间:2015-06-05 12:48:07

标签: ios swift init scenekit viewdidload

我正在SceneKit制作一款即将完成的3D游戏。该应用程序包含一个视图,其中包含一个SCNView和两个带按钮的小视图。

我发现当我启动游戏时,在启动画面消失后大约需要两到三秒才能在SCNView中显示场景。我在同一时间看到一个带有按钮的白色屏幕。我从COLLADA文件中将主场景加载到SCNView中,并从另一个Collade文件中添加两个节点。我还以编程方式添加一些节点并将物理添加到某些节点。所有这些都发生在我的viewDidLoad方法中。

我使用的代码:

@IBOutlet var scnView: SCNView!
@IBOutlet var soundButton: UIButton!
@IBOutlet var statsButton: UIButton!

var radAngle:Float = 0.0                        // Angle of number
var maxAngle:Float = (120)/180 * Float(M_PI)    // Angle of open numbers (up)

let dice1: SCNNode                              // die 1
let dice2: SCNNode                              // die 2
let leftCameraNode:SCNNode                      // Camera for rules
let rightCameraNode:SCNNode                     // Camera for box
let scoreCameraNode = SCNNode()                 // Camera for the statistics
var gameEndedNode: SCNNode = SCNNode()          // Node when game ended game

var dices:[SCNNode]                             // The two dice nodes
var dicePreviousTotal:Int = 0                   // thrown number (total)
var diceCurrentTotal:Int = 0                    // compare with previous

var numberNames:[String] = ["numberBlock_1", "numberBlock_2", "numberBlock_3", "numberBlock_4", "numberBlock_5", "numberBlock_6", "numberBlock_7", "numberBlock_8", "numberBlock_9"]           // Names of all NumberBlocks
var numbersUp:[Int] = []                        // Indicate for every numbers if it is up (open)
var numbersRound:[Int] = []                     // numbers from up to down this round

var longPressLocation:CGPoint = CGPointMake(0.0, 0.0)  //location of long press

var gameState = 0                               // 0:Ended, 1:Throwing, 2:Flipping
var soundMute = false                           // If sound is muted
var timesPlayed:Int = 0                         // Times played the game
var timesShut:Int = 0                           // Times that the box has been shut
var shutPercentage:Float = 0.0                  // Percentage of above

let scene = SCNScene(named: "ShutTheBox.scnassets/ShutTheBox.dae")! // Scene of the box
let noteScene = SCNScene(named: "bladpotlood.scnassets/blad.dae")!  // Scene of the rules note

var soundManager = SoundManager()               // The class that manages the sound
var soundPlayed1 = false                        // Indicate if sound has been played this round for die 1
var soundPlayed2 = false                        // Indicate if sound has been played this round for die 2

let flickSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Flick", ofType: "m4a")!)     // Flick sound
let diceSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Two Dice", ofType: "wav")!)   // Diceroll sound

var timer: NSTimer = NSTimer()                  // Timer to check if the dice stopped rolling
var throwDuration:Float = 0.0                   // Duration of one throw to prevent wrong throw

var gameEndedText:String = ""                   // String of text shown at game and
var scoreText:String = ""                       // String of text with the statistics
var scoreTextGeometry: SCNText = SCNText()      // Geometry of above
var timesPlayedNode:SCNNode = SCNNode()         // Node for above

let myGray = SCNMaterial()                      // Material Gray
let myWood = SCNMaterial()                      // Material Wood


required init(coder aDecoder: NSCoder) {
    dice1 = scene.rootNode.childNodeWithName("Dice1", recursively: false)!
    dice2 = scene.rootNode.childNodeWithName("Dice2", recursively: false)!
    dices = [dice1,dice2]
    leftCameraNode = noteScene.rootNode.childNodeWithName("Camera", recursively: false)!
    rightCameraNode = scene.rootNode.childNodeWithName("Camera", recursively: false)!
    myGray.diffuse.contents = UIColor.darkGrayColor()
    myWood.diffuse.contents = UIImage(named: "LightWoodTexture.jpg")
    super.init(coder:aDecoder)
}


func initGame() {
// -- Start a new game  -- //
    gameState = 1
    numbersUp = [1,1,1,1,1,1,1,1,1]
    dicePreviousTotal = 0
    for number in numberNames {
        scene.rootNode.childNodeWithName(number, recursively: false)!.eulerAngles = SCNVector3Make(-maxAngle, 0.0, 0.0)
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    retreiveScore()

    // Setup of scene
    scnView.scene = scene
    scnView.allowsCameraControl = false
    scnView.showsStatistics = false
    scnView.backgroundColor = UIColor.blackColor()
    scene.physicsWorld.gravity = SCNVector3Make(0.0, -9.8, 0.0)
    scene.physicsWorld.contactDelegate = self

    // Setup camera to see statistics
    scoreCameraNode.camera = SCNCamera()
    scene.rootNode.addChildNode(scoreCameraNode)
    scoreCameraNode.position = SCNVector3Make(18.5, 9, 5)
    scoreCameraNode.rotation = SCNVector4Make(-1.0, 0.0, 0.0, 1.00)

    // create and add a light to the scene, remove existing
    let lightNode = SCNNode()
    lightNode.light = SCNLight()
    lightNode.light!.type = SCNLightTypeOmni
    lightNode.position = SCNVector3(x: 0, y: 15, z: 10)
    scene.rootNode.addChildNode(lightNode)
    scene.rootNode.childNodeWithName("Lamp", recursively: false)?.removeFromParentNode()

    // create and add an ambient light to the scene
    let ambientLightNode = SCNNode()
    ambientLightNode.light = SCNLight()
    ambientLightNode.light!.type = SCNLightTypeAmbient
    ambientLightNode.light!.color = UIColor.blackColor()
    scene.rootNode.addChildNode(ambientLightNode)

    // add gamerules note and camera
    let noteNode = SCNNode()
    noteNode.addChildNode(noteScene.rootNode.childNodeWithName("Plane", recursively: false)!)
    noteNode.addChildNode(leftCameraNode)
    noteNode.position = SCNVector3Make(-12, 0.02, 0)
    noteNode.rotation = SCNVector4Make(0.0, 1.0, 0.0, 0.2)
    scene.rootNode.addChildNode(noteNode)

    // create score text and node
    if timesShut != 0 {
        shutPercentage = Float(timesShut/timesPlayed * 100)
    }

    scoreText = "Times played:\t\(timesPlayed) \nShut the Box:\t\(shutPercentage)%"
    scoreTextGeometry = SCNText(string: scoreText, extrusionDepth: 5)
    scoreTextGeometry.font = UIFont(name: "Futura-CondensedExtraBold", size: 20)
    scoreTextGeometry.chamferRadius = 0.8
    scoreTextGeometry.materials = [myWood, myGray, myGray]

    timesPlayedNode = SCNNode(geometry: scoreTextGeometry)
    timesPlayedNode.scale = SCNVector3Make(0.05, 0.05, 0.05)
    timesPlayedNode.rotation = SCNVector4Make(-1.0, 0.0, 0.0, Float(M_PI_4))
    timesPlayedNode.position = SCNVector3Make(14.0, 0.0, 0.0)
    timesPlayedNode.name = "timesPlayed"

    scene.rootNode.addChildNode(timesPlayedNode)

    // create boundary box
    let floorBorderGeometry = SCNBox(width: 100, height: 4.0, length: 100, chamferRadius: 0.0)
    let floorPhysicsShape = SCNPhysicsShape(geometry: floorBorderGeometry, options: nil)
    let floorNode = SCNNode()
    floorNode.position = SCNVector3Make(0.0, -1.85, 0.0)
    floorNode.physicsBody = SCNPhysicsBody(type: SCNPhysicsBodyType.Static, shape: floorPhysicsShape)
    scene.rootNode.addChildNode(floorNode)
    floorNode.physicsBody!.friction = 0.8
    floorNode.physicsBody!.categoryBitMask = 0b010
    floorNode.physicsBody!.collisionBitMask = 0b100

    let leftBorderGeometry = SCNBox(width: 4, height: 100, length: 100, chamferRadius: 0.0)
    let leftBorderPhysicsShape = SCNPhysicsShape(geometry: leftBorderGeometry, options: nil)
    let leftBorderNode = SCNNode()
    leftBorderNode.position = SCNVector3Make(-9.32, 0, 0)
    leftBorderNode.physicsBody = SCNPhysicsBody(type: SCNPhysicsBodyType.Static, shape: leftBorderPhysicsShape)
    scene.rootNode.addChildNode(leftBorderNode)
    leftBorderNode.physicsBody!.categoryBitMask = 0b001
    leftBorderNode.physicsBody!.collisionBitMask = 0b100

    let rightBorderNode = SCNNode()
    rightBorderNode.position = SCNVector3Make(9.32, 0, 0)
    rightBorderNode.physicsBody = SCNPhysicsBody(type: SCNPhysicsBodyType.Static, shape: leftBorderPhysicsShape)
    scene.rootNode.addChildNode(rightBorderNode)
    rightBorderNode.physicsBody!.categoryBitMask = 0b001
    rightBorderNode.physicsBody!.collisionBitMask = 0b100

    let frontBorderGeometry = SCNBox(width: 100, height: 100, length: 4, chamferRadius: 0.0)
    let frontBorderPhysicsShape = SCNPhysicsShape(geometry: frontBorderGeometry, options: nil)
    let frontBorderNode = SCNNode()
    frontBorderNode.position = SCNVector3Make(0, 0, 7.85)
    frontBorderNode.physicsBody = SCNPhysicsBody(type: SCNPhysicsBodyType.Static, shape: frontBorderPhysicsShape)
    scene.rootNode.addChildNode(frontBorderNode)
    frontBorderNode.physicsBody!.categoryBitMask = 0b001
    frontBorderNode.physicsBody!.collisionBitMask = 0b100

    let backBorderNode = SCNNode()
    backBorderNode.position = SCNVector3Make(0, 0, -4.35)
    backBorderNode.physicsBody = SCNPhysicsBody(type: SCNPhysicsBodyType.Static, shape: frontBorderPhysicsShape)
    scene.rootNode.addChildNode(backBorderNode)
    backBorderNode.physicsBody!.categoryBitMask = 0b001
    backBorderNode.physicsBody!.collisionBitMask = 0b100

    let topBorderNode = SCNNode()
    topBorderNode.position = SCNVector3Make(0.0, 50.0, 0.0)
    topBorderNode.physicsBody = SCNPhysicsBody(type: SCNPhysicsBodyType.Static, shape: floorPhysicsShape)
    scene.rootNode.addChildNode(topBorderNode)
    topBorderNode.physicsBody!.categoryBitMask = 0b001
    topBorderNode.physicsBody!.collisionBitMask = 0b100

    // Add physics to the dice
    for dice in dices {
        dice.physicsBody = SCNPhysicsBody.dynamicBody()
        dice.physicsBody!.mass = 1.5
        dice.physicsBody!.restitution = 0.0
        dice.physicsBody!.friction = 0.8
        dice.physicsBody!.damping = 0.1
        dice.physicsBody!.categoryBitMask = 0b100
        dice.physicsBody!.collisionBitMask =  0b001 | 0b010 | 0b100

    }

    // Add body to the numbertiles
    for name in numberNames {
        var numberNode = scene.rootNode.childNodeWithName(name, recursively: false)!

        numberNode.physicsBody = SCNPhysicsBody.kinematicBody()
        numberNode.physicsBody!.categoryBitMask = 0b001
        numberNode.physicsBody!.collisionBitMask = 0b100
    }


    // add a tap, pan and longPress gesture recognizer
    let tapGesture = UITapGestureRecognizer(target: self, action: "handleTap:")
    let panGesture = UIPanGestureRecognizer(target: self, action: "handlePan:")
    let longPressGesture = UILongPressGestureRecognizer(target: self, action:"handleLongPress:")

    var gestureRecognizers = [AnyObject]()
    gestureRecognizers.append(tapGesture)
    gestureRecognizers.append(panGesture)
    gestureRecognizers.append(longPressGesture)

    if let existingGestureRecognizers = scnView.gestureRecognizers {
        gestureRecognizers.extend(existingGestureRecognizers)
    }

    scnView.gestureRecognizers = gestureRecognizers

    // initialize game
    initGame()

}

正如您所见,我创建了35个全局变量,并且viewDidLoad中有许多行(130!)代码。我想这就是加载这么长时间的原因。我稍后需要在多个方法中使用变量,因此不能将它们更改为局部变量。

我知道这可能是糟糕的编码,但这是我第一次尝试创建一个完整的工作游戏,这与我所遵循的许多教程和课程完全不同且更大。我还在学习..

你能否就如何在游戏开启时缩短SCNView的渲染时间给出一些建议?

非常感谢所有帮助!

0 个答案:

没有答案