sprite kit collision detection with child sprite

馋奶兔 提交于 2020-01-02 15:55:12

问题


I'm trying to detect collisions between two sprites but I'm unable to do this with a child 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];

then I have collision detetion like this

- (void)checkCollisions {
[self.map enumerateChildNodesWithName:@"enemy"
usingBlock:^(SKNode *node, BOOL *stop){SKSpriteNode *enemy = (SKSpriteNode *)node;
if (CGRectIntersectsRect(enemy.frame, _object.frame)) {
[enemy removeFromParent];
}
}]; }

*This does not work!!! but if I use :

CGRectIntersectsRect(enemy.frame, self.player.frame)  

I can detect a collision with the main body. how do I do collision detection for a child of another sprite?


回答1:


The child node's position and frame property are relative to it's parent, which you need to account for in your code.

SKNode has two methods that can help you with converting the position of a given SKNode to/from the coordinate spaces of another node:

convertPoint:fromNode:
convertPoint:toNode:

You can use those to convert a SKNode's position property to another coordinate space. What you want to do is convert the _object's position to the coordinate space of the enemy or visa versa and then use a temporary CGRect with that new position for your CGRectIntersectsRect check.

Here's an example :

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
}

This code is assuming that your enemy and your player are in the same coordinate space. (have the same parent)




回答2:


This happens because _object is a child node for self.player, and enemy node is a child node for self.map node. Both nodes should have same parent if you want to compare their frames.

I suggest you to use Sprite Kit's built-in collision handling mechanism:

// 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


来源:https://stackoverflow.com/questions/21870605/sprite-kit-collision-detection-with-child-sprite

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!