Swift SpriteKit接触检查PhysicsBody内部

时间:2015-10-18 00:34:21

标签: swift sprite-kit skspritenode skphysicsbody

我正在开发PhysicsBody并遇到麻烦。 首先,如果可以使用PhysicsBody或仅使用像素检查,我现在不是真的。

问题是:联系人检查工作得很好但是如果一个节点在PhysicsBody内,它将无法看到它是否发生碰撞。 在图片中,它得到了很好的解释。

Picture 1: This works

Picture 2: This won't

一些想法如何运作? 也许PhysicsBody(绿线)填充SKNode?

这里有一些代码: (有些人解释说:如果Human在Object内移动并且被触摸是假的没有发生任何事情就可以了,但是如果Human被移动到Object内部并且被触摸将是True也没有发生任何事情,这是我的问题。)

    enum myContacts: UInt32 {
    case None   = 0
    case All    = 0xFFFFFFFF
    case Object  = 0b001
    case Human = 0b010
}

class whatever...{
    let Object = SKSpriteNode(imageNamed: "xyz")
    Object.position = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame))

    Object.physicsBody = SKPhysicsBody(circleOfRadius: Object.size.width/2)
    Object.physicsBody?.dynamic = true
    Object.physicsBody?.categoryBitMask = myContacts. Object.rawValue
    Object.physicsBody?.contactTestBitMask = myContacts.Human.rawValue
    Object.physicsBody?.collisionBitMask = 0
    Object.physicsBody?.usesPreciseCollisionDetection = true
    addChild(Object)

    let Human = SKSpriteNode(imageNamed: "zyx")
    Human.position = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame))

    Human.physicsBody = SKPhysicsBody(circleOfRadius: Human.size.width/2)
    Human.physicsBody?.dynamic = true
    Human.physicsBody?.categoryBitMask = myContacts. Human.rawValue
    Human.physicsBody?.contactTestBitMask = myContacts.Object.rawValue
    Human.physicsBody?.collisionBitMask = 0
    Human.physicsBody?.usesPreciseCollisionDetection = true
    addChild(Human)
}

func didBeginContact(contact: SKPhysicsContact) {
    if touched {
        let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
        switch contactMask {
        case myContacts.Object.rawValue | myContacts.Human.rawValue:
            print("Human touched")
        default:
            break
        }
    }
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    touched = true
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    touched = false
}

1 个答案:

答案 0 :(得分:0)

不确定我是否完全理解您的要求,但是如果您只是想在节点内部生成节点时检测到某个联系人&#34;采取&#34;通过另一个节点,此代码将起作用:

#import "GameScene.h"

static const uint32_t playerCategory     =  0x1 << 0;
static const uint32_t obstacleCategory   =  0x1 << 1;

@interface GameScene()<SKPhysicsContactDelegate>

@property (nonatomic, strong) SKSpriteNode *player;

@property (nonatomic, strong) SKSpriteNode *obstacle;

@end

@implementation GameScene

-(void)didMoveToView:(SKView *)view {
    /* Setup your scene here */

    self.physicsWorld.contactDelegate = self;

    [self initializeNodes];


}


-(void)initializeNodes{


    self.player =  [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(50,50)];

    self.player.name = @"player";

    self.player.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));

    self.player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.player.size];
    self.player.physicsBody.collisionBitMask = 0;
    self.player.physicsBody.categoryBitMask = playerCategory;
    self.player.physicsBody.affectedByGravity = NO;
    self.player.physicsBody.contactTestBitMask = obstacleCategory;

    self.player.zPosition = 10;

    [self addChild:self.player];


    self.obstacle =  [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:CGSizeMake(100,100)];

    self.obstacle.name = @"obstacle";

    self.obstacle.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));

    self.obstacle.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.obstacle.size];
    self.obstacle.physicsBody.collisionBitMask = 0;
    self.obstacle.physicsBody.categoryBitMask = obstacleCategory;
    self.obstacle.physicsBody.affectedByGravity = NO;
    self.obstacle.physicsBody.contactTestBitMask = playerCategory;

    self.obstacle.zPosition = 8;

    [self addChild:self.obstacle];

}





-(void)didBeginContact:(SKPhysicsContact *)contact{
    NSLog(@"Contact detected!");
}


-(void)update:(CFTimeInterval)currentTime {
    /* Called before each frame is rendered */
}

@end

在这里,一切都非常直接:

  • 我制作两个节点并为它们分配物理实体
  • 我将这两个节点放在同一位置
  • 结果,检测到联系

如果你复制&amp;粘贴此代码并运行它,您将在控制台中看到的信息是:&#34;已检测到联系人&#34;。

我猜这与第二张图片的情况相同(你说的是没有检测到联系)。

此外,如果您继续移动播放器(当播放器位于障碍物范围内时),则不会检测到其他联系人。玩家必须首先离开障碍物的界限。但是,您仍然可以检查allContactBodies方法的返回值,该方法返回当前正文(玩家物理机构)与之联系的SKPhysicsBody对象数组。