首先,谢谢@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]];
}
答案 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
,弹簧完全是刚性的,非压缩的。