我正在通过一个小游戏学习Swift和SpriteKit,玩家必须在其中保卫军事基地。但是,玩家必须触摸子弹。 但是我想当他触摸屏幕时,火势持续不断,而不是每次都敲击屏幕一次子弹。 此外,当他停下来触摸屏幕时,炮弹也停了下来。
我的Firebullet功能:
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()
}
感谢您的帮助:)
答案 0 :(得分:0)
您可以使用SKAction在其内部调用fireAction。
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是一个布尔值,您可以在touchesBegan中将其设置为true,然后在touchesEnded中将其设置为false。
答案 1 :(得分:0)
一种实现方法是在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的结束(等待x秒),然后再执行SKAction.removeFromParent。< / p>
答案 2 :(得分:0)
要连续触发,您需要做的只是简单地创建一系列动作,这些动作将在您进入触摸开始状态时重复,并在您释放触摸时停止操作
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")
}
}
现在,您将需要在取消触摸时处理删除操作。您还需要在多根手指按下屏幕时进行处理,因为您不想在操作发生时重新启动操作。
作为旁注,我建议在应用程序的开头创建大量的项目符号,并不断对其进行回收以避免不断产生新的项目符号。