精灵套件接头

时间:2014-01-14 21:17:01

标签: ios iphone objective-c sprite-kit

我正在尝试制作一个动画角色,可以触及屏幕上的内容,而无需移动他的躯干。

如果他不能伸手,那么他应该朝这个方向走最大量,然后通过静态躯干的物理限制来抵消。

problem

因此,在我的代码中,绿色矩形()移动到我点击的位置,然后是躯干。 我希望能够使红色矩形( body )静止,并使绿色矩形“指向”触点位置。

我试图在场景和红体矩形之间应用固定关节,但这似乎不起作用。

- (void) createSceneContent
{
    SKSpriteNode *body = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(100, 100)];
    body.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
    [self addChild:body];

    body.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:body.size];
    body.physicsBody.affectedByGravity = NO;
    body.physicsBody.dynamic = YES;

    self.hand = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(150, 20)];
    self.hand.position = CGPointMake(body.position.x + body.size.width / 2 + self.hand.size.width / 2, body.position.y);
    [self addChild:self.hand];
    self.hand.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.hand.size];
    self.hand.physicsBody.dynamic = NO;

    self.scene.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];

    [self.physicsWorld addJoint:[SKPhysicsJointPin jointWithBodyA:body.physicsBody bodyB:self.hand.physicsBody anchor:CGPointMake(body.position.x + body.size.width / 2, body.position.y)]];

    [self.hand runAction:[SKAction moveByX:100 y:10 duration:0.1]];
}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];

    CGPoint location = [touch locationInNode:self];
    [self.hand runAction:[SKAction moveTo:location duration:0.1]];
}

1 个答案:

答案 0 :(得分:3)

首先,如果你只想让手臂指向触摸的位置,你真的不需要在这里使用物理。
只需将手臂节点的anchorPoint更改为肩部(将引脚放在关节上)并围绕该点旋转(该点保持在辅助肩部节点中,以便以后可以轻松转换为其坐标) )。您可以使用atan2f计算旋转角度。这是代码:

- (void) createSceneContent
{
    SKSpriteNode *body = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(100, 100)];
    body.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
    [self addChild:body];

    self.hand = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(150, 20)];
    self.hand.position = CGPointMake(body.position.x + body.size.width*0.5, body.position.y);
    self.hand.anchorPoint = CGPointMake(0, 0.5);
    [self addChild:self.hand];

    SKNode *shoulderNode = [SKNode node];
    shoulderNode.position = self.hand.position;
    shoulderNode.name = @"shoulderNode";
    [self addChild:shoulderNode];

}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];

    CGPoint location = [touch locationInNode:self];
    CGPoint locationConv = [self convertPoint:location toNode:[self childNodeWithName:@"shoulderNode"]];

    self.hand.zRotation = (atan2f(locationConv.y, locationConv.x));
}

另一方面,如果您需要在这里使用物理实体,使用SKActions移动手臂可能是个坏主意,您也可能想要设置body.physicsBody.dynamic = NO以使躯干静止。然后,确保正确添加针脚接头,并将其frictionTorque属性设置为较高的值以减少悬空。使手指向正确位置的方法之一是在更新方法中设置的速度矢量 - 只需使用转换后的位置坐标(这里它们相对于身体节点的中心)。完整的示例代码:

- (void) createSceneContent {
    self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];

    body = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(100, 100)];
    body.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
    [self addChild:body];

    body.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:body.size];
    body.physicsBody.dynamic = NO;
    body.physicsBody.affectedByGravity = YES;

    self.hand = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(20, 150)];
    // experiment with the anchorPoint for different results
    self.hand.anchorPoint = CGPointMake(0.5, 0);
    self.hand.position = CGPointMake(body.position.x, body.position.y);
    [self addChild:self.hand];

    self.hand.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.hand.size];
    self.hand.physicsBody.dynamic = YES;
    self.hand.physicsBody.affectedByGravity = NO;

    SKPhysicsJointPin *pinHand = [SKPhysicsJointPin jointWithBodyA:body.physicsBody bodyB:self.hand.physicsBody anchor:CGPointMake(body.position.x, body.position.y-5)];
    [self.physicsWorld addJoint:pinHand];
    // experiment with the friction torque value to achieve desired results
    pinHand.frictionTorque = 1.0;
}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    location = [touch locationInNode:self];
}

-(void)update:(CFTimeInterval)currentTime {
    CGPoint locationConv = [self convertPoint:location toNode:body];
    // experiment with the multiplier (here: 10) for faster/slower movement
    self.hand.physicsBody.velocity = CGVectorMake(locationConv.x*10, locationConv.y*10);
}

希望有所帮助!