SKSpriteNode не работает с массивом случайных чисел

У меня есть SKSpriteNode, который постоянно появляется. Я создал генератор случайных чисел и попытался связать результаты с другим изображением спрайта. Однако это не работает. Числа генерируются случайным образом, но даже если возвращается «2», SKSpriteNode отображается как «Fire Barrel 1».

class GameScene: SKScene {

var firstObstacle = SKSpriteNode()
var player = SKSpriteNode()
var randomValue = Int()

override func didMove(to view: SKView) {

    createPlayer()

    let delay = SKAction.wait(forDuration: 3)
    let repeatingAction = SKAction.run(repeatingSequence)
    let sequence = SKAction.sequence([ delay, repeatingAction ] )
    run(SKAction.repeatForever(sequence))

}

func randomSelector() {
    let array = [0, 1, 2, 3]
    let randomValue = Int(arc4random_uniform(UInt32(array.count)))
    print(array[randomValue])
}

func createPlayer() {
    player = SKSpriteNode(imageNamed: "Player")
    player.setScale(0.4)
    player.position = CGPoint(x: -player.size.width, y: 0)
    player.zPosition = 1
    addChild(player)
}

func createObstacle() {

    if randomValue == 2 {

        firstObstacle = SKSpriteNode(imageNamed: "Fire Barrel 2")

    }

    else {

        firstObstacle = SKSpriteNode(imageNamed: "Fire Barrel 1")

    }

    firstObstacle.position = CGPoint(x: self.frame.width / 2, y: -self.frame.height / 2 + firstObstacle.size.height / 2)
    firstObstacle.zPosition = 1
    addChild(firstObstacle)
}

func repeatingSequence() {
    randomSelector()
    createObstacle()

    let moveObstacle = SKAction.moveBy(x: -self.frame.width - firstObstacle.size.width, y: 0, duration: 5)
    firstObstacle.run(moveObstacle)
}


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

}

override func update(_ currentTime: TimeInterval) {

}
}

person Martin Jones    schedule 23.10.2016    source источник


Ответы (1)


Ваша проблема

let randomValue = Int(arc4random_uniform(UInt32(array.count)))

Вы делаете то, что называется "переменным затенением". randomValue также существует на уровне экземпляра класса, но здесь, поскольку вы используете let, вы объявили версию с локальной областью.

Фактическое значение self.value равно Int(), что равно 0. Поэтому это "First Barrel l".

Обобщенный дизайн, который вы используете, не очень хорош. Если у вас нет реальной причины, по которой вам нужно удерживать randomValue, вы не должны делать ее переменной экземпляра класса. Вместо этого передайте его аргументом.

Это будет выглядеть примерно так:

func randomSelector() -> Int {
    let array = [0, 1, 2, 3]
    return  Int(arc4random_uniform(UInt32(array.count)))
}

func createObstacle(type:Int) {
    if (type == 2) {
        // Type 2 stuff
    } else {
        // Other stuff
    }

    // Rest of your stuff
}

createObstacle(type: randomSelector())

Хотя, учитывая характер того, как это работает, вам даже не нужен аргумент, вы можете просто сделать:

func createObstacle() {
    if (randomSelector() == 2) {
        // Type 2 stuff
    } else {
        // Other stuff
    }

    // Rest of your stuff
}
person Mobile Ben    schedule 23.10.2016
comment
Спасибо, это работает. Очень четкая инструкция и объяснение, большое спасибо. - person Martin Jones; 23.10.2016