3

これは以前に質問されましたが、元の質問者は動的プロパティを変更する必要がなかったため、質問を解除して自分の質問に答えました。

iOS7 でスプライト キットを使用しています。実行時に SKPhysicsBody の動的プロパティを変更できるようにしたいと考えています。もともと私は touchesBegan: メソッドでそれを変更していました。Apple Dev フォーラムの誰かが変更を didSimulatePhysics: メソッドに移すことを提案しましたが、それも役に立ちませんでした。

このコードはエラーを引き起こします:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
  if (!heyWereSwappingDynamismHere) 
  {
    heyWereSwappingDynamismHere = YES;
    SKNode * rope = [self childNodeWithName:@"rope"];
    SKNode * anchor = [rope childNodeWithName:@"anchor"];
    [listOfObjectsToSwapDynamic addObject:anchor];
  }
}

-(void) didSimulatePhysics 
{
  if (heyWereSwappingDynamismHere) 
  {
    for (SKNode * node in listOfObjectsToSwapDynamic) 
    {
        bool isItDynamic = node.physicsBody.isDynamic;
        node.physicsBody.dynamic = !isItDynamic;
    }
    [listOfObjectsToSwapDynamic removeAllObjects];
    heyWereSwappingDynamismHere = NO;
}

}

デバッガーに表示されるエラーは次のとおりです。

アサーションに失敗しました: (typeA == b2_dynamicBody || typeB == b2_dynamicBody)、関数 SolveTOI、ファイル /SourceCache/PhysicsKit/PhysicsKit-4.6/PhysicsKit/Box2D/Dynamics/b2World.cpp、行 670。

私は他の場所を見回しましたが、これは Sprite Kit の Box2D の実装 (およびカバー) に問題があるようです。

多分?

4

2 に答える 2

8

dynamicプロパティは前後に変更できますが、衝突/接触検出を使用している場合は十分に注意する必要があります。

2 つのボディ間の衝突/接触中に、それらの少なくとも 1 つが動的ボディでなければならないことがアサートされます。実行時にそのプロパティを NO に変更し、接触した他のボディも静的 (非動的) で、衝突/接触コールバックが発生している場合、この特定のアサーション エラーがスローされます - 中間の​​ 2 つの静的ボディ間で接触が検出されます。 -Box2d が楽しめない実行。

didBeginContact:可能な回避策のトリック-メソッドで直接でも、私にとってはうまくいきます:

SKPhysicsBody *temp = node.physicsBody;
temp.dynamic = NO;
node.physicsBody = temp;
于 2014-01-19T18:23:58.840 に答える
0

元の投稿者の意図が、SKNode を直接操作しながら衝突を無効にすることである場合、次のように実行できます。

@property (nonatomic, strong) SKNode *node;
@property (nonatomic, assign) uint32_t previousCollisionBitMask;

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  // Disable collisions & gravity
  self.previousCollisionBitMask = self.node.physicsBody.collisionBitMask;
  self.node.physicsBody.collisionBitMask = 0;
  self.node.physicsBody.affectedByGravity = NO;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  // Enable collisions & gravity
  self.node.physicsBody.collisionBitMask = self.previousCollisionBitMask;
  self.node.physicsBody.affectedByGravity = YES;
}

これにより、オブジェクトが衝突の計算から除外されます。重力を無効にすると、移動中にオブジェクトが落下しなくなります。

contactTextBitMask についても懸念がある場合は、同様のロジックを使用して、タッチでシーンを操作しているときにそれを無効にすることができます。

于 2014-02-24T23:35:34.740 に答える