与子sprite的精灵套件碰撞检测
我试图检测两个精灵之间的冲突,但我无法做到这一点与一个孩子精灵。
self.player = [[Player alloc] initWithImageNamed:@"player"]; self.player.position = CGPointMake(150, 75); [self addChild:self.player]; _object = [SKSpriteNode spriteNodeWithImageNamed:@"object"]; _object.position = CGPointMake(-40, 27); [self.player addChild:_object];
那么我有这样的碰撞检测
- (void)checkCollisions { [self.map enumerateChildNodesWithName:@"enemy" usingBlock:^(SKNode *node, BOOL *stop){SKSpriteNode *enemy = (SKSpriteNode *)node; if (CGRectIntersectsRect(enemy.frame, _object.frame)) { [enemy removeFromParent]; } }]; }
*这不起作用! 但如果我使用:
CGRectIntersectsRect(enemy.frame, self.player.frame)
我可以检测到与主体的碰撞。 如何为另一个精灵的孩子做碰撞检测?
子节点的position
和frame
属性是相对于parent
,您需要在代码中进行说明。
SKNode
有两种方法可以帮助您将给定SKNode
的position
转换为另一个节点的坐标空间:
convertPoint:fromNode: convertPoint:toNode:
您可以使用这些将SKNode
的position
属性转换为另一个坐标空间。 你想要做的就是把_object
的位置转换成敌人的坐标空间,或者反过来,然后用CGRectIntersectsRect
这个新位置的临时CGRect
来检查。
这是一个例子:
CGPoint globalPosition = [self.player convertPoint:_object.position toNode:self.player.parent]; CGRect tempRect = CGRectMake(globalPosition.x, globalPosition.y, _object.frame.size.width, _object.frame.size.height); if (CGRectIntersectsRect(enemy.frame, _object.frame)) { // collision occurred }
这个代码假设你的敌人和你的玩家在同一个坐标空间。 (有相同的父母)
发生这种情况是因为self.player
是self.player
的子节点,而enemy
节点是self.map
节点的子节点。 如果你想比较它们的帧,两个节点应该有相同的父节点。
我build议你使用Sprite Kit的内置碰撞处理机制:
// Object: _object = [SKSpriteNode spriteNodeWithImageNamed:@"object"]; _object.position = CGPointMake(-40, 27); _object.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_object.frame.size; _object.physicsBody.categoryBitMask = OBJECT_CATEGORY; _object.physicsBody.contactTestBitMask = ENEMY_CATEGORY; _object.physicsBody.collisionBitMask = 0; [self.player addChild:_object]; // Enemy: // init enemy: SKSpriteNode *enemy = [SKSpriteNode spriteNodeWithImageNamed:@"enemy"]; enemy.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:enemy.frame.size; enemy.physicsBody.categoryBitMask = ENEMY_CATEGORY; enemy.physicsBody.contactTestBitMask = OBJECT_CATEGORY; enemy.physicsBody.collisionBitMask = 0; // add enemy to the scene: [self addChild:enemy]; // Define that your SKScene conforms to SKPhysicsContactDelegate protocol: ..... @interface MyScene : SKScene <SKPhysicsContactDelegate> .... // SKScene.m: static uint32_t const OBJECT_CATEGORY = 0x1 << 0; static uint32_t const ENEMY_CATEGORY = 0x1 << 1; @implementation MyScene - (id)initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { ....... self.physicsWorld.contactDelegate = self; ........ } return self; } ....... - (void)didBeginContact:(SKPhysicsContact *)contact{ SKPhysicsBody *firstBody, *secondBody; if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask) { firstBody = contact.bodyA; secondBody = contact.bodyB; } else { firstBody = contact.bodyB; secondBody = contact.bodyA; } if (((firstBody.categoryBitMask & OBJECT_CATEGORY) != 0) && (secondBody.categoryBitMask & ENEMY_CATEGORY) != 0) { NSLog(@"Collision detected!"); } @end