0

ムカデなどの体節のある生き物を想像してみてください。ヘッド セグメントの制御により、ボディ セグメントはポイントによって前のボディ セグメントに接続されます。

頭が動くと (現時点では 8 つの基本方向/基本方向間)、ポイントはその回転に関連して移動します。

public static Vector2 RotatePoint(Vector2 pointToRotate, Vector2 centerOfRotation, float angleOfRotation)
{
    Matrix rotationMatrix = Matrix.CreateRotationZ(angleOfRotation);
    return Vector2.Transform(pointToRotate - centerOfRotation, rotationMatrix);
}

ここに図を投稿するつもりでしたが、ご存知のように...

 center(2)      point(2)                      center(1)    point(1)



                                                     point(1)                    

                point(2)    ^                                        |
                           / \                                       |
                            |                                        |
 center(2)                                           center(1)      \ /
                                                                     V

ベーススプライトに四角形のプロパティ/フィールドを使用することを考えましたが、

private Rectangle bounds = new Rectangle(-16, 16, 32, 32);

ボディ セグメント内の事前定義されたポイントがヘッド スプライトの境界内にとどまっていることを確認します。
私は現在やっていますが:

     private static void handleInput(GameTime gameTime)
    {
        Vector2 moveAngle = Vector2.Zero;

        moveAngle += handleKeyboardMovement(Keyboard.GetState()); // basic movement, combined to produce 8 angles
                                                                  // of movement

        if (moveAngle != Vector2.Zero)
        {
            moveAngle.Normalize();
            baseAngle = moveAngle;
        }

        BaseSprite.RotateTo(baseAngle);

        BaseSprite.LeftAnchor = RotatePoint(BaseSprite.LeftAnchor,
 BaseSprite.RelativeCenter, BaseSprite.Rotation); // call RotatePoint method

        BaseSprite.LeftRect = new Rectangle((int)BaseSprite.LeftAnchor.X - 1,
 (int)BaseSprite.LeftAnchor.Y - 1, 2, 2); 
 // All segments use a field/property that is a point which is suppose to rotate around the center
        // point of the sprite (left point is (-16,0) right is (16,0) initially
        // I then create a rectangle derived from that point to make use of the .Intersets method of the
        // Rectangle class

        BodySegmentOne.RightRect = BaseSprite.LeftRect; // make sure segments are connected?

        BaseSprite.Velocity = moveAngle * wormSpeed;

        //BodySegmentOne.RightAnchor = BaseSprite.LeftAnchor;

        if (BodySegmentOne.RightRect.Intersects(BaseSprite.LeftRect)) // as long as there two rects occupy the 
        {                                                             // same space move segment with head

            BodySegmentOne.Velocity = BaseSprite.Velocity;
        }

    }

現状では、セグメントは頭と一緒に移動しますが、平行に移動します。セグメントが頭に引っ張られているので、セグメントのより微妙な動きを得たいと思います。

そのような動きのコーディングは、ここにあるものよりもはるかに複雑になることを理解しています. この問題をどのように見るべきかについてのヒントや指示をいただければ幸いです。

4

1 に答える 1

0

Farseer のような物理エンジンを使用して何をする必要があるかを説明しますが、独自の物理エンジンを作成する場合も同じです。

  1. ムカデの体の関節点ごとにボディを作成します。
  2. 各ポイントに接続される外側のシェルをカプセル化する Shape を作成します。
  3. フィクスチャを使用してボディとシェイプを取り付けます。これにより、ムカデに 1 つのリンクが作成されます。
  4. SliderJoint を使用して複数のリンクをアタッチします。

たとえば、各リンクの外殻が円であると仮定すると、2 つのリンクを作成してそれらを結合する方法は次のとおりです。

    Fixture fix1 = FixtureFactory.CreateCircle(_world, 0.5f, 1, new Vector2(-5, 5));
    fix1.Body.BodyType = BodyType.Dynamic;

    Fixture fix2 = FixtureFactory.CreateCircle(_world, 0.5f, 1, new Vector2(5, 5));
    fix2.Body.BodyType = BodyType.Dynamic;

    JointFactory.CreateSliderJoint(_world, fix1.Body, fix2.Body, Vector2.Zero, Vector2.Zero, 10, 15);

これで、任意のボディに力を適用したり、形状に衝突したりすると、2 番目のジョイントがドラッグされます。

これはすべてただの物理学です - 本当にしたいのであれば、独自のものを実装することができます. ;)

于 2012-05-24T20:34:36.267 に答える