1
\$\begingroup\$

I am trying to run this code but I keep on getting this error:

fatal error: unexpectedly found nil while unwrapping an Optional value I don't understand why I'm getting it. Any hint?

import SpriteKit

class GameScene: SKScene {
    var level: Level!

    let TileWidth: CGFloat = 36.0
    let TileHeight: CGFloat = 36.0

    let gameLayer = SKNode()
    let rocksLayer = SKNode()

    private var swipeFromColumn: Int?
    private var swipeFromRow: Int?

    var swipeHandler: ((Swap) -> ())?

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder) is not used in this app")
    }

    override init(size: CGSize) {
        super.init(size: size)

        anchorPoint = CGPoint(x: 0.5, y: 0.5)

        let background = SKSpriteNode(imageNamed: "Background")
        background.size = size
        addChild(background)

        addChild(gameLayer)

        let layerPosition = CGPoint(
            x: -TileWidth * CGFloat(NumColumns) / 2,
            y: -TileHeight * CGFloat(NumRows) / 2)

        rocksLayer.position = layerPosition
        gameLayer.addChild(rocksLayer)

        swipeFromColumn = nil
        swipeFromRow = nil
    }

    func addSpritesForRocks(_ rocks: Set<Rock>) {
        for rock in rocks {
            let sprite = SKSpriteNode(imageNamed: rock.rockType.spriteName)
            sprite.size = CGSize(width: TileWidth, height: TileHeight)
            sprite.position = pointForColumn(rock.column, row: rock.row)
            rocksLayer.addChild(sprite)
        }
    }

    func pointForColumn(_ column: Int, row: Int) -> CGPoint {
        return CGPoint(
            x: CGFloat(column) * TileWidth + TileWidth / 2,
            y: CGFloat(row) * TileHeight + TileHeight / 2)
    }

    func convertPoint(_ point: CGPoint) -> (success: Bool, column: Int, row: Int) {
        if point.x >= 0 && point.x < CGFloat(NumColumns)*TileWidth &&
            point.y >= 0 && point.y < CGFloat(NumRows)*TileHeight {
            return (true, Int(point.x / TileWidth), Int(point.y / TileHeight))
        } else {
            return (false, 0, 0)
        }
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let touch = touches.first else { return }
        let location = touch.location(in: rocksLayer)

        let (success, column, row) = convertPoint(location)
        if success {
            if let rock = level.rockAtColumn(column: column, row: row) {
                swipeFromColumn = column
                swipeFromRow = row
            }
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard swipeFromColumn != nil else { return }

        guard let touch = touches.first else { return }
        let location = touch.location(in: rocksLayer)

        let (success, column, row) = convertPoint(location)
        if success {
            var horzDelta = 0, vertDelta = 0
            if column < swipeFromColumn! {
                horzDelta = -1
            } else if column > swipeFromColumn! {
                horzDelta = 1
            } else if row < swipeFromColumn! {
                vertDelta = -1
            } else if row > swipeFromColumn! {
                vertDelta = 1
            }

            if horzDelta != 0 || vertDelta != 0 {
                trySwapHorizontal(horzDelta, vertical: vertDelta)

                swipeFromColumn = nil
            }
        }
    }

    func trySwapHorizontal(_ horzDelta: Int, vertical vertDelta: Int) {
        let toColumn = swipeFromColumn! + horzDelta
        let toRow = swipeFromRow! + vertDelta

        guard toColumn >= 0 && toColumn < NumColumns else { return }
        guard toRow >= 0 && toRow < NumRows else { return }

        if let toRock = level.rockAtColumn(column: toColumn, row: toRow),
            let fromRock = level.rockAtColumn(column: swipeFromColumn!, row: swipeFromRow!),
            let handler = swipeHandler {
            // Communicate this swap request back to the ViewController.
            let swap = Swap(rockA: fromRock, rockB: toRock)
            handler(swap)
        }
    }

    func animateSwap(_ swap: Swap, completion: @escaping () -> ()) {
        let spriteA = swap.rockA.sprite!
        let spriteB = swap.rockB.sprite!

        spriteA.zPosition = 100
        spriteB.zPosition = 90

        let Duration: TimeInterval = 0.3

        let moveA = SKAction.move(to: spriteB.position, duration: Duration)
        moveA.timingMode = .easeOut
        spriteA.run(moveA, completion: completion)

        let moveB = SKAction.move(to: spriteA.position, duration: Duration)
        moveB.timingMode = .easeOut
        spriteB.run(moveB)
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        swipeFromColumn = nil
        swipeFromRow = nil
    }

    override func touchesCancelled(_ touches: Set<UITouch>?, with event: UIEvent?) {
        if let touches = touches {
            touchesEnded(touches, with: event)
        }
    }
}
\$\endgroup\$

closed as off-topic by Sean Middleditch, Almo, Vaillancourt, Jesse Dorsey Oct 13 '16 at 21:42

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions about debugging a problem must provide a minimal, complete, verifiable example of the issue so that readers can diagnose it without needing to guess, read all of your code, or engage in extensive back-and-forth dialog. For more information, see this meta thread." – Sean Middleditch, Almo, Jesse Dorsey
If this question can be reworded to fit the rules in the help center, please edit the question.

  • \$\begingroup\$ Is that the exact error message from the system? Indicating the line the error occurs on would be helpful. I'd wager the vast majority of people here are unfamiliar with Swift. Even as someone who's vaguely aware of its semantics, you've supplied far too much irrelevant code for me to have any possible hope of finding the problem. Have you tried using the swift debugger? \$\endgroup\$ – Sean Middleditch Sep 24 '16 at 17:41

Browse other questions tagged or ask your own question.