¿Cómo eliminar correctamente el nodo cuando se sale de los límites de la pantalla?

Estoy trabajando en un juego de sprite-kit donde los nodos se generan por debajo del punto más bajo de la pantalla y la gravedad está configurada para que floten en la parte superior de la pantalla. Todo funciona a la perfección, pero rápidamente comienza a ralentizar el FPS, y eventualmente los retrasos y fallos se vuelven muy lentamente. Pensé que la forma de resolver esto habría sido eliminar los nodos del padre después de haber superado un punto, este era el código que usé en la actualización:

-(void)update:(CFTimeInterval)currentTime { if (_bubble1.position.y > CGRectGetMaxX(self.frame)+40) { [self removeFromParent]; } } 

Y en caso de que sea necesario, así es como initWithSize dicha burbuja debajo del método 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], ]]]; } 

¿Cómo puedo hacer que los nodos se eliminen correctamente cuando salen de la pantalla? ¿Y cómo puedo mantener el FPS a una velocidad constante de 60 FPS?

¡¡Gracias por adelantado!!

Recomendaría usar la detección incorporada de contacto en spritekit. Cree un skspritenode que imite un techo que tenga un cuerpo de física configurado para detectar el contacto con burbujas. Cree un evento en contacto entre el nodo del techo y el nodo de burbuja que simplemente eliminará las burbujas. Esto asegurará que se eliminen las burbujas y se mantenga un FPS constante.

Ejemplo de evento llamado a contacto:

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

Ejemplo de detección de contacto:

 - (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 necesita:

  _bubble.physicsBody.contactTestBitMask = roofCategory; 

Techo:

 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]; 

1 / physicsBody propiedad physicsBody tu escena con el siguiente código:

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

2 / Crea máscaras de categoría para tu escena y tus nodos sprite:

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

3 / Establezca la categoryBitMask adecuada contactTestBitMask , collisionBitMask y contactTestBitMask para sus nodos de escena y sprite physicsBody :

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

Como ejemplo, la siguiente implementación de Swift SKScene muestra cómo eliminar todos los nodos de sprite que van más allá del marco de la escena:

 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.networkingColor(), 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 rendenetworking */ } }