2013-11-24 3 views
2

Есть ли способ удалить из родителя SKSpriteNode, который имеет границы области?iOS SKSpriteNode - оставить экран

, например:

-(void)didBeginContact:(SKPhysicsContact *)contact 
{ 
    firstNode = (SKSpriteNode *)contact.bodyA.node; 
    if (firstNode.position.y<0) { 
     [firstNode removeFromParent]; 
    } 
} 

Просто мне точку в правильном направлении. Является ли это методом обновления перечислением путем проверки их исправлений или является их действием, которое вы можете применить. Я прошел через документации не могу найти его, но я бы подумал, что это будет легко осуществить, так как это экономит память

ответ

6

метод Update, где вы можете сделать это хорошо:

- (void)update:(NSTimeInterval)currentTime { 
    //remove any nodes named "yourNode" that make it off screen 
    [self enumerateChildNodesWithName:@"yourNode" usingBlock:^(SKNode *node, BOOL *stop) { 

     if (node.position.x < 0){ 
      [node removeFromParent]; 
     } 
    }]; 
} 

Хотя обратите внимание, что удаление узлов не гарантирует освобождение памяти!

+0

Действительно? Установил ли я узел нуль или что-то еще? – Mike

+0

Нет, удалить его должно быть достаточно. Но иногда другие факторы (которые могут быть трудно идентифицировать) могут привести к сохранению памяти, поэтому просто подумайте, что я бы упоминал об этом! – AndyOS

+1

Например, если у вас есть другие сильные ссылки на узел. Это похоже на стандартное управление памятью в Cocoa. – swilliams

2

Вот как проверить, оставил ли узел какой-либо край экрана. В вашем цикле обновления выполните итерацию по всем дочерним объектам вашего слоя. Проверьте, имеет ли объект определенный тип. Затем проверьте, находится ли кадр узла вне каждого края экрана. Если так, вызовите removeFromParent. Обратите внимание: поскольку позиция узла находится в центре, вы хотите принять это во внимание.

-(void)update:(CFTimeInterval)currentTime 
{ 
    [_gameLayer.children enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) 
    { 
     if ([obj isKindOfClass:[MyNode class]]) 
     { 
      MyNode *myNode = (MyNode *)obj; 

      if (myNode.position.x + myNode.size.width/2 < 0 || 
       myNode.position.x - myNode.size.width/2 > self.size.width || 
       myNode.position.y + myNode.size.height/2 < 0 || 
       myNode.position.y - myNode.size.height/2 > self.size.height)   
      { 
       [myNode removeFromParent]; 
      } 
     } 
    }]; 
} 
0

Вы можете использовать эту функцию. Эта функция будет вызываться каждый кадр. (PS: Мой английский плох) -(void)didSimulatePhysics

1

Вы также можете обнаружить контакт с фоном SKSpriteNode и установить категорию для него. А потом, реализовать didEndContact: метод для удаления объекта

- (void)didEndContact:(SKPhysicsContact *)contact 
{ 
    //Find out your object (Remember it could be bodyA or bodyB) and remove it here 
} 
+0

Лучший подход, если объект, который контактирует с краем дисплея, определенно покидает экран .. рано или поздно. У меня была проблема, что мои яйца могут частично покинуть экран и вернуться - из-за гравитации и контакта с другими шарами. [SKScene didEndContact:] вызывается в таком случае тоже. – HBublitz

0

Я предпочитаю обработку контактов. Контактное тестирование выполняется в каждом кадре точно так же, как обработка обновления :. Но обнаружение контакта путем сравнения бит (SKPhysicsBody.categoryBitMask) очень быстрое и легкое.

Мне нужно обнаружить и удалить шарики, которые покидают экран. Итак, я настраиваю невидимую границу как сцену physicalBody, которая достаточно велика, чтобы обнаружить шары, которые полностью покинули экран.

Если физикаBody. contact TestBitMask узла # 1 == PhysicsBody. Категория BitMask узла №2 затем сделалBeginContact: вызывается, когда оба из них вступают в контакт.

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

    // bitmasks: 
    static uint32_t const categoryBitMaskBall = 0x1<<1; 
    static uint32_t const categoryBitMaskBorder = 0x1<<6; 

    CGFloat ballDiameter = [BallSprite radius] *2; 

    // floorShape is my scenes background 
    CGRect largeFloorFrame = floorShape.frame; 
    largeFloorFrame.origin.x -= ballDiameter; 
    largeFloorFrame.origin.y -= ballDiameter; 
    largeFloorFrame.size.width += ballDiameter *2; 
    largeFloorFrame.size.height += ballDiameter *2; 

    CGPathRef pathMainView = CGPathCreateWithRect(largeFloorFrame, nil); 
    self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromPath:pathMainView]; 
    self.physicsBody.categoryBitMask = categoryBitMaskBorder; 
} 

- (BallSprite*)addBall { 

    // initialize ball with additional configuration... 
    BallSprite *ball = [BallSprite ballAtPoint:(CGPoint)p]; 
    ball.categoryBitMask = categoryBitMaskBall; 
    ball.contactTestBitMask = categoryBitMaskBorder; 
    [self addChild:ball]; 
} 


- (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; 
    } 

    /*! 
     Check on outside border contact 
    */ 
    if ((firstBody.categoryBitMask & categoryBitMaskBall) != 0 && 
     (secondBody.categoryBitMask & categoryBitMaskBorder) != 0) { 

     [firstBody.node removeFromParent]; 
} 
    if ((firstBody.categoryBitMask & categoryBitMaskBorder) != 0 && 
     (secondBody.categoryBitMask & categoryBitMaskBall) != 0) { 

     [secondBody.node removeFromParent]; 
    } 
} 
0

Swift версия

self.enumerateChildNodesWithName("enemy") { 
node, stop in 

if (node.position.x < 0) { 
    node.removeFromParent() 
} 

} 
Смежные вопросы