Ios 当超出屏幕边界时,如何正确删除节点?

Ios 当超出屏幕边界时,如何正确删除节点?,ios,objective-c,xcode,sprite-kit,Ios,Objective C,Xcode,Sprite Kit,我正在制作一个精灵套件游戏,其中节点在屏幕最低点下方生成,重力设置为使它们浮到屏幕顶部。一切工作都很完美,但它很快开始减慢FPS,并最终变得非常缓慢。我认为解决这个问题的方法是在节点超过某个点后从父节点中删除节点,这是我在更新中使用的代码: -(void)update:(CFTimeInterval)currentTime { if (_bubble1.position.y > CGRectGetMaxX(self.frame)+40) { [self remov

我正在制作一个精灵套件游戏,其中节点在屏幕最低点下方生成,重力设置为使它们浮到屏幕顶部。一切工作都很完美,但它很快开始减慢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帧的恒定速率?


提前谢谢

我建议在spritekit中使用内置的触点检测。创建一个模拟屋顶的skspritenode,该屋顶的物理主体设置为检测与气泡的接触。在屋顶节点和气泡节点之间创建一个接触事件,该事件将仅删除气泡。这将确保气泡被清除,并保持恒定的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];
}}
屋顶:


使用Swift 1.1/iOS 8,您可以使用以下模式来解决问题


1。使用以下代码初始化场景的
physicsBody
属性:

physicsBody = SKPhysicsBody(edgeLoopFromRect: frame) // or CGRectInset(frame, -10, -10) if you need insets 
let boundaryCategoryMask: UInt32 =  0x1 << 1
let someNodeCategoryMask: UInt32 =  0x1 << 2
// Scene
physicsBody!.categoryBitMask = boundaryCategoryMask

// Sprite node
/* ... */
someNode.physicsBody!.categoryBitMask = someNodeCategoryMask
someNode.physicsBody!.contactTestBitMask = boundaryCategoryMask 
2。为场景和精灵节点创建类别遮罩:

physicsBody = SKPhysicsBody(edgeLoopFromRect: frame) // or CGRectInset(frame, -10, -10) if you need insets 
let boundaryCategoryMask: UInt32 =  0x1 << 1
let someNodeCategoryMask: UInt32 =  0x1 << 2
// Scene
physicsBody!.categoryBitMask = boundaryCategoryMask

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

例如,以下场景实现演示了如何删除超出场景帧的所有精灵节点:

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

}
类游戏场景:SKScene,skphysiccontactdelegate{

让boundaryCategoryMask:UInt32=0x1“FPS”只与节点数量有松散的关系。其他因素将对此有更大的影响。真的吗?!就像@BradAllredYou只有一个气泡ivar,以后您需要使用数组来访问所有气泡。使用更新代码,您将只能删除最后创建的气泡。您可以更轻松地运行每个气泡一种自定义操作,经常检查其位置,必要时调用removeFromParent。