Cocos2d V3(Chipmunk)中具有摩擦和限制的PivotJoints

5
我试图将使用SpriteKit开始的游戏转换为Cocos2d V3。然而,我在物理方面遇到了一些问题。我创建了一个类似于人体的玩家角色。在SpriteKit中,四肢通过PinJoints连接。我通过Chipmunk中的PivotJoints重新创建了基本功能。这个功能可以正常工作。
但是,我需要添加一些摩擦力到关节上。现在它们只会尽可能快地旋转,更重要的是,我需要限制关节的旋转角度。你可以想象,大多数人无法自由地将他们的肩膀旋转360度。 ;)
据我所知,我应该使用ChipmunkRotaryLimitJoint和ChipmunkGearJoint来实现这一点。我的问题是,我不知道如何正确地附加它们。这是我现在的代码:
- (CCPhysicsJoint *)createPinJointWithBodyA:(CCPhysicsBody *)bodyA
                                      bodyB:(CCPhysicsBody *)bodyB
                                     anchor:(CGPoint)anchor
                                   friction:(CGFloat)friction
                                 lowerLimit:(CGFloat)lowerLimit
                                 upperLimit:(CGFloat)upperLimit
{

    CCPhysicsJoint *pin = [CCPhysicsJoint 
        connectedPivotJointWithBodyA:bodyA
                               bodyB:bodyB
                             anchorA:anchor];

    ChipmunkRotaryLimitJoint *limitJoint = [ChipmunkRotaryLimitJoint 
        rotaryLimitJointWithBodyA:bodyA.body 
                            bodyB:bodyB.body
                              min:CC_DEGREES_TO_RADIANS(lowerLimit)
                              max:CC_DEGREES_TO_RADIANS(upperLimit)];

    ChipmunkGearJoint *gearJoint = [ChipmunkGearJoint 
        gearJointWithBodyA:bodyA.body
                     bodyB:bodyB.body
                     phase:0.5
                     ratio:0.5];

    return pin;
}

齿轮关节调用中的值只是占位符!

有人知道这应该如何工作吗?我通过谷歌找到了一些东西,但所有教程都假设我在其他环境中使用chipmunk。我是否需要为这些限制和齿轮关节创建自己的CCPhysicJoint实现?

谢谢和最好的祝愿, Thomas

1个回答

6

我想我解决了这个问题。原来我需要创建自己的CCPhysicsJoint类别,该类别实现了ChipmunkRotaryLimitJoint和ChipmunkRotaryDampedSpring。虽然不完全一样,但现在足够好用。

目前代码如下:

[CCPhysicsJoint connectedRotaryLimitJointWithBodyA:bodyA
                                             bodyB:bodyB
                                               min:CC_DEGREES_TO_RADIANS(lowerLimit)
                                               max:CC_DEGREES_TO_RADIANS(upperLimit)];

[CCPhysicsJoint connectedDampedRotarySpringWithBodyA:bodyA
                                               bodyB:bodyB
                                           restAngle:0
                                           stiffness:friction *1000.0f
                                             damping:10000.0f];

我刚刚询问是否应该将这个包含在Cocos2D代码库中。目前,这是包装器:

CCPhysicsJoint+THCAdditions.h

//
//  CCPhysicsJoint+THCAdditions.h
//
//  Created by Thomas Hempel on 02.02.14.
//  Copyright (c) 2014 Thomas Hempel. All rights reserved.
//

#import "CCPhysicsBody.h"
#import "CCPhysicsJoint.h"

@interface CCPhysicsJoint (THCAdditions)

+ (CCPhysicsJoint *)connectedRotaryLimitJointWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB min:(CGFloat)min max:(CGFloat)max;
+ (CCPhysicsJoint *)connectedGearJointWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB phase:(CGFloat)phase ratio:(CGFloat)ratio;
+ (CCPhysicsJoint *)connectedSimpleMotorJointWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB rate:(CGFloat)rate;
+ (CCPhysicsJoint *)connectedDampedRotarySpringWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB restAngle:(CGFloat)restAngle stiffness:(CGFloat)stiffness damping:(CGFloat)damping;

@end

CCPhysicsJoint+THCAdditions.m

//
//  CCPhysicsJoint+THCAdditions.m
//
//  Created by Thomas Hempel on 02.02.14.
//  Copyright (c) 2014 Thomas Hempel. All rights reserved.
//

#import "CCPhysicsJoint+THCAdditions.h"
#import "CCPhysics+ObjectiveChipmunk.h"

// ------------------------------------------------------------------------
#pragma mark - Rotary Limit Joint
// ------------------------------------------------------------------------

@interface CCPhysicsRotaryLimitJoint : CCPhysicsJoint
@end

@implementation CCPhysicsRotaryLimitJoint {
    ChipmunkRotaryLimitJoint *_constraint;
}

- (id)initWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB min:(CGFloat)min max:(CGFloat)max
{
    if ((self = [super init])){
        _constraint = [ChipmunkRotaryLimitJoint rotaryLimitJointWithBodyA:bodyA.body
                                                                    bodyB:bodyB.body
                                                                      min:min
                                                                      max:max];
        _constraint.userData = self;
    }
    return self;
}

- (ChipmunkConstraint *)constraint
{
    return _constraint;
}

- (void)willAddToPhysicsNode:(CCPhysicsNode *)physics
{
}

@end

// ------------------------------------------------------------------------
#pragma mark - Gear Joint
// ------------------------------------------------------------------------

@interface CCPhysicsGearJoint : CCPhysicsJoint
@end

@implementation CCPhysicsGearJoint {
    ChipmunkGearJoint *_constraint;
}

- (id)initWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB phase:(CGFloat)phase ratio:(CGFloat)ratio
{
    if ((self = [super init])){
        _constraint = [ChipmunkGearJoint gearJointWithBodyA:bodyA.body
                                                      bodyB:bodyB.body
                                                      phase:phase
                                                      ratio:ratio];
        _constraint.userData = self;
    }

    return self;
}

- (ChipmunkConstraint *)constraint
{
    return _constraint;
}

- (void)willAddToPhysicsNode:(CCPhysicsNode *)physics
{
}

@end

// ------------------------------------------------------------------------
#pragma mark - Simple Motor Joint
// ------------------------------------------------------------------------

@interface CCPhysicsSimpleMotorJoint : CCPhysicsJoint
@end

@implementation CCPhysicsSimpleMotorJoint {
    ChipmunkSimpleMotor *_constraint;
}

- (id)initWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB rate:(CGFloat)rate
{
    if ((self = [super init])){
        _constraint = [ChipmunkSimpleMotor simpleMotorWithBodyA:bodyA.body
                                                          bodyB:bodyB.body
                                                           rate:rate];
        _constraint.userData = self;
    }

    return self;
}

- (ChipmunkConstraint *)constraint
{
    return _constraint;
}

- (void)willAddToPhysicsNode:(CCPhysicsNode *)physics
{
}

@end

// ------------------------------------------------------------------------
#pragma mark - Damped Rotary Spring
// ------------------------------------------------------------------------

@interface CCPhysicsDampedRotarySpring : CCPhysicsJoint
@end

@implementation CCPhysicsDampedRotarySpring {
    ChipmunkDampedRotarySpring *_constraint;
}

- (id)initWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB restAngle:    (CGFloat)restAngle stiffness:(CGFloat)stiffness damping:(CGFloat)damping
{
    if ((self = [super init])){
        _constraint = [ChipmunkDampedRotarySpring dampedRotarySpringWithBodyA:bodyA.body
                                                                        bodyB:bodyB.body
                                                                    restAngle:restAngle
                                                                    stiffness:stiffness
                                                                      damping:damping];
        _constraint.userData = self;
    }

    return self;
}

- (ChipmunkConstraint *)constraint
{
    return _constraint;
}

- (void)willAddToPhysicsNode:(CCPhysicsNode *)physics
{
}

@end

// ------------------------------------------------------------------------
#pragma mark - Implementation
// ------------------------------------------------------------------------


@implementation CCPhysicsJoint (THCAdditions)

+ (CCPhysicsJoint *)connectedRotaryLimitJointWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB min:(CGFloat)min max:(CGFloat)max
{

    CCPhysicsJoint *joint = [[CCPhysicsRotaryLimitJoint alloc] initWithBodyA:bodyA bodyB:bodyB min:min max:max];
    [bodyA addJoint:joint];
    [bodyB addJoint:joint];

    [bodyA.physicsNode.space smartAdd:joint];

    return joint;
}

+ (CCPhysicsJoint *)connectedGearJointWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB phase:(CGFloat)phase ratio:(CGFloat)ratio
{
    CCPhysicsJoint *joint = [[CCPhysicsGearJoint alloc] initWithBodyA:bodyA bodyB:bodyB phase:phase ratio:ratio];

    [bodyA addJoint:joint];
    [bodyB addJoint:joint];

    [bodyA.physicsNode.space smartAdd:joint];

    return joint;
}

+ (CCPhysicsJoint *)connectedSimpleMotorJointWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB rate:(CGFloat)rate
{
    CCPhysicsJoint *joint = [[CCPhysicsSimpleMotorJoint alloc] initWithBodyA:bodyA bodyB:bodyB rate:rate];

    [bodyA addJoint:joint];
    [bodyB addJoint:joint];

    [bodyA.physicsNode.space smartAdd:joint];

    return joint;
}

+ (CCPhysicsJoint *)connectedDampedRotarySpringWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB restAngle:(CGFloat)restAngle stiffness:(CGFloat)stiffness damping:(CGFloat)damping
{
    CCPhysicsJoint *joint = [[CCPhysicsDampedRotarySpring alloc] initWithBodyA:bodyA bodyB:bodyB restAngle:restAngle stiffness:stiffness damping:damping];

    [bodyA addJoint:joint];
    [bodyB addJoint:joint];

    [bodyA.physicsNode.space smartAdd:joint];

    return joint;
}

@end

祝一切顺利, 托马斯


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接