我尝试了此处发布的解决方案,但没有解决问题。没有人在那里回应我的请求,因为该问题已被标记为已回答。
我让玩家跳过屏幕抓住绳子。抓取是通过在绳段和玩家之间建立SKPhysicsJointPin
来实现的。绳索本身由许多段组成,通过SKPhysicsJointPin
相互连接。这些行为符合预期。然而,玩家似乎连接了大约一秒钟,但随着玩家和绳索一起摆动,他们之间的关节伸展,玩家完全脱离屏幕。
以下是玩家(猴子)被添加到场景中的地方:
- (void)addMonkeyToWorld
{
SKSpriteNode *monkeySpriteNode = [SKSpriteNode spriteNodeWithImageNamed:@"Monkey"];
// Basic properties
monkeySpriteNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:monkeySpriteNode.size];
monkeySpriteNode.physicsBody.density = physicsParameters.monkeyDensity;
monkeySpriteNode.physicsBody.restitution = physicsParameters.monkeyRestitution;
monkeySpriteNode.physicsBody.linearDamping = physicsParameters.monkeyLinearDamping;
monkeySpriteNode.physicsBody.angularDamping = physicsParameters.monkeyAngularDamping;
monkeySpriteNode.physicsBody.velocity = physicsParameters.monkeyInitialVelocity;
// Collision properties
monkeySpriteNode.physicsBody.categoryBitMask = monkeyCategory;
monkeySpriteNode.physicsBody.contactTestBitMask = ropeCategory;
monkeySpriteNode.physicsBody.collisionBitMask = 0x0;
monkeySpriteNode.physicsBody.usesPreciseCollisionDetection = YES;
}
以下是整理联系人事件的地方:
- (void)didBeginContact:(SKPhysicsContact *)contact
{
// Sort which bodies are which
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask > contact.bodyB.categoryBitMask) {
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
else {
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
// Verify that the two bodies were the monkey and rope, then handle collision
if ((firstBody.categoryBitMask & ropeCategory) != 0 && (secondBody.categoryBitMask & monkeyCategory) != 0)
{
[self monkey:secondBody didCollideWithRope:firstBody atPoint:contact.contactPoint];
}
}
这是在玩家和绳索之间添加接头的地方:
- (void)monkey:(SKPhysicsBody *)monkeyPhysicsBody didCollideWithRope:(SKPhysicsBody *)ropePhysicsBody atPoint:(CGPoint)contactPoint
{
if (monkeyPhysicsBody.joints.count == 0) {
// Create a new joint between the monkey and the rope segment
CGPoint convertedMonkeyPosition = CGPointMake(monkeyPhysicsBody.node.position.x + sceneWidth/2., monkeyPhysicsBody.node.position.y + sceneHeight/2.);
CGPoint convertedRopePosition = CGPointMake(ropePhysicsBody.node.position.x + sceneWidth/2., ropePhysicsBody.node.position.y + sceneHeight/2.);
CGFloat leftMostX = convertedMonkeyPosition.x < convertedRopePosition.x ? convertedMonkeyPosition.x : convertedRopePosition.x;
CGFloat bottomMostY = convertedMonkeyPosition.y < convertedRopePosition.y ? convertedMonkeyPosition.y : convertedRopePosition.y;
CGPoint midPointMonkeyAndRope = CGPointMake(leftMostX + fabsf(ropePhysicsBody.node.position.x - monkeyPhysicsBody.node.position.x) / 2.,
bottomMostY + fabsf(ropePhysicsBody.node.position.y - monkeyPhysicsBody.node.position.y) / 2.);
SKPhysicsJointPin *jointPin = [SKPhysicsJointPin jointWithBodyA:monkeyPhysicsBody bodyB:ropePhysicsBody anchor:midPointMonkeyAndRope]; // FIXME: Monkey-rope joint going to weird position
jointPin.upperAngleLimit = M_PI/4;
jointPin.shouldEnableLimits = YES;
[self.scene.physicsWorld addJoint:jointPin];
}
}
任何想法会导致SKPhysicsJointPin
伸展?
这个问题与我在这里发布的另一个问题有关。我会在这里为任何出现的人重复答案。
我在我的GameScene.m中添加了以下方便的方法。
-(CGPoint)convertSceneToFrameCoordinates:(CGPoint)scenePoint
{
CGFloat xDiff = myWorld.position.x - self.position.x;
CGFloat yDiff = myWorld.position.y - self.position.y;
return CGPointMake(scenePoint.x + self.frame.size.width/2 + xDiff, scenePoint.y + self.frame.size.height/2 + yDiff);
}
我用这种方法来添加关节。它处理所有需要处理的坐标系变换,这些变换会导致此问题中提出的问题。例如,我添加关节的方式
CGPoint convertedRopePosition = [self convertSceneToFrameCoordinates:ropePhysicsBody.node.position];
SKPhysicsJointPin *jointPin = [SKPhysicsJointPin jointWithBodyA:monkeyPhysicsBody bodyB:ropePhysicsBody anchor:convertedRopePosition];
jointPin.upperAngleLimit = M_PI/4;
jointPin.shouldEnableLimits = YES;
[self.scene.physicsWorld addJoint:jointPin];