【问题标题】:Sprite Kit ignores contact sometimesSprite Kit 有时会忽略接触
【发布时间】:2014-08-19 11:00:36
【问题描述】:

各位开发者您好,

我是 Sprite Kit 的新手,刚刚开始在我的游戏中实现物理。我只有两个精灵需要接触。一个是主角,一只蝴蝶“bfly”,另一个是一个能量球,在接触时会给主角带来健康。

然而,在我的游戏中发生了一些奇怪的事情,尽管我实现了我所有的台词以使物理起作用,但有时,在某些我不理解的情况下,能量球直接穿过主角并忽略了这一点接触和接触工具应该发生的效果。然后我必须积极寻找能量球,让它发生并尝试多次触摸它才能成功。

我希望接触总是发生,无论能量是意外撞到我身上,还是我主动寻找它。当这两个精灵以任何方式相互接触时,就会发生接触。我尝试了一切,最后决定寻求帮助。

这是我的代表:

@interface CloudScene () <SKPhysicsContactDelegate>

请注意,我添加这些属性是为了解决问题,但问题就在它们之前:

@property(assign, nonatomic) uint32_t contactTestBitMask;
@property(nonatomic) BOOL usesPreciseCollisionDetection;

static const uint32_t bflyCategory = 0x1 << 0;
static const uint32_t energyCategory = 0x1 << 1;

initWithSize 方法:

self.physicsWorld.gravity = CGVectorMake(0, 0);
self.physicsWorld.contactDelegate = self;

两者的物理(注意碰撞之前设置为 0 并且问题仍然存在,我只是添加它们,希望弹跳效果至少不会让球直接穿过 bfly 角色但没有工作):

    _bfly.name = @"bflyNode";
    _bfly.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_bfly.frame.size];
    _bfly.physicsBody.categoryBitMask = bflyCategory;
    _bfly.physicsBody.contactTestBitMask = energyCategory;
    _bfly.physicsBody.collisionBitMask = bflyCategory | energyCategory;
    _bfly.physicsBody.usesPreciseCollisionDetection = YES;
    _bfly.physicsBody.dynamic = YES;
    _bfly.physicsBody.affectedByGravity = NO;
    _bfly.physicsBody.mass = 1;


energyball.name = @"energyballNode";
energyball.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:energyball.frame.size];
energyball.physicsBody.categoryBitMask = energyCategory;
energyball.physicsBody.contactTestBitMask = bflyCategory;
energyball.physicsBody.collisionBitMask = energyCategory | bflyCategory;
energyball.physicsBody.usesPreciseCollisionDetection = YES;
energyball.physicsBody.dynamic = YES;
energyball.physicsBody.affectedByGravity = NO;
energyball.physicsBody.mass = 1;

最后是我的 didBeginContact 方法:

-(void)didBeginContact:(SKPhysicsContact *)contact{

SKPhysicsBody *bfly;
SKPhysicsBody *energyball;

if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
    bfly = contact.bodyA;
    energyball = contact.bodyB;
}
else
{
    bfly = contact.bodyB;
    energyball = contact.bodyA;
}

if ((bfly.categoryBitMask & bflyCategory) != 0)
{

    SKNode * energyball = (contact.bodyA.categoryBitMask & bflyCategory) ? contact.bodyB.node : contact.bodyA.node;
    SKAction*energySound = [SKAction playSoundFileNamed:@"Energybell.m4a" waitForCompletion:NO];
    [energyball runAction:energySound];
    energyball.hidden = YES;
    [self addChild:[self FenergyNode:@"energy"]];
    [self adjustScoreBy:2];
    [scoreLabel setText: [NSString stringWithFormat:@"Score: %d", [GameState sharedInstance].score]];
    _bflyHP =MAX(0, _bflyHP+100);
    [energyball runAction:[SKAction removeFromParent]];


}

}

提前致谢!

【问题讨论】:

    标签: xcode5 sprite-kit


    【解决方案1】:

    我认为这句话是在自取其辱:

    SKNode * energyball = (contact.bodyA.categoryBitMask & bflyCategory) ?
                                                contact.bodyB.node : contact.bodyA.node;
    

    如果我正确理解你的代码,能量球categoryBitMask 永远不会设置为bflyCategory。因此,您总是选择 bodyA 的节点。由于 A 和 B 可以随时更改,因此依赖于 energyBall 始终是 bodyA 在某些时候容易失败。

    此外,您之前已经选择了SKPhysicsBody* energyBall,您应该使用它。这也应该带来一个编译器警告,如“x 阴影局部变量 y”,因为它们使用相同的标识符(变量名)。

    尝试将上面的行替换为:

    SKNode* ball = energyball.node;
    

    并将SKNode* energyball 的所有用途更改为ball

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多