SpriteKit物理 - 如何让我的角色在跌倒后站起来?

时间:2014-09-05 16:45:10

标签: ios7 sprite-kit physics game-physics

我是精灵套件和游戏物理的新手。我希望我的角色在他跌倒或被击倒时直立起来。有点像落地式打孔袋。这是我目前的代码:

#import "MyScene.h"

@interface MyScene () <SKPhysicsContactDelegate> {
    SKSpriteNode *_body;
    SKSpriteNode *_leg1;
    SKSpriteNode *_leg2;
    SKSpriteNode *_foot1;
    SKSpriteNode *_foot2;
}
@end

@implementation MyScene

-(id)initWithSize:(CGSize)size {    
    if (self = [super initWithSize:size]) {

        //self.backgroundColor = [SKColor greenColor];

        self.physicsWorld.gravity = CGVectorMake(0, -2.0);
        self.physicsWorld.contactDelegate = self;
        self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];

        SKSpriteNode *button = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(50, 50)];
        button.position = CGPointMake(40, 40);
        button.zPosition = 10;
        button.name = @"button";
        [self addChild: button];

        [self createCharacter];

    }
    return self;
}

-(void)createCharacter {

    // Add sprites

    _body = [SKSpriteNode spriteNodeWithColor:[SKColor purpleColor] size:CGSizeMake(40, 60)];
    _body.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
    [self addChild: _body];

    _leg1 = [SKSpriteNode spriteNodeWithColor:[SKColor purpleColor] size:CGSizeMake(14, 60)];
    _leg1.position = CGPointMake(_body.position.x+20-7, _body.position.y-65);
    [self addChild:_leg1];

    _foot1 = [SKSpriteNode spriteNodeWithColor:[SKColor purpleColor] size:CGSizeMake(20, 10)];
    _foot1.position = CGPointMake(_leg1.position.x-2.5, _leg1.position.y-40);
    [self addChild:_foot1];

    _leg2 = [SKSpriteNode spriteNodeWithColor:[SKColor purpleColor] size:CGSizeMake(14, 60)];
    _leg2.position = CGPointMake(_body.position.x-20+7, _body.position.y-65);
    [self addChild:_leg2];

    _foot2 = [SKSpriteNode spriteNodeWithColor:[SKColor purpleColor] size:CGSizeMake(20, 10)];
    _foot2.position = CGPointMake(_leg2.position.x-2.5, _leg2.position.y-40);
    [self addChild:_foot2];

    // Add physics bodies to sprites

    _body.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_body.size];

    _leg1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_leg1.size];
    _foot1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_foot1.size];
    _foot1.physicsBody.mass = 1;

    _leg2.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_leg2.size];
    _foot2.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_foot2.size];
    _foot2.physicsBody.mass = 0.5;

    // Add joints

    SKPhysicsJoint *hipJoint = [SKPhysicsJointFixed jointWithBodyA:_body.physicsBody bodyB:_leg1.physicsBody anchor:_leg1.position];
    SKPhysicsJoint *ankleJoint = [SKPhysicsJointFixed jointWithBodyA:_leg1.physicsBody bodyB:_foot1.physicsBody anchor:_foot1.position];

    SKPhysicsJointPin *hipJoint2 = [SKPhysicsJointPin jointWithBodyA:_body.physicsBody bodyB:_leg2.physicsBody anchor:CGPointMake(_leg2.position.x, CGRectGetMaxY(_leg2.frame))];
    [hipJoint2 setShouldEnableLimits:YES];
    [hipJoint2 setLowerAngleLimit:-M_PI_2];
    [hipJoint2 setUpperAngleLimit:0.0];
    SKPhysicsJoint *ankleJoint2 = [SKPhysicsJointFixed jointWithBodyA:_leg2.physicsBody bodyB:_foot2.physicsBody anchor:_foot2.position];

    [self.scene.physicsWorld addJoint:hipJoint];
    [self.scene.physicsWorld addJoint:ankleJoint];

    [self.scene.physicsWorld addJoint:hipJoint2];
    [self.scene.physicsWorld addJoint:ankleJoint2];

}

-(void)characterJump {

    CGFloat radianFactor = 0.0174532925;
    CGFloat rotationInDegrees = _body.zRotation / radianFactor;
    CGFloat newRotationDegrees = rotationInDegrees + 90;
    CGFloat newRotationRadians = newRotationDegrees * radianFactor;

    CGFloat r = 500;

    CGFloat dx = r * cos(newRotationRadians);
    CGFloat dy = r * sin(newRotationRadians);

    [_body.physicsBody applyImpulse:CGVectorMake(dx, dy)];

    NSLog(@"leg2 rotation: %f", _foot2.zRotation / radianFactor);
}

-(void)characterKick {
    NSLog(@"Kick..");
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    SKNode *node = [self nodeAtPoint:location];

    if ([node.name isEqualToString:@"button"]) {
        [self characterJump];
        [self characterKick];
    }
}

-(void)update:(CFTimeInterval)currentTime {

}

@end

运行代码并点按按钮让他跳跃并最终摔倒。此外,关节限制不起作用,因为它有时会突破限制。

非常感谢帮助。

1 个答案:

答案 0 :(得分:1)

我通过在场景的更新方法中检查_body SKSpriteNode的'y'位置来解决这个问题。如果'y'位置低于某个极限,我从下面对身体的物理身体施加冲动,再次站起来。

这符合要求/期望。

-(void)update:(CFTimeInterval)currentTime {
    if(_body.position.y < 30) {
        [self upOnYourFeet];
    }
}

-(void)upOnYourFeet {
    [_body.physicsBody applyImpulse:CGVectorMake(0, 80)];
}