关注RayWenderlich tutorial我遇到了一些问题,无法创建一个让子弹弹回的块。但最令人讨厌的事情是无法检测到子弹和砖块之间的碰撞。现在,子弹就像它不存在一样通过砖块。
这是子弹和砖的定义: 子弹:
bullet = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:kBulletSize];
bullet.name = kShipFiredBulletName;
bullet.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bullet.frame.size];
bullet.physicsBody.dynamic = YES;
bullet.physicsBody.restitution = 1.0;
bullet.physicsBody.affectedByGravity = NO;
bullet.physicsBody.categoryBitMask = kShipFiredBulletCategory;
bullet.physicsBody.contactTestBitMask = kInvaderCategory;
bullet.physicsBody.collisionBitMask = 0x0;
砖:
SKNode* rebote;
rebote = [SKSpriteNode spriteNodeWithColor:[SKColor orangeColor] size:kBouncetSize];
rebote.position = CGPointMake(550, 500);
rebote.name = @"kBounceBlock";
rebote.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:rebote.frame.size];
rebote.physicsBody.restitution = 1.0;
rebote.physicsBody.friction = 0.0;
rebote.physicsBody.dynamic = NO;
rebote.physicsBody.affectedByGravity = YES;
rebote.physicsBody.categoryBitMask = kShipFiredBulletCategory;
rebote.physicsBody.contactTestBitMask = kInvaderCategory;
rebote.physicsBody.collisionBitMask = 0x0;
[self addChild:rebote];
这里是碰撞检测方法:
-(void)handleContact:(SKPhysicsContact*)contact
{
// Ensure you haven't already handled this contact and removed its nodes
if (!contact.bodyA.node.parent || !contact.bodyB.node.parent)
return;
NSArray* nodeNames = @[contact.bodyA.node.name, contact.bodyB.node.name];
if ([nodeNames containsObject:kShipName] && [nodeNames containsObject:kInvaderFiredBulletName])
{
// Invader bullet hit a ship
[self runAction:[SKAction playSoundFileNamed:@"ShipHit.wav" waitForCompletion:NO]];
//1
[self adjustShipHealthBy:-0.334f];
if (self.shipHealth <= 0.0f)
{
//2
[contact.bodyA.node removeFromParent];
[contact.bodyB.node removeFromParent];
}
else
{
//3
SKNode* ship = [self childNodeWithName:kShipName];
ship.alpha = self.shipHealth;
if (contact.bodyA.node == ship)
[contact.bodyB.node removeFromParent];
else
[contact.bodyA.node removeFromParent];
}
}
else if ([nodeNames containsObject:kInvaderName] && [nodeNames containsObject:kShipFiredBulletName])
{
NSLog(@"Contacto entre bala e Invader.");
// Ship bullet hit an invader
[self runAction:[SKAction playSoundFileNamed:@"InvaderHit.wav" waitForCompletion:NO]];
[contact.bodyA.node removeFromParent];
[contact.bodyB.node removeFromParent];
//4
[self adjustScoreBy:100];
}
if ([nodeNames containsObject:@"kBounceBlock"])
NSLog(@"Contacto entre el cuerpo naranja !!");
}
但是我做错了?我在子弹和砖块中定义了恢复属性。砖块不是动态的,两者都在相同的'collisionBitMask'中。
我很丢失。 提前致谢
答案 0 :(得分:4)
为contactTestBitMask
和collisionBitMask
设置正确的Brick
和Bullet
。
由于某些原因,您将collisionBitMask
设置为0x0
,这意味着该节点根本不会与任何对象发生冲突。
另外,您为categoryBitMask
指定了错误的Brick
(与Bullet
相同)。您应该为它创建一个单独的类别:
bullet.physicsBody.categoryBitMask = kShipFiredBulletCategory;
bullet.physicsBody.contactTestBitMask = kBrickCategory;
bullet.physicsBody.collisionBitMask = kBrickCategory;
rebote.physicsBody.categoryBitMask = kBrickCategory;
rebote.physicsBody.contactTestBitMask = kShipFiredBulletCategory;
rebote.physicsBody.collisionBitMask = kShipFiredBulletCategory;
答案 1 :(得分:2)
categoryBitMask
是指定节点“所属”的类别(或类别)的位置。 contactTestBitMask
是让节点知道在与它们发生碰撞时应该触发-handleContact:
的其他节点的地方。
您将两个节点都放在contactTestBitMask
kInvaderCategory
之上。这意味着如果这些节点中的任何一个与categoryBitMask
kInvaderCategory
的节点发生冲突,则会调用其-handleContact:
方法。但是,您的节点都没有categoryBitMask
kInvaderCategory
,因此永远不会发生。
例如,如果您要为rebote
节点contactTestBitMask
kShipFiredBulletCategory
提供-handleContact:
,那么每当bullet
节点发生碰撞时,它都会调用bullet
使用它,因为categoryBitMask
节点的kShipFiredBulletCategory
为{{1}}。