Как постоянно стрелять - PullRequest
0 голосов
/ 16 апреля 2019

Я изучаю Swift и SpriteKit с помощью небольшой игры, в которой игрок должен защищать военную базу. Тем не менее, игрок должен коснуться для стрельбы пули. Но мне бы хотелось, чтобы при касании экрана огонь непрерывный, а не касаться экрана каждый раз одной пулей. Кроме того, когда он остановился, чтобы коснуться экрана, огонь остановился.

Моя функция огнестрельного оружия:

func fireBullet () {
    let bullet = SKSpriteNode(imageNamed: "Bullet")
    bullet.name = "Bullet" //afin de permettre l'arrêt des missiles en cas de gameOver
    bullet.setScale(0.5)
    bullet.position = CGPoint(x: planet.position.x, y: planet.position.y)
    bullet.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    bullet.zPosition = 1
    bullet.physicsBody = SKPhysicsBody(rectangleOf: bullet.size) // changer le rectangle en forme circulaire
    bullet.physicsBody!.affectedByGravity = false
    bullet.physicsBody!.categoryBitMask = physicsCategories.bullet
    bullet.physicsBody!.collisionBitMask = physicsCategories.none
    bullet.physicsBody!.contactTestBitMask = physicsCategories.asteroid
    self.addChild(bullet)
    let moveBullet = SKAction.moveTo(y: self.size.height + bullet.size.height, duration: 1.0)
    let deleteBullet = SKAction.removeFromParent()
    let bulletSequence = SKAction.sequence([bulletSound, moveBullet, deleteBullet])
    bullet.run(bulletSequence)
}

И я называю это в TouchesBegan:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if currentGameState == gameState.preGame {
        gameStart()
    }
   else if currentGameState == gameState.inGame {
        fireBullet()
    }

Спасибо за вашу помощь:)

Ответы [ 3 ]

0 голосов
/ 17 апреля 2019

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

Примерно так (не проверялось, запись из памяти) срабатывает каждые 1,5 секунды

var isTouching = false
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    fireBall()
    isTouching = true
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    isTouching = false
    dt = 0
}

var lastUpdateTime: TimeInterval = 0
var dt: TimeInterval = 0

override func update(_ currentTime: TimeInterval) {
    //Update time fraction per frame
    if lastUpdateTime > 0 {
        dt += currentTime - lastUpdateTime
    } else {
        dt = 0
    }
    if dt > 1.5 && isTouching {
        fireBall()
        dt = 0
    }
    lastUpdateTime = currentTime
}

Еще одна важная вещь : удаление узла, когда он больше не нуженВы можете сделать это, используя задержку в качестве конца последовательности SKAction (ожидание х секунд), а затем SKAction.removeFromParent.

0 голосов
/ 18 апреля 2019

Чтобы стрелять непрерывно, все, что вам нужно сделать, это просто создать серию действий, которые будут повторяться при входе в состояние начала касания, и останавливать действия при отпускании касания

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if currentGameState == gameState.preGame {
        gameStart()
    }
    else if currentGameState == gameState.inGame {

        let fire = SKAction.run{self.fireBullet()}
        let wait = SKAction.wait(forDuration:0.1)  //delay between shots
        let seq = SKAction.sequence([fire,wait])
        let repeat = SKAction.repeatForever(seq)
        planet.run(repeat, withKey:"bullets")
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if currentGameState == gameState.preGame {

    }
    else if currentGameState == gameState.inGame {
        planet.removeAction(forKey:"bullets")
    }
}

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

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

0 голосов
/ 16 апреля 2019

Вы можете вызывать fireAction внутри себя с помощью SKAction.

func fireBullet() {

    ...

    let moveBullet = SKAction.moveTo(y: self.size.height + bullet.size.height, duration: 1.0)
    let deleteBullet = SKAction.removeFromParent()
    let fireCooldown = SKAction.wait(forDuration: 0.5)
    let bulletSequence = SKAction.sequence([bulletSound, moveBullet, deleteBullet, fireCooldown])
    bullet.run(bulletSequence) {
        if currentGameState == gameState.inGame, isTouchingScreen {
            fireBullet()
        }
        // runs actions, wait for 0.5 seconds and trigger a new fireBullet in completion
    }
}

Для настройки перезарядки вы можете изменить значение fireCooldown или, если вы не хотите ждать завершения всего действия, вы можете удалить fireCooldown изпоследовательность и вызвать его в одиночку с завершением.IsTouchingScreen - это логическое значение, для которого вы можете установить значение true в touchSegan и затем значение false в touchShended.

...