1

在 Game1.cs 的代码顶部,我有:

private float angle = 0f;
private float angleRightLeft = 0f;
private float angleUpDown = 0f;
private bool rotationDirection;
private int terrainWidth = 4;
private int terrainHeight = 3;
private float[,] heightData;

在 draw 方法中,我有以下代码:

protected override void Draw(GameTime gameTime)
{
    graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
    device.Clear(Color.Black);
    RasterizerState rs = new RasterizerState();
    rs.CullMode = CullMode.None;
    rs.FillMode = FillMode.WireFrame;
    device.RasterizerState = rs;
    if (rotationDirection == true)
    {
        worldMatrix = Matrix.CreateFromAxisAngle(this.rotation.Left, 
                                                 angleRightLeft);
        worldMatrix = Matrix.CreateTranslation(-terrainWidth / 2.0f,
                                               0,
                                               terrainHeight / 2.0f) *
                                               Matrix.CreateRotationY(angleRightLeft);
    }
    else
    {
        worldMatrix = Matrix.CreateTranslation(-terrainWidth / 2.0f,
                                               0,
                                               terrainHeight / 2.0f) *
                                               Matrix.CreateRotationX(angleUpDown);
    }
    effect.CurrentTechnique = effect.Techniques["ColoredNoShading"];
    effect.Parameters["xView"].SetValue(viewMatrix);
    effect.Parameters["xProjection"].SetValue(projectionMatrix);
    effect.Parameters["xWorld"].SetValue(worldMatrix);
}

和按键处理输入法:

private void ProcessInput(float amount)
{
    previousState = currentState;
    currentState = Mouse.GetState();
    Vector3 moveVector = new Vector3(0 , 0 , 0);
    KeyboardState keyState = Keyboard.GetState();
    if (keyState.IsKeyDown(Keys.Up) || keyState.IsKeyDown(Keys.W))
    {
        angleUpDown += 0.05f;
        rotationDirection = false;
    }

    if (keyState.IsKeyDown(Keys.Down) || keyState.IsKeyDown(Keys.S))
    {
        angleUpDown -= 0.05f;
        rotationDirection = false;
    }

    if (keyState.IsKeyDown(Keys.Right) || keyState.IsKeyDown(Keys.D))
    {
        angleRightLeft += 0.05f;
        rotationDirection = true;
    }

    if (keyState.IsKeyDown(Keys.Left) || keyState.IsKeyDown(Keys.A))
    {
        angleRightLeft -= 0.05f;
        rotationDirection = true;
    }

    if (keyState.IsKeyDown(Keys.Q))
        cameraPosition += new Vector3(0, 1, 0);
    if (keyState.IsKeyDown(Keys.Z))
        cameraPosition += new Vector3(0, -1, 0);
    if (keyState.IsKeyDown(Keys.Escape))
    {
        this.graphics.PreferredBackBufferWidth = 800;
        this.graphics.PreferredBackBufferHeight = 600;
        this.graphics.IsFullScreen = false;
        this.graphics.ApplyChanges();
    }
    if (this.graphics.PreferredBackBufferWidth < 1920)
    {
       /*
       if (WasMouseLeftClick())
       {
           changeScreenNode(this.graphics, 1920, 1080, true);
       }*/

       if (WasDoubleClick())
       {
           changeScreenNode(this.graphics, 1920, 1080, true);
       }
    }

    if (WasMouseLeftClick())
    {
        previousClick = DateTime.Now;
    }
}

以及更新方法:

protected override void Update(GameTime gameTime)
{
    fpsm.Update();
    float timeDifference = (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f;
    ProcessInput(timeDifference);
    modelRotation += (float)gameTime.ElapsedGameTime.TotalMilliseconds *
                            MathHelper.ToRadians(0.1f);
    base.Update(gameTime);
}

问题是,当我按下 D 按钮并将地形向右旋转时,如果停止按下 D 并按下 W 以向上旋转地形,那么地形首先会移回其原始位置。

我希望它保持在我按下 D 或 A 或 S 或 W 后的位置,当我点击另一个键时,它会从那里继续,而不是先重置到原来的位置。

我想我需要在 draw 方法中改变一些东西。

当我单击一个键然后单击另一个键时,我该如何做到这一点,它将从停止的位置旋转而不是首先返回/重置到其原始位置?

编辑**

这就是我在 draw 方法中所做的:

if (rotationDirection == true)
            {
                worldMatrix = Matrix.CreateFromAxisAngle(this.rotation.Left, angleRightLeft);
                worldMatrix = Matrix.CreateTranslation(-terrainWidth / 2.0f, 0, terrainHeight / 2.0f) * Matrix.CreateRotationY(angleRightLeft);
                oldPosition = worldMatrix;
            }
            else
            {
                worldMatrix = Matrix.CreateTranslation(-terrainWidth / 2.0f, 0, terrainHeight / 2.0f) * Matrix.CreateRotationX(angleUpDown);
                oldPosition = worldMatrix;
            }

oldPosition 是 Matrix 类型。然后在键处理方法中,我对每个按下的键执行:worldMatrix = oldPosition;

if (keyState.IsKeyDown(Keys.Up) || keyState.IsKeyDown(Keys.W))
            {
                angleUpDown += 0.05f;
                rotationDirection = false;
                worldMatrix = oldPosition;
            }

但它仍然不能正常工作。我做错了什么 ?

4

1 回答 1

2

如果我正确阅读您的问题,您希望在更改输入方向时保持先前的旋转。如果是这种情况,您可以通过替换它来实现:

if (rotationDirection == true)
        {
            worldMatrix = Matrix.CreateFromAxisAngle(this.rotation.Left, angleRightLeft);
            worldMatrix = Matrix.CreateTranslation(-terrainWidth / 2.0f, 0, terrainHeight / 2.0f) * Matrix.CreateRotationY(angleRightLeft);
            oldPosition = worldMatrix;
        }
        else
        {
            worldMatrix = Matrix.CreateTranslation(-terrainWidth / 2.0f, 0, terrainHeight / 2.0f) * Matrix.CreateRotationX(angleUpDown);
            oldPosition = worldMatrix;
        }

有了这个

worldMatrix = Matrix.CreateTranslation(-terrainWidth / 2.0f, 0, terrainHeight / 2.0f) * Matrix.CreateRotationX(angleUpDown) * Matrix.CreateRotationY(angleLeftRight);

您现有的代码一次只使用一个轴旋转矩阵。如果您在下一次更新/绘制时更改了方向,它会将前一个轴重置为零。上面更新的代码使用了这两个值。除此之外,您还可以像这样使用 Matrix.CreateFromYawPitchRoll (我可能在这里订购错误,所以请仔细检查):

worldMatrix = Matrix.CreateTranslation(-terrainWidth / 2.0f, 0, terrainHeight / 2.0f) * Matrix.CreateFromYawPitchRoll(angleUpDown, angleLeftRight, 0);
于 2013-10-22T03:41:53.050 回答