防止父节点受SpriteKit中子物理主体的影响

时间:2014-09-26 02:39:52

标签: objective-c sprite-kit game-physics

我是一名长期的网络开发人员,但这是我第一次制作游戏或使用Objective C。我真的(真的!)就像目前使用Objective C一样,并且在我的游戏中已经走得很远。在此先感谢您的帮助!

我正试图在英雄获得一个拾取后,让三个尖刺球(SKSpriteNodes)围绕我的英雄舰旋转一圈(见图)。所有的外观和动画都很棒,直到我将物理体添加到球中,这是必需的,因此它们可以与怪物碰撞。我希望英雄船不受附属物理体的影响,这样英雄运动就能保持平稳和恒定 - 我正在移动英雄:

    [self.heroShip.physicsBody applyForce:CGVectorMake(moveByX, moveByY)];.

enter image description here

这里没有物理机构。我将3个子节点附加到锚节点,将锚节点附加到英雄船,然后旋转锚。以下动画看起来与我想要的完全一样。

    SKSpriteNode * spikeballAnchor = [[SKSpriteNode alloc] init];

    SKSpriteNode * spikeball1   = [SKSpriteNode spriteNodeWithImageNamed:@"spikeball"];
    spikeball1.name             = HERO_SPIKEBALL;
    spikeball1.position         = CGPointMake(100, 0);
    [spikeballAnchor addChild:spikeball1];

    SKSpriteNode * spikeball2   = [SKSpriteNode spriteNodeWithImageNamed:@"spikeball"];
    spikeball2.name             = HERO_SPIKEBALL;
    spikeball2.position         = CGPointMake(-50, 86);
    [spikeballAnchor addChild:spikeball2];

    SKSpriteNode * spikeball3   = [SKSpriteNode spriteNodeWithImageNamed:@"spikeball"];
    spikeball3.name             = HERO_SPIKEBALL;
    spikeball3.position         = CGPointMake(-50, -86);
    [spikeballAnchor addChild:spikeball3];

    [spikeballAnchor runAction:[SKAction repeatActionForever:[SKAction rotateByAngle:(M_PI_2 * 2) duration:1]]];

    [self.heroShip addChild:spikeballAnchor];

但是穗球需要与敌人的怪物相撞!当我将以下物理体添加到钉状球时,它会快速飞出轨道。

    SKSpriteNode * spikeball1   = [SKSpriteNode spriteNodeWithImageNamed:@"spikeball"];
    spikeball1.name             = HERO_SPIKEBALL;
    spikeball1.position         = CGPointMake(100, 0);
    spikeball1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:spikeball1.size];
    spikeball1.physicsBody.categoryBitMask    = spikeballCategory;
    spikeball1.physicsBody.contactTestBitMask = monsterCategory;
    spikeball1.physicsBody.collisionBitMask   = defaultCategory;
    [spikeballAnchor addChild:spikeball1];

确定。因此,我已经尝试了我能想到的所有内容,并且已经在网上搜索解决方案。给出我尝试的所有东西的例子会占用很多空间,所以我会总结一下。

我试过让锚点成为一个物理体,将钉球固定在锚点上,然后将锚固定在英雄身上。没有运气。

我尝试在锚点和球之间创建一个SKPhysicsJointLimit,SKPhysicsJointPin和一个SKPhysicsJointFixed。在所有这些装备中,钉球的物理性质使船停下来。我已经尝试将锚的质量和球设置为零。奇怪的是,即使没有质量,它们似乎仍然会影响船的运动。另外,我尝试将物理体的摩擦力,线性阻尼和angularDamping设置为零。

当我在设置物理体之前添加子节点时,关节似乎也起作用。

以下是我得到的最接近/最好的结果(示例中有一个钉球),但我无法使球的旋转不影响船!当我运行时,球不会一致地旋转(船的运动加速并减慢围绕关节的旋转)并且球的运动抛出船的运动,从而在船上产生不期望的钟摆效应。当它们被摧毁时,需要使用2球和1球。

    SKSpriteNode * spikeballAnchor = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(10, 10)];
    [self.heroShip addChild:spikeballAnchor];
    spikeballAnchor.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:spikeballAnchor.size];
    spikeballAnchor.physicsBody.pinned = true;
    spikeballAnchor.name = HERO_SPIKEBALL;

    SKSpriteNode * spikeball1   = [SKSpriteNode spriteNodeWithImageNamed:@"spikeball"];
    spikeball1.name             = HERO_SPIKEBALL;
    spikeball1.position         = CGPointMake(100, 0);
    [spikeballAnchor addChild:spikeball1];
    spikeball1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:spikeball1.size];
    spikeball1.physicsBody.categoryBitMask    = spikeballCategory;
    spikeball1.physicsBody.contactTestBitMask = monsterCategory;
    spikeball1.physicsBody.collisionBitMask   = defaultCategory;

    [spikeballAnchor runAction:[SKAction repeatActionForever:[SKAction rotateByAngle:(M_PI_2 * 2) duration:1]]];

    SKPhysicsJointFixed * joint = [SKPhysicsJointFixed jointWithBodyA:spikeballAnchor.physicsBody bodyB:spikeball1.physicsBody anchor:spikeballAnchor.position];
    [self.physicsWorld addJoint:joint];

我曾考虑过试图独立于船只移动锚和它的孩子,但是我担心他们会失去同步,如果锚不是,当英雄死亡时,它会增加一点管理来移除它们英雄的孩子。但如果我能保持他们的位置完全同步,那不是一个交易破坏者。

很抱歉这么冗长。非常感谢任何帮助!

// Collision Bits

static const int defaultCategory            = 0;
static const int projectileCategory         = 1;
static const int spikeballCategory          = 2;
static const int monsterCategory            = 3;
static const int heroCategory               = 4;
static const int pickupCategory             = 5;
static const int boundariesCategory         = 50;

1 个答案:

答案 0 :(得分:0)

不是问题的答案,所以有点offtopic,但我在你的代码中看到另一个问题:你的类别是相交的,因为它们被用作位掩码。我的意思是,您的monsterCategory包括spikeballCategoryprojectileCategory,因为在二进制3 = 1 | 2中。

  monsterCategory      3   0b00000011  
  projectileCategory   1   0b00000001  
  spikeballCategory    2   0b00000010  

所以你可能会注意到你的尖刺可能像怪物一样,反之亦然,射弹就像怪物一样,反之亦然。