【问题标题】:Spritekit remove physicsBodySpritekit 移除physicsBody
【发布时间】:2023-03-22 02:12:02
【问题描述】:

在带有 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];
    }
}

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

【问题讨论】:

  • 您不想移除汽车的物理车身?
  • 您是否将物理体单独存储在其他地方?将其设置为 nil 就足够了

标签: ios physics sprite-kit


【解决方案1】:

相关:Why are didBeginContact called multiple times?

您注意到SKPhysicsContactDelegate-didBeginContact: 被多次调用,尽管将物理体设置为 nil。这意味着在update cycle 中的单个物理模拟期间多个像素同时连接。

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

无论以下对同一循环中的 didBeginContact 调用没有影响:

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

我的解决方案如下:

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

_

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
}

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多