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. 为蜈蚣身体的每个关节点创建一个 Body。
  2. 创建一个封装将附加到每个点的外壳的形状。
  3. 使用夹具连接身体和形状。这会在您的蜈蚣中创建一个链接。
  4. 使用 SliderJoint 附加多个链接。

例如 - 假设每个链接的外壳是一个圆圈,下面是如何创建两个链接并将它们连接在一起。

    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);

现在对任何物体施加力或在形状上碰撞将拖动第二个关节 - 就像你想要的那样。

这一切都只是物理原理——所以如果你真的想的话,你可以实现自己的。;)

于 2012-05-24T20:34:36.267 回答