5

iOS 7 で新しいスプライト キットを使用して、単純な永遠に跳ねるボールを作成しようとしています。重力を設定します。

 scene.physicsWorld.gravity=CGVectorMake(0, -9);

そして、私が設定したボール本体のために:

ball.physicsBody=[SKPhysicsBody bodyWithCircleOfRadius:17];
ball.physicsBody.mass=1;
ball.physicsBody.restitution=1;
ball.physicsBody.linearDamping=0;
ball.physicsBody.angularDamping=0;

ここでのボールは単なる SKSpriteNode です。しかし、問題が 1 つあります。跳ね返るたびに、位置が少しずつ高くなっていきます。そして数分で、ボールはほぼ画面の上部にあります。誰でもこの問題を解決できますか。ボールを毎回同じ位置にバウンドさせたいだけです(たとえば、画面の中央など)。ありがとう。

4

2 に答える 2

15

ここにはおそらく 2 つの問題があります。

  1. ボールがバウンドするときの衝突には、ボールとボールが跳ね返るエッジ ループの 2 つのボディが関係します。衝突でエネルギーが失われないようにするには、両方のボディの摩擦と反発をゼロにする必要があります。

  2. ただし、それを行ったとしても、多くの物理エンジン (SpriteKit を含む) では、浮動小数点の丸め誤差が原因で、このような状況で問題が発生します。衝突後にボディの速度を一定に保ちたい場合は、強制するのが最善であることがわかりました。didEndContact:またはdidSimulatePhysicsハンドラーを使用して移動ボディの速度をリセットし、衝突前と同じ速度になります (ただし、反対方向に)。

上下にバウンドするボールがある場合、その速度のリセットは簡単です。速度ベクトルの垂直成分を無効にするだけです。

ball.physicsBody.velocity = CGVectorMake(0, -ball.physicsBody.velocity.dy);

角度のある面で跳ね返る場合は、もう少し複雑です。速度ベクトルを正規化して (つまり、大きさが 1.0 になるようにスケーリングして) 衝突後の方向を取得し、それをスケーリングして必要な速度にします。この種のベクトル演算を行うときは、ベクトルを次のように変換してGLKVector2、GLKit フレームワークの高速演算関数を使用できるようにします。

GLKVector2 velocity = GLKVector2Make(ball.physicsBody.velocity.dx, ball.physicsBody.velocity.dy);
GLKVector2 direction = GLKVector2Normalize(velocity);
GLKVector2 newVelocity = GLKVector2MultiplyScalar(direction, newSpeed);
ball.physicsBody.velocity = CGVectorMake(newVelocity.x, newVelocity.y);
于 2013-09-30T17:31:09.350 に答える