Sprite Kit:如何子类化SKNode以创建Vehicle类(带关节的复杂对象)

Jer*_*911 3 subclass sprite-kit sknode

有没有人想出(本地)如何将SKNode子类化为包含多个通过关节连接的物体 - 例如,汽车?

似乎没有办法将子类的关节添加到父场景的physicsWorld属性中.

此外,当尝试编译并运行下面的对象时,即使没有关节,我也会收到BAD_EXC_ACCESS错误.

感谢@Smick在此处发布的初始车辆代码:Sprite Kit引脚接头似乎有一个不正确的锚点

卡车类:

#import "Truck.h"

@implementation Truck


-(id)initWithPosition:(CGPoint)pos {


SKSpriteNode *carBody = [SKSpriteNode spriteNodeWithColor:[UIColor whiteColor] size:CGSizeMake(120, 8)];
carBody.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:carBody.size];
carBody.position = pos;
carBody.physicsBody.mass = 1.0;


SKSpriteNode *carTop = [SKSpriteNode spriteNodeWithColor:[UIColor whiteColor] size:CGSizeMake(50, 8)];
carTop.position = CGPointMake(230, 708);
carTop.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:carTop.size];
carTop.physicsBody.mass = 0;

SKPhysicsJointFixed *carBodyJoint = [SKPhysicsJointFixed jointWithBodyA:carBody.physicsBody
                                                                  bodyB:carTop.physicsBody
                                                                 anchor:CGPointMake(0, 0)];



return self;
}

+(Truck*)initWithPosition:(CGPoint)pos {
return [[self alloc] initWithPosition:pos];
}


@end
Run Code Online (Sandbox Code Playgroud)

MyScene: 在此输入图像描述

小智 6

对不起发帖很晚,但是我自己也来了.

除非附加的节点已经添加到SKScene的场景图中,否则物理关节不起作用.

在上面的initWithPosition期间,情况并非如此.传入SKScene对我来说也不起作用,我怀疑因为Vehicle节点仍未添加到场景图中.

你仍然可以在类中封装你的物理关节,但你必须在之后调用另一个方法

[self addChild:car]
Run Code Online (Sandbox Code Playgroud)

这是我对你已经拥有的东西的改进:

Vehicle.h

@interface Vehicle : SKNode

@property (nonatomic) SKSpriteNode *leftWheel;
@property (nonatomic) SKSpriteNode *ctop;

-(id)initWithPosition:(CGPoint)pos;
-(void)initPhysics;

@end
Run Code Online (Sandbox Code Playgroud)

Vehicle.m

//

#import "Vehicle.h"

@implementation Vehicle {
    SKSpriteNode *chassis;
    SKSpriteNode *rightWheel;
    SKSpriteNode *leftShockPost;
    SKSpriteNode *rightShockPost;
    int wheelOffsetY;
    CGFloat damping;
    CGFloat frequency;
}

- (SKSpriteNode*) makeWheel
{
    SKSpriteNode *wheel = [SKSpriteNode spriteNodeWithImageNamed:@"Wheel.png"];
    //    wheel.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:wheel.size.width/2];
    return wheel;
}

-(id)initWithPosition:(CGPoint)pos {

    if (self = [super init]) {

        wheelOffsetY    =   60;
        damping         =   1;
        frequency       =   4;

        chassis = [SKSpriteNode spriteNodeWithColor:[UIColor whiteColor] size:CGSizeMake(120, 8)];
        chassis.position = pos;
        [self addChild:chassis];

        _ctop = [SKSpriteNode spriteNodeWithColor:[UIColor greenColor] size:CGSizeMake(70, 16)];
        _ctop.position = CGPointMake(chassis.position.x+20, chassis.position.y+12);

        [self addChild:_ctop];

        _leftWheel = [self makeWheel];
        _leftWheel.position = CGPointMake(chassis.position.x - chassis.size.width / 2, chassis.position.y - wheelOffsetY);  //Always set position before physicsBody

        [self addChild:_leftWheel];

        rightWheel = [self makeWheel];
        rightWheel.position = CGPointMake(chassis.position.x + chassis.size.width / 2, chassis.position.y - wheelOffsetY);
        [self addChild:rightWheel];

        //------------- LEFT SUSPENSION ----------------------------------------------------------------------------------------------- //

        leftShockPost = [SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:CGSizeMake(7, wheelOffsetY)];
        leftShockPost.position = CGPointMake(chassis.position.x - chassis.size.width / 2, chassis.position.y - leftShockPost.size.height/2);
        [self addChild:leftShockPost];


        //------------- RIGHT SUSPENSION ----------------------------------------------------------------------------------------------- //

        rightShockPost = [SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:CGSizeMake(7, wheelOffsetY)];
        rightShockPost.position = CGPointMake(chassis.position.x + chassis.size.width / 2, chassis.position.y - rightShockPost.size.height/2);
        [self addChild:rightShockPost];

    }

    return self;
}

-(void) initPhysics {

    chassis.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:chassis.size];
    _ctop.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_ctop.size];

    SKPhysicsJointFixed *cJoint = [SKPhysicsJointFixed jointWithBodyA:chassis.physicsBody
                                                                bodyB:_ctop.physicsBody
                                                               anchor:CGPointMake(_ctop.position.x, _ctop.position.y)];

    _leftWheel.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:_leftWheel.size.width/2];
    _leftWheel.physicsBody.allowsRotation = YES;

    rightWheel.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:rightWheel.size.width/2];
    rightWheel.physicsBody.allowsRotation = YES;

    leftShockPost.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:leftShockPost.size];
    SKPhysicsJointSliding  *leftSlide = [SKPhysicsJointSliding jointWithBodyA:chassis.physicsBody
                                                                        bodyB:leftShockPost.physicsBody
                                                                       anchor:CGPointMake(leftShockPost.position.x, leftShockPost.position.y)
                                                                         axis:CGVectorMake(0, 1)];

    leftSlide.shouldEnableLimits = TRUE;
    leftSlide.lowerDistanceLimit = 5;
    leftSlide.upperDistanceLimit = wheelOffsetY;


    SKPhysicsJointSpring *leftSpring = [SKPhysicsJointSpring jointWithBodyA:chassis.physicsBody bodyB:_leftWheel.physicsBody
                                                                    anchorA:CGPointMake(chassis.position.x - chassis.size.width / 2, chassis.position.y)
                                                                    anchorB:_leftWheel.position];
    leftSpring.damping = damping;
    leftSpring.frequency = frequency;

    SKPhysicsJointPin *lPin = [SKPhysicsJointPin jointWithBodyA:leftShockPost.physicsBody bodyB:_leftWheel.physicsBody anchor:_leftWheel.position];

    rightShockPost.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:rightShockPost.size];
    SKPhysicsJointSliding  *rightSlide = [SKPhysicsJointSliding jointWithBodyA:chassis.physicsBody
                                                                         bodyB:rightShockPost.physicsBody
                                                                        anchor:CGPointMake(rightShockPost.position.x, rightShockPost.position.y)
                                                                          axis:CGVectorMake(0, 1)];

    rightSlide.shouldEnableLimits = TRUE;
    rightSlide.lowerDistanceLimit = 5;
    rightSlide.upperDistanceLimit = wheelOffsetY;


    SKPhysicsJointSpring *rightSpring = [SKPhysicsJointSpring jointWithBodyA:chassis.physicsBody bodyB:rightWheel.physicsBody
                                                                     anchorA:CGPointMake(chassis.position.x + chassis.size.width / 2, chassis.position.y)
                                                                     anchorB:rightWheel.position];
    rightSpring.damping = damping;
    rightSpring.frequency = frequency;

    SKPhysicsJointPin *rPin = [SKPhysicsJointPin jointWithBodyA:rightShockPost.physicsBody bodyB:rightWheel.physicsBody anchor:rightWheel.position];

    // Add all joints to the array.
    // Add joints to scene's physics world

    [self.scene.physicsWorld addJoint: cJoint];
    [self.scene.physicsWorld addJoint: leftSlide];
    [self.scene.physicsWorld addJoint: leftSpring];
    [self.scene.physicsWorld addJoint: lPin];
    [self.scene.physicsWorld addJoint: rightSlide];
    [self.scene.physicsWorld addJoint: rightSpring];
    [self.scene.physicsWorld addJoint: rPin];

}
@end
Run Code Online (Sandbox Code Playgroud)

并从MyScene.m调用它

_car = [[DMVehicle alloc] initWithPosition:location];
[self addChild:_car];
[_car initPhysics];
Run Code Online (Sandbox Code Playgroud)

希望有所帮助,我知道它通过它完成了帮助我