ios - 如何在生成的 spritekit 节点上设置 physicsBody

标签 ios swift xcode sprite-kit skphysicsbody

我的物理体有问题。我有大约 20 个随机生成的节点可供查看。每次节点生成时,我都会设置对象的物理特性,如下所示:

func showObject(){
    let texture =  SKTexture(imageNamed: "A.png")
    object = SKSpriteNode(texture: texture)
        object.name = "A"
    object.position = CGPoint(x: 0, y: self.frame.width)
    object.setScale(0.7)
    object.zPosition = 2
    object.run(moveAndRemove)

    object.physicsBody = SKPhysicsBody(texture: texture, size: texture.size())
    object.physicsBody?.categoryBitMask = PhysicsCategory.Object
    object.physicsBody?.collisionBitMask = PhysicsCategory.Object2
    object.physicsBody?.contactTestBitMask = PhysicsCategory.Object2
    object.physicsBody?.affectedByGravity = false
    object.physicsBody?.isDynamic = true

    addChild(object)
}

我认为这不是最优的,因为每次生成节点时都会设置 physicsBody。因此,我有时会出现轻微的闪烁 - 应用程序运行时会降低 fps。 physicsBody什么时候关闭,一切正常。所以我有一个简单的问题。如何在游戏开始后为所有 20 个节点设置物理体,而不是仅仅生成它们而不再次创建 physicsBody。我尝试将带有纹理的物理体直接设置为 SKView,但在此之后,应用程序崩溃并出现零错误。

感谢任何提示。

这是我的产卵:

let SpawnObject = SKAction.run({
    () in

    let randomFunc = [self.showObject, self.showObject1.......]
        let randomResult = Int(arc4random_uniform(UInt32(randomFunc.count)))
        randomFunc[randomResult]()
})

let delay1 = SKAction.wait(forDuration: 0.9)
let SpawnDelay1 = SKAction.sequence([SpawnObject,delay1])
let SpawnDelayForever1 = SKAction.repeatForever(SpawnDelay1)
self.run(SpawnDelayForever1)

let distance = CGFloat(self.frame.height + 200)
let moveObject = SKAction.moveBy(x: -distance, y: 0, duration: TimeInterval(0.004 * distance))
let removeObject = SKAction.removeFromParent()
moveAndRemove = SKAction.sequence([moveObject,removeObject])

最佳答案

有很多不同的方法可以解决这个问题,如果我生成多个相同的对象,我喜欢做的是将对象预加载到一个数组中,然后在需要时从数组中拉出它们,当你完成对象后,您可以将它们从场景中移除,但将它们保留在数组中。然后您可以再次使用该对象,而不必重新创建它,也不必重新创建导致延迟的物理体

private var moveAndRemove = SKAction()
private var objects = [SKSpriteNode]()
private let objectCount = 20

override func didMove(to view: SKView) {

    for x in 0..<objectCount {
        let texture =  SKTexture(imageNamed: "A")
        let object = SKSpriteNode(texture: texture)
        object.name = "A"
        object.isHidden = true
        object.setScale(0.7)
        object.zPosition = 2

        object.physicsBody = SKPhysicsBody(texture: texture, size: texture.size())
        object.physicsBody?.categoryBitMask = 0
        object.physicsBody?.collisionBitMask = 0
        object.physicsBody?.contactTestBitMask = 0
        object.physicsBody?.affectedByGravity = false
        object.physicsBody?.isDynamic = true

        objects.append(object)
    }

    let distance = CGFloat(self.frame.height + 200)
    let moveObject = SKAction.moveBy(x:0 - distance, y: 0, duration: Double(0.004 * distance))
    let removeObject = SKAction.removeFromParent()
    let hideObject = SKAction.hide()
    moveAndRemove = SKAction.sequence([moveObject, hideObject, removeObject])

    let SpawnObject = SKAction.run( {

        let randomResult = Int(arc4random_uniform(UInt32(self.objects.count)))
        self.showObject(objectIndex: randomResult)
    })

    let delay1 = SKAction.wait(forDuration: 0.9)
    let SpawnDelay1 = SKAction.sequence([SpawnObject, delay1])
    let SpawnDelayForever1 = SKAction.repeatForever(SpawnDelay1)
    self.run(SpawnDelayForever1)
}

func showObject(objectIndex: Int) {

    let object = objects[objectIndex]

    guard object.isHidden == true else { return }

    object.isHidden = false
    object.position = CGPoint(x: 0, y: self.frame.width)
    object.zPosition = 10000
    addChild(object)
    object.run(moveAndRemove)
}

我已经编辑了答案以反射(reflect)您的生成代码。请注意,我只是通过检查对象的隐藏状态来检查数组中的对象是否已被使用。有许多其他方法可以检查对象是否已被使用,但您必须找出最适合您的方法。

关于ios - 如何在生成的 spritekit 节点上设置 physicsBody,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42817670/

相关文章:

json - 如何使用 Codable 协议(protocol)解析带有自定义参数的 JSON

swift - 需要帮助添加多个保护语句来检查字符数

ios - Swift 5.1 运行时如何与旧版本的 iOS 一起工作?

iphone - 更改设备时 iOS 模拟器无法正确运行应用程序

Xcode 11 - "Couldn' t 与辅助应用程序通信。”尝试添加 Swift 包时

ios - 使用 Swift 从 Firebase 中删除整个子项

iphone - 无法在 Instruments : At least one target failed to launch 中启动我的应用程序

ios - Swift:彩虹色环

ios - 为什么DispatchGroup会干扰主队列?

ios - UIButton _setTitleFrozen 崩溃