繁体   English   中英

Spritekit删除PhysicsBody

[英]Spritekit remove physicsBody

在带有SpriteKit的IOS 7中,如何仅移除物理物体,而将节点保留在场景中? 我试图让碰撞发生,然后让汽车演员砸破障碍墙。

for (SKSpriteNode *node in _obstacles)
{
    node.position = CGPointMake(node.position.x - 2, node.position.y);

    if( [_car intersectsNode: node] && node.physicsBody.collisionBitMask == 0)
    {
        NSLog(@"We have a hit!");
        _lives--;

        //prevent simultaneous hit
        node.physicsBody.collisionBitMask = 1;
        node.physicsBody.contactTestBitMask = 1;
        node.physicsBody.dynamic = NO;

        node.physicsBody = nil;

       // [removeRequired addObject:node];
        //flash the car to show momentary invuln

        if(_lives <= 0)
        {
            _gameOver = YES;
        }
    }
    else if( (node.position.x + (node.size.width / 2)) < 0)
    {
        [removeRequired addObject:node];
    }
}

但是删除似乎没有受到尊重。 我可以看到发生了多次点击(作为参考,此代码从update方法中调用。

相关: 为什么BeginContact被多次调用?

如您所见,尽管将物理主体设置为nil,但仍多次调用SKPhysicsContactDelegate-didBeginContact:。 这意味着在更新周期的单个物理模拟过程中,多个像素同时连接。

我相信SKNode-physicsBody已在循环中被复制以进行评估,您所做的任何更改都不会兑现,直到下一次物理模拟。 引擎还可能认为联系是同时发生的,并且didBeginContact调用已经排队。

无论如何,以下内容对于同一周期内的didBeginContact调用均无效:

node.physicsBody.categoryBitMask = 0
node.physicsBody.contactTestBitMask = 0
node.physicsBody.collisionBitMask = 0
node.physicsBody = nil;

我的解决方案如下:

  • 在第一个didBeginContact中将planetNode.physicsBody设置为nil
  • 仅对具有非零节点属性的PhysicalBodies做出反应

_

func didBeginContact(contact: SKPhysicsContact) {
  if let planetNode = getNodeFromContact(contact, categoryBitMask: PhysicsCategory.Planet) {
    NSLog("Planet hit")
    if let physicsBody = planetNode.physicsBody {
      physicsBody.contactTestBitMask = PhysicsCategory.None
    }
    planetNode.physicsBody = nil
    planetNode.addChild(NodeFactory.explosion())
    planetNode.runAction(SKAction.fadeOutWithDuration(0.5))

    if let shipNode = getNodeFromContact(contact, categoryBitMask: PhysicsCategory.Ship) {
      NSLog("Ship hit")
      shipNode.runAction(actionBlink())
    }
  }
}

func getNodeFromContact(contact: SKPhysicsContact, categoryBitMask: UInt32) -> SKNode? {
  if (contact.bodyA.categoryBitMask & categoryBitMask) > 0 {
    return contact.bodyA.node;
  } else if (contact.bodyB.categoryBitMask & categoryBitMask) > 0 {
    return contact.bodyB.node;
  }
  return nil
}

您可以在与刚碰撞的汽车相同的位置添加一个没有PhysicalBody的新节点,该节点具有所有相同的值(纹理,速度等),然后简单地移除碰撞的汽车。 换一个。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM