通常、スプライトを物理演算と直接操作の両方で駆動することは望ましくありません。基本的に、スプライトの制御をめぐって物理エンジンと戦っています。
ボックスに物理演算を適用する代わりに、物理演算とアクションを組み合わせようとする代わりに、定期的なフレーム更新を行ってスプライトを移動および回転させることを検討することもできます。ほとんどの物理エンジンには、パペットのように動かされ、衝突を適切にトリガーする物理オブジェクトを持つ方法がありますが、物理エンジンによって直接制御されることはありません。それを調べると、より良い結果が得られるかもしれません。
編集:
必要なモーションを実現するには、 update() 関数 (または Cocos2D に相当するもの - 現時点では SpriteKit の方が詳しい) を使用して直接アニメーション化します。(以下の未テストのコード。)
ポイント/秒、たとえば100の定数x速度から始めたいと思います。更新()関数では、最後の更新()関数以降、秒単位でデルタを撮影し、その速度を掛けて取得します。 x位置の変化:
float newX = oldX + delta * xVelocity;
ジャンプを行うには、「isJumping」BOOL を保持する必要があります。YES の場合は、放物線の Y 距離を追加して、ボックスを回転させます。これを行う簡単な方法は、ジャンプしたい X 距離を 0 から 1 にランプし、それを放物線モーションにマッピングすることです。
float newY = 0; // zero is the ground plane
if (self.isJumping) {
self.jumpRamp += delta * xVelocity / jumpLength;
if (self.jumpRamp > 1.0) {
self.zRotation = self.jumpRamp * M_PI;
// Map the jump ramp onto (-1,1), and then square it to get parabolic motion
// Since the jump ramp goes from (0,1), we subtract .5 and multiply by 2
// to get a range from (-1, 1). Then we square that.
float parabolic = ((self.jumpRamp - .5) * 2) * (self.jumpRamp - .5) * 2));
// This yields (0,1), with the parabola pointing up. We need to
// invert it, scale it, and move it up so the end points are on the "floor".
newY = self.maxJumpHeight * (1.0 - parabolic);
} else {
self.isJumping = NO;
self.zRotation = 0;
self.jumpRamp = 0;
}
}
これで、必要なモーションができました。あとは衝突検出だけです。これは、以前とまったく同じ方法で実行できます。ボックスを物理演算から切り離すだけです (Box2D を使用すると、「動的」ボディの代わりに「キネマティック」ボディを使用するように見えます)。以前と同様に衝突メッセージが表示されますが、物理やアクションに頼るのではなく、ボックスの動作を直接制御します。