2014-06-11 21 views
9

Sto lavorando a un gioco di sprite-kit in cui i nodi si generano sotto il punto più basso dello schermo e la gravità è impostata per farli galleggiare nella parte superiore dello schermo. Tutto funziona perfettamente, ma inizia rapidamente a rallentare l'FPS, e alla fine i ritardi e le anomalie diventano molto lentamente. Ho pensato che il modo per risolvere questo sarebbe stato per rimuovere i nodi dal genitore dopo che avevano passato un punto, questo è stato il codice che ho usato nell'aggiornamento:Come rimuovere correttamente il nodo fuori dai limiti dello schermo?

-(void)update:(CFTimeInterval)currentTime { 

    if (_bubble1.position.y > CGRectGetMaxX(self.frame)+40) { 
     [self removeFromParent]; 
    } 

} 

E in caso di necessità, questo Ecco come ho generato detto bolla di seguito il metodo initWithSize:

-(void)didMoveToView:(SKView *)view { 

    [self performSelector:@selector(spawnBubbles) withObject:nil afterDelay:1.0]; 
    [self performSelector:@selector(spawnBubbles1) withObject:nil afterDelay:1.5]; 

} 

-(void)spawnBubbles { 
    randomPosition = arc4random() %260*DoubleIfIpad; 
    randomPosition = randomPosition + 20*DoubleIfIpad; 

    randomNumber = arc4random() %7; 
    randomNumber = randomNumber + 1; 

    myColorArray = [[NSArray alloc] initWithObjects:colorCombo1, colorCombo2, colorCombo3, colorCombo4, colorCombo5, colorCombo6, colorCombo7, colorCombo8, nil]; 
    myRandomColor = [myColorArray objectAtIndex:randomNumber]; 

    _bubble1 = [SKShapeNode node]; 
    [_bubble1 setPath:CGPathCreateWithEllipseInRect(CGRectMake(-25*DoubleIfIpad, -25*DoubleIfIpad, 50*DoubleIfIpad, 50*DoubleIfIpad), nil)]; 
    _bubble1.strokeColor = _bubble1.fillColor = myRandomColor; 
    _bubble1.position = CGPointMake(randomPosition, CGRectGetMinY(self.frame)-60); 
    _bubble1.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:20]; 
    _bubble1.physicsBody.categoryBitMask = CollisionBubble; 

    [self addChild:_bubble1]; 

    [self runAction:[SKAction sequence:@[ 
             [SKAction waitForDuration:1.0], 
             [SKAction performSelector:@selector(spawnBubbles) onTarget:self], 
             ]]]; 

} 

Come posso fare in modo che i nodi vengono smaltite correttamente quando lasciano lo schermo? E come posso mantenere il FPS ad un tasso costante di 60 FPS?

Grazie in anticipo !!

+1

"FPS" è in stretta relazione al numero di nodi. altri fattori contribuiranno a questo di più. –

+0

Realy ?! come cosa @BradAllred – user3576196

+0

Hai solo un bubble ivar, avresti bisogno di usare un array per accedere a tutti in seguito. Con il tuo codice di aggiornamento sarai solo in grado di rimuovere la bolla creata per ultima. Più facilmente puoi fare in modo che ogni bolla esegua un'azione personalizzata che controlli frequentemente la sua posizione e chiama removeFromParent quando necessario. – LearnCocos2D

risposta

12

Si consiglia di utilizzare il rilevamento dei contatti integrato in spritekit. Creare uno skspritenode che imita un tetto con un corpo fisico impostato per rilevare il contatto con le bolle. Crea un evento sul contatto tra il nodo del tetto e il nodo del fumetto che rimuoverà semplicemente le bolle. Ciò assicurerà che le bolle vengano rimosse e tu mantenga un FPS costante.

Esempio di evento chiamato a contatto:

- (void)bubble:(SKSpritenode*)bubble didCollideWithRoof:(SKSpriteNode*)roof{ 
[bubble removeFromParent];} 

esempio rilevamento di contatto:

- (void)didBeginContact:(SKPhysicsContact *)contact 
{ 
SKPhysicsBody *firstBody, *secondBody; 
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask) 
{ 
    firstBody = contact.bodyA; 
    secondBody = contact.bodyB; 
} 
else 
{ 
    firstBody = contact.bodyB; 
    secondBody = contact.bodyA; 
} 

if (firstBody.categoryBitMask==bubbleCategory && secondBody.categoryBitMask == roofCategory) 
{ 
    [self bubble:(SKSpriteNode*)firstBody.node didCollideWithRoof:(SKSpriteNode*)secondBody.node]; 
}} 

Bubble bisogno:

_bubble.physicsBody.contactTestBitMask = roofCategory; 

tetto:

SKSpriteNode *roof = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(self.scene.size.width, 1)]; 
roof.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(self.scene.size.width, 1)]; 

    roof.position = CGPointMake(self.scene.size.width/2,self.scene.size.height) 
    roof.physicsBody.dynamic = NO; 
    roof.physicsBody.categoryBitMask = floorCategory; 
    roof.physicsBody.contactTestBitMask = bubbleCategory; 
    [self addChild:roof]; 
4

1/init di proprietà della scena physicsBody con il seguente codice:

physicsBody = SKPhysicsBody(edgeLoopFromRect: frame) // or CGRectInset(frame, -10, -10) if you need insets 

2/creare maschere di categoria per la scena e i nodi sprite:

let boundaryCategoryMask: UInt32 = 0x1 << 1 
let someNodeCategoryMask: UInt32 = 0x1 << 2 

3/Impostare la corretta categoryBitMask, collisionBitMask e contactTestBitMask per i nodi di scena e sprite physicsBody proprietà:

// Scene 
physicsBody!.categoryBitMask = boundaryCategoryMask 

// Sprite node 
/* ... */ 
someNode.physicsBody!.categoryBitMask = someNodeCategoryMask 
someNode.physicsBody!.contactTestBitMask = boundaryCategoryMask 
.210

A titolo di esempio, la seguente implementazione Swift SKScene vi mostra come rimuovere tutti i nodi sprite che vanno al di là di telaio della vostra scena:

class GameScene: SKScene, SKPhysicsContactDelegate { 

    let boundaryCategoryMask: UInt32 = 0x1 << 1 
    let squareCategoryMask: UInt32 = 0x1 << 2 


    override func didMoveToView(view: SKView) { 
     // Scene 
     backgroundColor = SKColor.whiteColor() 
     physicsWorld.contactDelegate = self 
     physicsBody = SKPhysicsBody(edgeLoopFromRect: frame) 
     physicsBody!.categoryBitMask = boundaryCategoryMask 

     // Square 
     let square = SKSpriteNode(color: SKColor.redColor(), size: CGSize(width: 80, height: 80)) 
     square.zPosition = 0.1 
     square.position = CGPoint(x: size.width/2.0 - square.size.width/2, y: size.height - square.size.height) 
     square.physicsBody = SKPhysicsBody(rectangleOfSize: square.frame.size) 
     square.physicsBody!.dynamic = true 
     square.physicsBody!.affectedByGravity = true 
     square.physicsBody!.categoryBitMask = squareCategoryMask 
     // square.physicsBody!.collisionBitMask = 0 // don't set collisions (you don't want any collision) 
     square.physicsBody!.contactTestBitMask = boundaryCategoryMask // this will trigger -didBeginContact: and -didEndContact: 
     addChild(square) 
    } 

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { 
     // Check if the array containing the scene’s children is empty 
     println("children: \(children)") 
    } 

    func didBeginContact(contact: SKPhysicsContact) { 
     if contact.bodyA.categoryBitMask == squareCategoryMask { 
      contact.bodyA.node?.removeFromParent() 
      println("square removed") 
     } 

     if contact.bodyB.categoryBitMask == squareCategoryMask { 
      contact.bodyB.node?.removeFromParent() 
      println("square removed") 
     } 
    } 

    func didEndContact(contact: SKPhysicsContact) { 
     /* ... */ 
    } 

    override func update(currentTime: CFTimeInterval) { 
     /* Called before each frame is rendered */ 
    } 

} 
Problemi correlati