двойные нереста (и перекрывающиеся) враги на Spritekit - PullRequest
2 голосов
/ 07 апреля 2020

У меня проблемы с бесконечной запуском игры, в основном из-за появления двух созданных мной врагов, иногда случается, что два врага появляются, когда мы вызываем функцию «startDifficultyTimer». В основном, когда я вызываю эту функцию, игра порождает 2 узла в одном ряду, поэтому игрок вынужден проигрывать, я хочу этого избежать, но я не знаю как, я пробовал почти все, я пытался удалить createsequentialenemy из didmove но проблема все еще сохраняется, я думаю (как newb ie), что проблема в функции startDifficultTimer, потому что, когда значение достигает предела, проблема исчезает, я разместил код ниже, извините за, вероятно, огромную ошибку, но мы новая игра в быстрой разработке, огромное спасибо всем!

func createEnemy() {
    let enemy: Enemy
    let duration: CGFloat

    switch Int(arc4random() % 100) {
        case 0...70:
            enemy = Enemy.createEnemy()
            duration =  CGFloat(Float(arc4random()%1)) + durationV
            enemy.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 55, height: 37))
            let enemyf = enemy.frame
            let fixedx = frame.width + enemy.frame.width/2.0
            let positions = [ CGPoint(x: fixedx, y: 383), CGPoint(x: fixedx, y: 447), CGPoint(x: fixedx, y: 511)]
            let position = positions[Int(arc4random_uniform(UInt32(positions.count)))]
            enemy.position = position
        case 71...100:
            enemy = Enemy.createEnemyMedium()
            duration =  CGFloat(Float(arc4random()%1)) + durationV
            enemy.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 40, height: 70))
            let enemyf = enemy.frame
            let fixedx = frame.width + enemy.frame.width/2.0
            let positions = [ CGPoint(x: fixedx, y: 415), CGPoint(x: fixedx, y: 479)]
            let position = positions[Int(arc4random_uniform(UInt32(positions.count)))]
            enemy.position = position
        default:
            enemy = Enemy.createEnemy()
            //type = .small
            duration =  CGFloat(Float(arc4random()%1)) + durationV
            let enemyf = enemy.frame
            let fixedx = frame.width + enemy.frame.width/2.0
            let positions = [ CGPoint(x: fixedx, y: 383), CGPoint(x: fixedx, y: 447), CGPoint(x: fixedx, y: 511)]
            let position = positions[Int(arc4random_uniform(UInt32(positions.count)))]
            let texture = SKTexture(imageNamed: "dronea1")
            enemy.position = position
    }

    enemy.physicsBody!.isDynamic = false
    enemy.physicsBody!.categoryBitMask = PhysicsCategory.Enemy
    addChild(enemy)

    let moveTo = SKAction.moveTo(x: 0.0, duration: TimeInterval(duration))
    enemy.run(.repeatForever(.sequence([moveTo, .removeFromParent()])))
}

func createSequentialEnemies() {
    // remove previous action if running. This way you can adjust the spawn duration property and call this method again and it will cancel previous action.
    removeAction(forKey: spawnKey)
    let spawnAction = SKAction.run(createEnemy)
    let spawnDelay = SKAction.wait(forDuration: spawnDuration)
    let spawnSequence = SKAction.sequence([spawnAction, spawnDelay])
    run(SKAction.repeatForever(spawnSequence), withKey: spawnKey)later
}

func startDifficultyTimer() {
    let difficultyTimerKey = "DifficultyTimerKey"
    let action1 = SKAction.wait(forDuration: 1)
    let action2 = SKAction.run { [unowned self] in
        guard self.spawnDuration > 0.5 else {  // set a min limit
            self.removeAction(forKey: difficultyTimerKey) // if min duration has been reached than you might as well stop running this timer.
            return
        }
        self.spawnDuration -= 0.5 // reduce by half a second
        self.createSequentialEnemies() // spawn enemies again
    }
    let sequence = SKAction.sequence([action1, action2])
    run(SKAction.repeatForever(sequence), withKey: difficultyTimerKey)
}

1 Ответ

1 голос
/ 07 апреля 2020

Я думаю, что проблема в том, что вы говорите «остановить это действие» при изменении таймера. Но это утверждение не знает, был ли враг только что создан или вот-вот будет создан. Где бы он ни был в l oop, вы останавливаете его и начинаете l oop снова. Так что, если он только что создал врага, и вы остановите l oop и начнете его заново, генерируя нового врага быстрее, вы получите двух врагов подряд.

Обойти это можно было бы путем запуска последовательность в обратном порядке. Сделайте паузу, а затем сгенерируйте своего врага.

let spawnSequence = SKAction.sequence([spawnDelay, spawnAction])

вы можете получить немного больший промежуток между врагами, но вы не получите два с размахом друг на друга.

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

...