Swift 4 SprikeKit - 线程1:致命错误:索引超出范围

时间:2018-01-30 19:17:22

标签: arrays swift

我正在学习Swift,我正在跟随我工作过的另一个项目。但是,我收到了这个错误:

我收到错误:

Thread 1: Fatal error: Index out of range

我的所有代码:

import SpriteKit
import GameplayKit

class GameScene: SKScene {

    var scoreLabel : SKLabelNode?
    var player : SKSpriteNode?
    var track : Int = 0

    var trackArray : [SKSpriteNode]? = [SKSpriteNode]()
    var ballDirection = Int(arc4random_uniform(2))
    var velocityArray = [Int]()
    var playerVelocity : Int = GKRandomSource.sharedRandom().nextInt(upperBound: 100)

    var currentScore : Int = 0 {
        didSet {
            self.scoreLabel?.text = "SCORE: \(self.currentScore)"
        }
    }


    func createHUD() {
        scoreLabel = self.childNode(withName: "score") as? SKLabelNode
        currentScore = 0
    }

    //I think the problem is coming from this function, however I more-or-less copied it from a tutorial project that works so I don't know what the problem is.
    func setupTracks() {
        for i in  {
            if let track = self.childNode(withName: "\(i)") as? SKSpriteNode {
                trackArray?.append(track)
                print(track)
            }
        }
    }


    func createBall() {

        player = SKSpriteNode(imageNamed: "ball1")
        player?.physicsBody = SKPhysicsBody(circleOfRadius: player!.size.width / 2)
        player?.physicsBody?.linearDamping = 0

        //This line throws the error
        let ballPosition = trackArray?[track].position
        print(track)
        player?.position = CGPoint(x: (ballPosition?.x)!, y: (ballPosition?.y)!)

        player?.position.x = (ballPosition!.x)
        player?.position.y = (ballPosition!.y)

        self.addChild(player!)

    }


    override func didMove(to view: SKView) {

        createHUD()
        createBall()

    }


    override func update(_ currentTime: TimeInterval) {
        // Called before each frame is rendered

    }
}

我有8个Color Sprite对象,我通过GameScene.sks输入,每个对象名为0 - 9,

我认为它正在寻找尚未分配的数组中的值?但我有一部分(我认为)正在分配这个价值。它也适用于其他项目,所以我很迷失。

1 个答案:

答案 0 :(得分:0)

如果没有上下文,有些内容对我没有任何意义,但基于我可以推断的情况,似乎更好的解决方案是使用单个字典来访问SKSpriteNode以及方向和速度。要实现这一点,您可以创建一个自定义对象,或者只使用一个简单的元组。

初始化字典并用对象填充后,您可以访问字典中的单个值,以获取createEnemy函数所需的所有数据。它可能看起来像这样:

var tracks = [Int : (node: SKSpriteNode, direction: CGFloat, velocity: CGFloat)]()

func setupTrack() {
    for i in 0 ... 9 {
        if let track = self.childNode(withName: "\(i)") as? SKSpriteNode {
            //Get direction and velocity here, if initial value is known
            //Setting to 0 for now
            tracks[i] = (node: track, direction: 0, velocity: 0)
        }
    }
}


func createEnemy(forTrack track: Int) -> SKShapeNode? {
    guard let thisTrack = tracks[track] else { return nil }

    let enemySprite = SKShapeNode()
    enemySprite.name = "ENEMY"

    enemySprite.path = CGPath(roundedRect: CGRect(x: 0, y: -10, width: 20, height: 20), cornerWidth: 10, cornerHeight: 10, transform: nil)

    let enemyPosition = thisTrack.node.position

    let left = thisTrack.direction

    enemySprite.position.x = left ? -50 : self.size.height + 50
    enemySprite.position.y = enemyPosition.y

    enemySprite.physicsBody?.velocity = left ? CGVector(dx: thisTrack.velocity, dy: 0) : CGVector(dx: 0, dy: -thisTrack.velocity)

    return enemySprite
}

这将阻止您越过阵列的界限。请注意:由于您循环遍历硬编码的0 ... 9范围,但您可选将项目附加到Array(如果您的if let track失败)您无法保证名称为“7”的“track”项对应于数组中的第7个索引。这是Dictionary更安全的另一个原因。此外,您似乎正在维护3个独立的数组(track,directionArray和velocityArray),由于我刚才描述的原因,它似乎容易出错。