我对物理身体有问题。我有大约 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 较低。物理身体什么时候关闭,一切都好。所以我有一个简单的问题。如何在游戏开始后为所有 20 个节点设置物理主体,而不仅仅是在不再次创建物理体的情况下生成它们。我尝试将带有纹理的物理主体直接设置为 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)
}
我已经编辑了答案以反映您的生成代码。请注意,我只是通过检查对象的隐藏状态来检查数组中的对象是否已被使用。还有许多其他方法可以检查对象是否已被使用,但您必须找出最适合您的方法。