2013-12-09 1 views
3

Это предложение было задано earlier, но первоначальному аферу не нужно было менять динамическое свойство, поэтому он ответил на свой вопрос, разоблачив его.Sprite Kit failing assertion: (typeA == b2_dynamicBody || typeB == b2_dynamicBody)

Я использую Sprite Kit в iOS7, и я хотел бы иметь возможность изменять динамическое свойство SKPhysicsBody во время выполнения. Первоначально я менял это в своем методе touchBegan:. Кто-то из форума 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; 
} 

}

Ошибка появляется в отладчик:

Assertion failed: (typeA == b2_dynamicBody || typeB == b2_dynamicBody), function SolveTOI, file /SourceCache/PhysicsKit/PhysicsKit-4.6/PhysicsKit/Box2D/Dynamics/b2World.cpp, line 670.

Я огляделась в другом месте, но это, кажется, к быть проблема с реализацией Sprite Kit (и покрытие) Box2D.

Может быть?

+0

попробуйте создать новое тело, заменяющее предыдущее, или, возможно, вам не нужно, чтобы оно было статичным, но вы не хотели бы, чтобы он сталкивался с чем-либо. В этом случае используйте категории контактов и установите гравитационную шкалу в 0, это будет иметь тот же эффект, что и статическое тело. В bix2d вы не можете изменить тело от статического к динамическому и наоборот, я думаю, что это одинаково для комплекта спрайтов. – LearnCocos2D

+0

Возможно, релевантно: http://www.box2d.org/forum/viewtopic.php?f=3&t=7643 https://code.google.com/p/box2d/source/detail?r=235 – iforce2d

ответ

8

Вы можете изменить свойство dynamic вперед и назад, однако вы должны быть очень осторожны, если используете обнаружение столкновения/контакта.

Во время столкновения/контакта между двумя телами утверждается, что хотя бы один из них должен быть динамическим телом. Если вы измените это свойство на НЕТ во время выполнения, а другое связанное с ним тело также статично (нединамично), и произойдет обратный вызов столкновения/контакта, он выкинет эту конкретную ошибку утверждения - контакт будет обнаружен между 2 статическими телами в середине -execution, который Box2d не нравится.

Возможный способ обхода трюк - работает для меня, даже непосредственно в didBeginContact: метода:

SKPhysicsBody *temp = node.physicsBody; 
temp.dynamic = NO; 
node.physicsBody = temp; 
+0

Действительно приятно , отлично работает! – Napolux

+0

+1 Я также заметил, что iOS 8 не жалуется на это, но iOS 7 делает. – KBog

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, вы можете использовать аналогичную логику, чтобы отключить это, пока вы манипулируете сценой прикосновениями.