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

 飞天猪的世界公寓 发布于 2023-02-13 16:54

有没有人想出(本地)如何将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

MyScene: 在此输入图像描述

1 个回答
  • 对不起发帖很晚,但是我自己也来了.

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

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

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

    [self addChild:car]
    

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

    Vehicle.h

    @interface Vehicle : SKNode
    
    @property (nonatomic) SKSpriteNode *leftWheel;
    @property (nonatomic) SKSpriteNode *ctop;
    
    -(id)initWithPosition:(CGPoint)pos;
    -(void)initPhysics;
    
    @end
    

    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
    

    并从MyScene.m调用它

    _car = [[DMVehicle alloc] initWithPosition:location];
    [self addChild:_car];
    [_car initPhysics];
    

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

    2023-02-13 16:56 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有