2017-03-15 1 views
1

Ich habe ein Problem mit Physikkörper. Ich habe ungefähr 20 Knoten, die nach dem Zufallsprinzip zum Ansehen kommen. Jedes Mal, wenn der Knoten laicht stelle ich die Physik des Objekts, wie folgt aus:Wie man physicsBody auf dem Laichen von spritekitnodes setzt

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) 
} 

Ich denke, das ist nicht optimal, weil physicsBody jedes Mal gesetzt, wenn der Knoten hervorgebracht wird. Aus diesem Grund habe ich manchmal wenig Flimmern - niedrigere fps wenn App läuft. Wenn physicsBody ausgeschaltet ist, ist alles in Ordnung. Ich habe eine einfache Frage. Wie stelle ich den Physikkörper für alle 20 Knoten nach dem Spielstart ein und spawne sie einfach, ohne physicsBody neu zu erstellen. Ich versuche, Physikkörper mit Textur direkt zu SKView zu setzen, aber danach stürzt app mit Nullfehler ab.

Danke für jeden Tipp.

Es ist mein Laich:

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]) 
+0

Beim Laichen wird der physicBody neu gezeichnet, sogar für diejenigen, die Sie zuvor erstellt haben. Eine Möglichkeit, dies zu tun, besteht darin, sie NICHT aus der Szene zu entfernen, sondern sie vom Bildschirm wegzubewegen, damit der Benutzer sie nicht sehen kann. Wenn Sie sie wieder benötigen, verschieben Sie sie zurück auf den Bildschirm. –

Antwort

2

Es gibt viele verschiedene Möglichkeiten, wie Sie zu diesem gehen könnte, was ich tun, wenn ich mehrere des gleichen Objektes am Laichen wird die Objekte in einem Array Vorspannung und die ziehe sie aus dem Array, wie ich sie brauche, wenn du mit dem Objekt fertig bist, kannst du sie aus der Szene entfernen, aber sie im Array behalten. Sie können dann wieder das Objekt verwenden, ohne sie neu erstellen zu müssen und ohne die Physik Körper neu erstellen die Verzögerung verursacht

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) 
} 

ich die Antwort bearbeitet haben Ihre Laich Code zu reflektieren. Bitte beachten Sie, dass ich nur überprüfe, ob das Objekt im Array bereits verwendet wurde, indem ich den versteckten Status des Objekts überprüfe. Es gibt viele andere Möglichkeiten zu überprüfen, ob das Objekt verwendet wurde, aber Sie müssen herausfinden, was am besten für Sie funktioniert.

+0

Kann ich Ihre Lösung auf diese Spawn-Funktion anwenden? –

+0

ja, erzeuge sie einfach wie in didMove func, aber füge sie nicht der Szene hinzu (oder füge sie der Szene hinzu, außer Sichtweite). Dann, wenn Sie einen brauchen, ziehen Sie ihn einfach aus dem Array von Objekten (wenn Sie sie noch nicht zur Szene hinzugefügt haben, müssten Sie an dieser Stelle). Diese –

+0

ist der Laich Code 'lassen SpawnObject = SKAction.run ({ () in showobject() }) lassen delay1 = SKAction.wait (forDuration: 0,9) lassen SpawnDelay1 = SKAction.sequence ([ SpawnObject, DELAY1]) lassen SpawnDelayForever1 = SKAction.repeatForever (SpawnDelay1) self.run (SpawnDelayForever1) let distance = CGFloat (self.frame.height + 200) lassen moveobject = SKAction.moveBy (x: -Entfernung, y: 0, Dauer: TimeInterval (0.004 * distance)) let removeObject = SKAction.removeFromParent() moveAndRemove = SKAction.sequence ([moveObject, removeObject]) ' –

Verwandte Themen