Why won't this SKPhysicsJointPin keep these 2 sprites together?

半世苍凉 提交于 2019-12-12 21:19:37

问题


I clearly don't understand the SKPhysicsJoint very well, but there is so little info on the web yet, other than the Apple docs of course. What is wrong with the following code, which I would think should keep the head and neck permanently joined - my intention is that they act like 2 pieces of paper with a pin, so that they can rotate a bit, but not just totally come apart. When I run this code, they fall to the bottom of the SKScene they're in, hit the ground, then the head falls off the body.

Maybe the joint is not moving WITH them or something, it's just staying in place while they move??

self.head = [SKSpriteNode spriteNodeWithImageNamed:@"head.png"];
self.head.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.head.size];
self.head.physicsBody.mass = 0.05;
self.head.physicsBody.dynamic = YES;

self.chest = [SKSpriteNode spriteNodeWithImageNamed:@"chest_neck"];
self.chest.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.chest.size];
self.chest.physicsBody.mass = 0.05;
self.chest.physicsBody.dynamic = YES;

self.leftLeg = [SKSpriteNode spriteNodeWithImageNamed:@"left_leg"];
self.leftLeg.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.leftLeg.size];
self.leftLeg.physicsBody.mass = 10;
self.leftLeg.physicsBody.dynamic = YES;

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
    self.head.position = CGPointMake(282, 220);
    self.chest.position = CGPointMake(282, 130);
    self.leftLeg.position = CGPointMake(282, 10);

} else {
    self.head.position = CGPointMake(512, 380);
    self.chest.position = CGPointMake(512, 290);
    self.leftLeg.position = CGPointMake(512, 10);

}



[self addChild:self.head];
[self addChild:self.chest];
[self addChild:self.leftLeg];


self.chestJointPinAnchor = CGPointMake(self.chest.position.x, self.chest.position.y+39);
self.chestJointPin = [SKPhysicsJointPin jointWithBodyA:self.head.physicsBody bodyB:self.chest.physicsBody anchor:self.chestJointPinAnchor];
[self.physicsWorld addJoint:self.chestJointPin];

回答1:


This is because you set sprite's position after you set up its physicsBody property. I haven't discovered any mention of that in documentation, but I broke my head last weekend trying to figure out why my manually created rope works, but recursively one doesn't. SpriteNodes' position MUST be set before physicsBody. So, just reorder your code somehow like that:

self.head = [SKSpriteNode spriteNodeWithImageNamed:@"head.png"];
self.chest = [SKSpriteNode spriteNodeWithImageNamed:@"chest_neck"];
self.leftLeg = [SKSpriteNode spriteNodeWithImageNamed:@"left_leg"];

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
    self.head.position = CGPointMake(282, 220);
    self.chest.position = CGPointMake(282, 130);
    self.leftLeg.position = CGPointMake(282, 10);

} else {
    self.head.position = CGPointMake(512, 380);
    self.chest.position = CGPointMake(512, 290);
    self.leftLeg.position = CGPointMake(512, 10);

self.head.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.head.size];
self.head.physicsBody.mass = 0.05;
self.head.physicsBody.dynamic = YES;

self.chest.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.chest.size];
self.chest.physicsBody.mass = 0.05;
self.chest.physicsBody.dynamic = YES;

self.leftLeg.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.leftLeg.size];
self.leftLeg.physicsBody.mass = 10;
self.leftLeg.physicsBody.dynamic = YES;


}

Oh, I've noticed, you've already found an answer by yourself... Could you please mark your question as answered then.




回答2:


That seems about right.

A pin joint allows both bodies to rotate around the joint's anchor point. A real world example is an analog clock. Or a bicycle's pedals. Or a car wheel's axle.

One thing you have to know is that bodies connected through a joint will not collide with each other. You can use the pin joint limits though to prevent the head from doing a full 360 spin around the pin joint anchor.




回答3:


Okay, so I found out that this is an actual bug in Sprite Kit. The fix is to set the sprite's position before setting its physicsBody. I did that and it worked perfectly, as expected.




回答4:


Additionally, not invalidating what was said above, but apparently the physics engine assumes the scene's anchorPoint is left at (0, 0). If you change it to something else, the physics engine will still treat it like (0, 0).



来源:https://stackoverflow.com/questions/19666719/why-wont-this-skphysicsjointpin-keep-these-2-sprites-together

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!