精灵套件 - 弹簧接头(减震器)

时间:2013-11-28 03:07:05

标签: ios spring sprite-kit

首先,谢谢@Smick在这里发布的初始车辆代码: Sprite Kit pin joints appear to have an incorrect anchor

我正在尝试在车轮(左轮)和底盘之间添加滑动接头以及弹簧接头,以产生减震效果。

我的代码如下,我没有压缩。我意识到文档显示了一个弹簧接头将两个节点拉在一起 - 与我想要的相反。这可能在SK吗?

我认为针接头可能是罪魁祸首?当我注释掉销钉接头时,汽车零件会变得混乱 - 一切都在屏幕上飞舞。最初,销接头将车轮固定在底盘上,但显然我想将车轮固定在“减震器”上。

此外,SKPhysicsJointSliding的“轴”参数让我有点困惑。它想要一个矢量。相对于?

的向量

提前谢谢。

- (SKShapeNode*) makeWheel
{
SKShapeNode *wheel = [[SKShapeNode alloc] init];
CGMutablePathRef myPath = CGPathCreateMutable();
CGPathAddArc(myPath, NULL, 0,0, 16, 0, M_PI*2, YES);
wheel.path = myPath;
wheel.physicsBody.mass = 0.5;
return wheel;
}

- (void) createCar{

// 1. car body
SKSpriteNode *carBody = [SKSpriteNode spriteNodeWithColor:[UIColor whiteColor] size:CGSizeMake(120, 8)];
carBody.position = CGPointMake(200, 700);
carBody.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:carBody.size];
carBody.physicsBody.mass = 1.0;
[self addChild:carBody];

// 2. wheels
SKShapeNode *leftWheel = [self makeWheel];
leftWheel.position = CGPointMake(carBody.position.x - carBody.size.width / 2, carBody.position.y-40);
leftWheel.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:16];
[self addChild:leftWheel];

SKShapeNode *rightWheel = [self makeWheel];
rightWheel.position = CGPointMake(carBody.position.x + carBody.size.width / 2, carBody.position.y);
rightWheel.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:16];
[self addChild:rightWheel];


/* Build left shock absorber and attach wheel */

CGVector av =CGVectorMake(0.0, 5.0);

SKPhysicsJointSliding *leftSlide = [SKPhysicsJointSliding    jointWithBodyA:carBody.physicsBody
                                                                    bodyB:leftWheel.physicsBody
                                                                  anchor:leftWheel.position
                                                                    axis:av];


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



SKPhysicsJointPin *leftPin = [SKPhysicsJointPin jointWithBodyA:leftSpring.bodyA
                                                        bodyB:leftSpring.bodyB
                                                        anchor:leftWheel.position];


[self.physicsWorld addJoint:leftSlide];
[self.physicsWorld addJoint:leftSpring];
[self.physicsWorld addJoint:leftPin];

[self.physicsWorld addJoint:[SKPhysicsJointPin jointWithBodyA:carBody.physicsBody     bodyB:rightWheel.physicsBody anchor:rightWheel.position]];

}

3 个答案:

答案 0 :(得分:8)

编辑我的答案。悬架需要将车轮连接到滑动体上,而不是通过滑动接头连接车轮。做前者允许轮子旋转。后者没有。

Vehicle.m

#import "Vehicle.h"

@implementation Vehicle

- (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]) {

        _joints = [NSMutableArray array];

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

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

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

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


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

        SKSpriteNode *rightWheel = [self makeWheel];
        rightWheel.position = CGPointMake(chassis.position.x + chassis.size.width / 2, chassis.position.y - wheelOffsetY);
        rightWheel.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:rightWheel.size.width/2];
        rightWheel.physicsBody.allowsRotation = YES;
        [self addChild:rightWheel];

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

        SKSpriteNode *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);
        leftShockPost.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:leftShockPost.size];
        [self addChild:leftShockPost];

       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];


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

        SKSpriteNode *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);
        rightShockPost.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:rightShockPost.size];
        [self addChild:rightShockPost];

        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.

        [_joints addObject:cJoint];

        [_joints addObject:leftSlide];
        [_joints addObject:leftSpring];
        [_joints addObject:lPin];

        [_joints addObject:rightSlide];
        [_joints addObject:rightSpring];
        [_joints addObject:rPin];

    }

    return self;
}


@end

答案 1 :(得分:4)

我冒昧地将Jeremiah的代码转换为swift,以便在操场上进行测试 - 我认为这对于使用spritekit非常宝贵。没有新功能;刚刚翻译成swift并修改为在游乐场中运行:

现在更新为Swift 3.因为我关心。

import Foundation
import SpriteKit
import PlaygroundSupport

let view:SKView = SKView(frame: CGRect(x: 0, y: 0, width: 1024, height: 768))
PlaygroundPage.current.liveView = view

let scene = SKScene(size: CGSize(width: 1024, height: 768))
scene.name = "PlaygroundScene"
scene.physicsWorld.gravity =  CGVector()
scene.scaleMode = SKSceneScaleMode.aspectFill

var vehicle = SKNode()

var joints = [SKPhysicsJoint]()
let wheelOffsetY:CGFloat    =   60;
let damping:CGFloat     =   1;
let frequency :CGFloat    =   4;

let chassis = SKSpriteNode.init(color: UIColor.white, size: CGSize(width: 120, height: 8))
chassis.position = CGPoint(x: scene.size.width/2, y: scene.size.height/2)
chassis.physicsBody =  SKPhysicsBody.init(rectangleOf: chassis.size)
vehicle.addChild(chassis)


let ctop = SKSpriteNode.init(color: UIColor.green, size: CGSize(width: 70, height: 16))

ctop.position = CGPoint(x: chassis.position.x+20, y: chassis.position.y+12)
ctop.physicsBody = SKPhysicsBody.init(rectangleOf: ctop.size)
vehicle.addChild(ctop)



let cJoint = SKPhysicsJointFixed.joint(withBodyA: chassis.physicsBody!, bodyB: ctop.physicsBody!, anchor: CGPoint(x: ctop.position.x, y: ctop.position.y))



let leftWheel = SKSpriteNode(imageNamed: "wheel.png")
leftWheel.position = CGPoint(x: chassis.position.x - chassis.size.width / 2, y: chassis.position.y - wheelOffsetY)  //Always set position before physicsBody
leftWheel.physicsBody = SKPhysicsBody(circleOfRadius: leftWheel.size.width/2)
leftWheel.physicsBody!.allowsRotation = true;
vehicle.addChild(leftWheel)


let rightWheel = SKSpriteNode(imageNamed: "wheel.png")
rightWheel.position = CGPoint(x: chassis.position.x + chassis.size.width / 2, y: chassis.position.y - wheelOffsetY)  //Always set position before physicsBody
rightWheel.physicsBody = SKPhysicsBody(circleOfRadius: leftWheel.size.width/2)
rightWheel.physicsBody!.allowsRotation = true;
vehicle.addChild(rightWheel)


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

let leftShockPost = SKSpriteNode(color: UIColor.blue, size:CGSize(width:7, height: wheelOffsetY))

leftShockPost.position = CGPoint(x:chassis.position.x - chassis.size.width / 2, y: chassis.position.y - leftShockPost.size.height/2)

leftShockPost.physicsBody = SKPhysicsBody(rectangleOf: leftShockPost.size)
vehicle.addChild(leftShockPost)

let leftSlide = SKPhysicsJointSliding.joint(withBodyA: chassis.physicsBody!, bodyB: leftShockPost.physicsBody!, anchor:CGPoint(x:leftShockPost.position.x, y: leftShockPost.position.y), axis:CGVector(dx: 0.0, dy: 1.0))


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


let leftSpring = SKPhysicsJointSpring.joint(withBodyA: chassis.physicsBody!, bodyB: leftWheel.physicsBody!, anchorA: CGPoint(x:chassis.position.x - chassis.size.width / 2, y: chassis.position.y), anchorB: leftWheel.position)


leftSpring.damping = damping;
leftSpring.frequency = frequency;

let lPin = SKPhysicsJointPin.joint(withBodyA: leftShockPost.physicsBody!, bodyB:leftWheel.physicsBody!, anchor:leftWheel.position)


//--------------------- Right SUSPENSION ---------------------- //

let rightShockPost = SKSpriteNode(color: UIColor.blue, size:CGSize(width: 7, height: wheelOffsetY) )

rightShockPost.position = CGPoint(x:chassis.position.x + chassis.size.width / 2, y: chassis.position.y - rightShockPost.size.height/2)

rightShockPost.physicsBody = SKPhysicsBody(rectangleOf: rightShockPost.size)
vehicle.addChild(rightShockPost)

let rightSlide = SKPhysicsJointSliding.joint(withBodyA: chassis.physicsBody!, bodyB: rightShockPost.physicsBody!, anchor:CGPoint(x:rightShockPost.position.x, y: rightShockPost.position.y), axis:CGVector(dx: 0.0, dy: 1.0))


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


let rightSpring = SKPhysicsJointSpring.joint(withBodyA: chassis.physicsBody!, bodyB: rightWheel.physicsBody!, anchorA: CGPoint(x: chassis.position.x - chassis.size.width / 2, y: chassis.position.y), anchorB: rightWheel.position)


rightSpring.damping = damping;
rightSpring.frequency = frequency;

let rPin = SKPhysicsJointPin.joint(withBodyA: leftShockPost.physicsBody!, bodyB:rightWheel.physicsBody!, anchor:rightWheel.position)


// Add all joints to the array.

joints.append(cJoint)
joints.append(leftSlide)
joints.append(leftSpring)
joints.append(rightSlide)
joints.append(rightSpring)
joints.append(rPin)


scene.addChild(vehicle)
view.presentScene(scene)

答案 2 :(得分:1)

弹簧没有压缩?一个罪魁祸首是使用frequency的默认0.0。将frequency增加到9.0,然后不做任何其他更改,我怀疑您会看到一些所需的压缩。

frequency视为衡量春天"僵硬度的指标是有用的。较高的frequency意味着更强的弹簧。 frequency的{​​{1}}非常非常松散!但是,此逻辑会在0.0001的默认frequency处分解。在0.0,弹簧完全是刚性的,非压缩的。