如何在屏幕边界之外正确删除节点?

我正在开发一个精灵套件游戏,其中节点在屏幕最低点以下产生,重力设置为让它们浮动到屏幕的顶部。 一切都很完美,但它很快就开始放慢FPS,最终滞后和故障变得非常缓慢。 我认为解决这个问题的方法是在父节点经过一个点之后从父节点中删除节点,这是我在更新中使用的代码:

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

并且在需要的情况下,这是我在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], ]]]; } 

我怎样才能使节点在离开屏幕时正确处理? 我怎样才能保持60 FPS的恒定速率?

提前致谢!!

我build议在spritekit中使用内置的接触检测。 创build一个模仿屋顶的skspritenode,其中有一个物理机构用于检测与气泡的接触。 在屋顶节点和泡泡节点之间的联系中创build一个事件,它将简单地移除泡泡。 这将确保气泡被移除,并保持恒定的FPS。

联系方式的事件示例:

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

接触检测示例:

 - (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.physicsBody.contactTestBitMask = roofCategory; 

屋顶:

 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属性:

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

2 /为你的场景和你的精灵节点创build类别掩码:

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

3 /为您的场景和精灵节点设置适当的categoryBitMaskcollisionBitMaskcontactTestBitMask physicsBody属性:

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

作为一个例子,下面的Swift SKScene实现展示了如何去除超出场景框架的所有精灵节点:

 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 */ } }