将场景更改回原始版本后,EXC BAD ACCESS

时间:2016-05-05 10:48:48

标签: ios swift sprite-kit exc-bad-access

我正在用Sprite-kit制作一个游戏,你可以转动一个轮子并需要躲避球,但每次我将场景从gameOverScene改为gameScene时,我都会得到一个EXC BAD ACCESS。当gameScene第一次加载时没有出现问题。

我收到此错误,因为我将'wheel'变量放在gameScene中的didMoveToView函数之外。我这样做了,所以你不必触摸方向盘就可以旋转它。

那么你们可以帮我解决这个问题吗?

gameScene:

import SpriteKit

//Collision bitmasks
let BallCategory   : UInt32 = 0x1 << 0 // 00000000000000000000000000000001
let BorderCategory   : UInt32 = 0x1 << 1 // 00000000000000000000000000000010
let WheelCategory  : UInt32 = 0x1 << 2 // 00000000000000000000000000000100

//Score variable
var score:Int = 0
let scoreLabel = SKLabelNode()

//Drag rotating variables
var startingAngle:CGFloat?
var startingTime:NSTimeInterval?

//Wheel variable
let wheel = SKSpriteNode(imageNamed: "wheel") // THE ERROR IS PROBABLY HERE!

class GameScene: SKScene, SKPhysicsContactDelegate {

    override func didMoveToView(view: SKView) {
        super.didMoveToView(view)

        //Border
        let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
        self.physicsBody = borderBody
        self.physicsBody?.categoryBitMask = BorderCategory
        self.physicsBody?.restitution = 1
        self.physicsBody?.friction = 0


        //Ball
        let ballNode = SKSpriteNode(imageNamed: "ball")
        let scaleBall = frame.width / ballNode.frame.width * 0.035
        ballNode.position = CGPoint(x: size.width * 0.5, y: size.height * 0.5)
        addChild(ballNode)
        ballNode.setScale(scaleBall)
        let ballWidth = ballNode.size.width
        ballNode.physicsBody = SKPhysicsBody(circleOfRadius: ballWidth * 0.5)
        ballNode.physicsBody?.dynamic = true
        ballNode.physicsBody?.categoryBitMask = BallCategory
        ballNode.physicsBody?.contactTestBitMask = BorderCategory
        ballNode.physicsBody?.restitution = 1
        ballNode.physicsBody?.friction = 0
        ballNode.physicsBody?.angularDamping = 0
        ballNode.physicsBody?.linearDamping = 0
        let delay = SKAction.waitForDuration(1.0)
        ballNode.runAction(delay) {
            let widthiPhone6 = CGFloat(375)
            let heightiPhone6 = CGFloat(667)
            let forceX = (self.frame.width / widthiPhone6) * (self.frame.width / widthiPhone6) * ((self.frame.width / widthiPhone6) / 1.5) * 3
            let forceY = (self.frame.height / heightiPhone6) * (self.frame.height / heightiPhone6) * ((self.frame.width / widthiPhone6) / 1.5) * 2.3
            print("Force: \(forceX), \(forceY)")
            ballNode.physicsBody!.applyImpulse(CGVectorMake(forceX, forceY))
        }

        //Score
        //scoreLabel.position = CGPoint(x: size.width * 0.1, y: size.height * 0.1)
        //scoreLabel.fontColor = UIColor.blackColor()
        addChild(scoreLabel)

        //Background
        backgroundColor = SKColor.whiteColor()

        //physicsWorld
        physicsWorld.gravity = CGVectorMake(0, 0)
        physicsWorld.contactDelegate = self

        //Wheel
        //let wheel = SKSpriteNode(imageNamed: "wheel")
        let scaleWheel = frame.width / wheel.frame.width * 0.8
        print("Scale of the wheel: \(scaleWheel)\nFrame width: \(frame.width)\nWheel frame width: \(wheel.frame.width)")
        wheel.name = "wheel"
        wheel.position = view.center

        //Scale constants
        let sprite = SKSpriteNode()
        sprite.position = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame))
        let offsetX: CGFloat = sprite.frame.size.width * sprite.anchorPoint.x
        let offsetY: CGFloat = sprite.frame.size.height * sprite.anchorPoint.y

        //path
        let path: CGMutablePathRef = CGPathCreateMutable()

        CGPathMoveToPoint(path, nil, -142 - offsetX, 143 - offsetY)
        CGPathAddLineToPoint(path, nil, -177 - offsetX, 161 - offsetY)
        CGPathAddLineToPoint(path, nil, -149 - offsetX, 188 - offsetY)
        CGPathAddLineToPoint(path, nil, -105 - offsetX, 215 - offsetY)
        CGPathAddLineToPoint(path, nil, -57 - offsetX, 232 - offsetY)
        CGPathAddLineToPoint(path, nil, -2 - offsetX, 238 - offsetY)
        CGPathAddLineToPoint(path, nil, 57 - offsetX, 231 - offsetY)
        CGPathAddLineToPoint(path, nil, 109 - offsetX, 213 - offsetY)
        CGPathAddLineToPoint(path, nil, 146 - offsetX, 188 - offsetY)
        CGPathAddLineToPoint(path, nil, 176 - offsetX, 162 - offsetY)
        CGPathAddLineToPoint(path, nil, 142 - offsetX, 141 - offsetY)
        CGPathAddLineToPoint(path, nil, 121 - offsetX, 160 - offsetY)
        CGPathAddLineToPoint(path, nil, 92 - offsetX, 179 - offsetY)
        CGPathAddLineToPoint(path, nil, 53 - offsetX, 194 - offsetY)
        CGPathAddLineToPoint(path, nil, 0 - offsetX, 201 - offsetY)
        CGPathAddLineToPoint(path, nil, -48 - offsetX, 195 - offsetY)
        CGPathAddLineToPoint(path, nil, -88 - offsetX, 181 - offsetY)
        CGPathAddLineToPoint(path, nil, -119 - offsetX, 163 - offsetY)

        CGPathCloseSubpath(path)

        //pathTwo
        let pathTwo: CGMutablePathRef = CGPathCreateMutable()

        CGPathMoveToPoint(pathTwo, nil, -241 - offsetX, 31 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -205 - offsetX, 17 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -205 - offsetX, -18 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -199 - offsetX, -56 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -184 - offsetX, -94 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -164 - offsetX, -127 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -140 - offsetX, -153 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -115 - offsetX, -175 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -86 - offsetX, -191 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -65 - offsetX, -200 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -64 - offsetX, -240 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -98 - offsetX, -228 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -129 - offsetX, -211 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -165 - offsetX, -184 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -195 - offsetX, -152 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -216 - offsetX, -117 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -233 - offsetX, -77 - offsetY)
        CGPathAddLineToPoint(pathTwo, nil, -244 - offsetX, -25 - offsetY)

        CGPathCloseSubpath(pathTwo)

        //pathThree
        let pathThree: CGMutablePathRef = CGPathCreateMutable()

        CGPathMoveToPoint(pathThree, nil, 204 - offsetX, -3 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 240 - offsetX, 21 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 241 - offsetX, -30 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 235 - offsetX, -66 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 222 - offsetX, -104 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 205 - offsetX, -136 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 180 - offsetX, -168 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 150 - offsetX, -196 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 113 - offsetX, -220 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 79 - offsetX, -233 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 78 - offsetX, -194 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 104 - offsetX, -181 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 133 - offsetX, -161 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 154 - offsetX, -140 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 172 - offsetX, -115 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 186 - offsetX, -89 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 196 - offsetX, -63 - offsetY)
        CGPathAddLineToPoint(pathThree, nil, 202 - offsetX, -36 - offsetY)

        CGPathCloseSubpath(pathThree)

        //Physics bodies
        let bodyOne = SKPhysicsBody(edgeLoopFromPath: path)
        let bodyTwo = SKPhysicsBody(edgeLoopFromPath: pathTwo)
        let bodyThree = SKPhysicsBody(edgeLoopFromPath: pathThree)

        wheel.physicsBody = SKPhysicsBody(bodies: [bodyOne, bodyTwo, bodyThree])
        wheel.physicsBody!.angularDamping = 5
        wheel.physicsBody?.pinned = true
        wheel.physicsBody?.affectedByGravity = false
        wheel.physicsBody?.restitution = 1
        wheel.setScale(scaleWheel)
        addChild(wheel)
    }

    func didBeginContact(contact: SKPhysicsContact) {
        //Create local variables for two physics bodies
        var firstBody: SKPhysicsBody
        var secondBody: SKPhysicsBody

        //Assign the two physics bodies so that the one with the lower category is always stored in firstBody
        if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
            firstBody = contact.bodyA
            secondBody = contact.bodyB
        } else {
            firstBody = contact.bodyB
            secondBody = contact.bodyA
        }

        //React to the contact between ball and bottom
        if firstBody.categoryBitMask == BallCategory && secondBody.categoryBitMask == BorderCategory {
            score += 1
            scoreLabel.text = "\(score)"
            scoreLabel.position = CGPoint(x: size.width * 0.1, y: size.height * 0.1)
            scoreLabel.fontColor = UIColor.blackColor()
            print("SCORE: \(score)")
        } else {
            print("GAME OVER")

            NSUserDefaults.standardUserDefaults().integerForKey("score")
            NSUserDefaults.standardUserDefaults().setInteger(score, forKey: "score")
            NSUserDefaults.standardUserDefaults().synchronize()

            NSUserDefaults.standardUserDefaults().integerForKey("highscore")
            //Check if score is higher than NSUserDefaults stored value and change NSUserDefaults stored value if it's true
            if score > NSUserDefaults.standardUserDefaults().integerForKey("highscore") {
                NSUserDefaults.standardUserDefaults().setInteger(score, forKey: "highscore")
                NSUserDefaults.standardUserDefaults().synchronize()
            }

            score = 0

            //removeChildrenInArray([wheel])

            let newScene = GameOverScene(size: size)
            newScene.scaleMode = .AspectFill
            view?.presentScene(newScene)
        }

    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        for touch in touches {
            let location = touch.locationInNode(self)
            //let node = nodeAtPoint(location)
            let node = wheel
            let dx = location.x - node.position.x
            let dy = location.y - node.position.y
            // Store angle and current time
            startingAngle = atan2(dy, dx)
            startingTime = touch.timestamp
            node.physicsBody?.angularVelocity = 0
            }
    }

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        for touch in touches {
            let location = touch.locationInNode(self)
            //let node = nodeAtPoint(location)
            let node = wheel
            let dx = location.x - node.position.x
            let dy = location.y - node.position.y

            let angle = atan2(dy, dx)
            // Calculate angular velocity
            // EDIT: Handle wrap at pi/-pi
            var deltaAngle:CGFloat
            if startingAngle == nil {
                deltaAngle = CGFloat()
            } else {
                deltaAngle = angle - startingAngle!
            }
            if abs(deltaAngle) > CGFloat(M_PI) {
                if (deltaAngle > 0) {
                    deltaAngle = deltaAngle - CGFloat(2*M_PI)
                }
                else {
                    deltaAngle = deltaAngle + CGFloat(2*M_PI)
                }
            }
            if startingTime == nil {
                startingTime = 0
            }
            let dt = CGFloat(touch.timestamp - startingTime!)
            let velocity = deltaAngle / dt

            node.physicsBody?.angularVelocity = velocity

            // Update angle and time
            startingAngle = angle
            startingTime = touch.timestamp
        }
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        startingAngle = nil
        startingTime = nil
    }

    func offset(node: SKSpriteNode, isX: Bool)->CGFloat {
        return isX ? node.frame.size.width * node.anchorPoint.x : node.frame.size.height * node.anchorPoint.y
    }

    func AddLineToPoint(path: CGMutablePath!, x: CGFloat, y: CGFloat, node: SKSpriteNode) {
        CGPathAddLineToPoint(path, nil, (x * 2) - offset(node, isX: true), (y * 2) - offset(node, isX: false))
    }

    func MoveToPoint(path: CGMutablePath!, x: CGFloat, y: CGFloat, node: SKSpriteNode) {
        CGPathMoveToPoint(path, nil, (x * 2) - offset(node, isX: true), (y * 2) - offset(node, isX: false))
    }
}

gameOverScene:

import Foundation
import SpriteKit

class GameOverScene: SKScene {

    //Create button
    let button = SKLabelNode(text: "Tap to restart!")

    override func didMoveToView(view: SKView) {
        super.didMoveToView(view)

        //Background
        backgroundColor = SKColor.whiteColor()

        //Button
        button.fontColor = UIColor.blackColor()
        button.fontSize = 50
        button.position = view.center
        addChild(button)

        //Ruined
        let youTotally = SKLabelNode(text: "You totally")
        youTotally.fontSize = 50
        youTotally.fontColor = UIColor.redColor()
        youTotally.position = CGPoint(x: size.width * 0.5, y: size.height * 0.8)
        addChild(youTotally)


        let ruined = SKLabelNode(text: "Ruined")
        ruined.fontSize = 60
        ruined.fontColor = UIColor.redColor()
        ruined.position = CGPoint(x: size.width * 0.5, y: size.height * 0.8 - 60)
        addChild(ruined)

        let it = SKLabelNode(text: "it!")
        it.fontSize = 50
        it.fontColor = UIColor.redColor()
        it.position = CGPoint(x: size.width * 0.5, y: size.height * 0.8 - 110)
        addChild(it)

        //Score
        let scoreLabelEnd = SKLabelNode(text: "Score: \(NSUserDefaults.standardUserDefaults().integerForKey("score"))")
        scoreLabelEnd.position = CGPoint(x: size.width * 0.5, y: size.height * 0.1 + 40)
        scoreLabelEnd.fontColor = UIColor.blackColor()
        addChild(scoreLabelEnd)

        //Highscore
        let highscoreLabel = SKLabelNode(text: "Highscore: \(NSUserDefaults.standardUserDefaults().integerForKey("highscore"))")
        highscoreLabel.position = CGPoint(x: size.width * 0.5, y: size.height * 0.1)
        highscoreLabel.fontColor = UIColor.blackColor()
        addChild(highscoreLabel)

        NSUserDefaults.standardUserDefaults().integerForKey("score")
        NSUserDefaults.standardUserDefaults().setInteger(0, forKey: "score")
        NSUserDefaults.standardUserDefaults().synchronize()
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        print("GAME START")
        let newScene = GameScene(size: size)
        newScene.scaleMode = .AspectFill
        view?.presentScene(newScene)
    }
}

我得到的错误的图片。 Picture of the error

0 个答案:

没有答案