所以我有一个游戏,有一个叫做敌人的精灵,它周围有一个看不见的圆圈,还有一个玩家精灵,可以360度自由地绕着敌人移动.然而,当玩家进入敌人圆圈的框架时,这会触发敌人开始向玩家emits 子弹.这名球员仍然可以移动.我遇到的问题是让敌人不停地射击子弹,并且即使在球员换了位置之后,也要不断地向球员的位置射击.

我将添加一些代码来帮助您判断问题:

为了快速参考,我们这里有一篇简短的文章,其中我只包含了我认为快速帮助所需的最低限度.(我不确定在哪里调用FireBullets()函数...在更新函数内部?在DID搬家的里面?在DidBegin?)内部.

    func fireBullets() {

        var fireBulletAction: SKAction

        fireBulletAction = SKAction.run {
            let bullet = self.createBullets()
            var moveBullet = SKAction.move(to: self.player.position, duration: 1)
            bullet.run(moveBullet)
        }

        var waitForDuration: SKAction
        waitForDuration = SKAction.wait(forDuration: 1)

        var bulletSequence = SKAction.sequence([fireBulletAction, waitForDuration])

        var repeatBulletSequence = SKAction.repeatForever(bulletSequence)

        enemy.run(repeatBulletSequence, withKey: "fireBullet")
    }

或者,为了更快、更容易地用所有组件(它仍然只有96行代码)重现问题,我制作了这个简单的GameScene.swft文件,您可以轻松地将它从text复制粘贴到XCode中.

推荐答案

EDIT:我没有考虑到你的项目中使用了SKAction.repeatForever,所以我编辑了我最初的答案,这是部分错误的.

这是你的问题:

override func didMove(to view: SKView) {

    // side note: add this when overriding methods
    super.didMove(to: view)

    createPlayer(view: view)
    createEnemy(view: view)
    if collisionDetected {
        fireBullets()
    }
}

此方法在呈现场景时调用.在您的样例项目中,collisionDetectedfalse,所以fireBullets()永远不会触发.

您应该将它移到update()函数中,假设您的fps设置为60,则该函数每隔1/60秒调用一次.注意:我还假设你不想定位玩家和敌人,这样场景一出现就会触emits 击:

    override func update(_ currentTime: TimeInterval) {
        super.update(currentTime)
        if !collisionDetected {
            detectCollisions()
        } else if !isShooting {
            fireBullets()
        }
    }

请注意,我添加了一个isShooting支票,这是一个新变量.原因是,因为您使用的是SKAction.repeatForever,而update()被多次调用,所以您希望只触发fireBullets()方法一次.实现这一点的一种方法是声明另一个变量来跟踪它.

var isShooting = false

然后在fireBullets()中,第一次emits 时将其设置为TRUE,这样就不会再次emits :

isShooting = true 

如果你想了解更多,here是另一个类似的例子,来self 回答的一个问题.

这样,在您的样例项目中,一切都按预期工作,至少在我的模拟器中,就像您所说的那样.

在一个侧面的 node 上,你应该在某个时刻从场景中移除子弹 node ,我想你实际上在你的实际项目中注意到了这一点,否则 node 数量会迅速增加,直到崩溃.

此外,对于碰撞检测,请考虑使用SKPhysicsContactDelegate.

Swift相关问答推荐

在Swift中,将秒设置为0也等于将1添加到分钟

try 从闭包访问返回的字符串时出现无法将类型 '()' 的返回表达式转换为返回类型 'String'编译器错误

为什么我的Swift app不能用xcodebuild构建,但是用XCode可以构建?

自定义碰撞形状出现在错误的位置

将弱引用作为类函数引用传递时,弱引用无法按预期工作

如何从 Swift 中隐藏 Objective-C 类接口的一部分?

Swift Random Float Fatal Error:在无限范围内没有均匀分布

SwiftUI:当 currentIndex 值更改时,数组中的第 n 个视图是否已换出?

为什么 id 不能通过 struct 从 Objective-C 移植到 Swift?

Swift并发:为什么不在其他后台线程上执行任务

按钮图像不会立即刷新

响应 UITextField (UIViewRepresentable) 中的特定按键

如何在 Swift 中的两个 UIView 中心之间添加线?

`IndexSet` 永远不会是空的?

使用 Date.ParseStrategy 将字符串解析为日期

如何在界面生成器中创建 UILayoutGuide?

更改日期 Select 器的文本 colored颜色

Swift if 语句 - 多个条件用逗号分隔?

在 Swift 中为 UIPickerView 设置默认值?

如何在 Swift 中重写 setter