1

我正在尝试编写两个合适的键来以合适的速度更新船舶前进/后退方向的位置,我想出的是:在 Cmodel 中:

//Update method
        public void Update(Vector3 position, Vector3 orientation)  
        {

            //TO DO - Create an updated version of this.local matrix


            this.local *= Matrix.CreateFromYawPitchRoll(orientation.Y, orientation.X, orientation.Z);

            this.local *= Matrix.CreateTranslation(position.X, position.Y, position.Z);
        }

比在 Game1 中:

 protected override void Update(GameTime gameTime)
    {
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        // TODO: Add your update logic here
        //Update the camera
        camera.Update();

       KeyboardState keyState = Keyboard.GetState();

        // The time since Update was called last.
        float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

        float RotationAngle = 0;
        RotationAngle += elapsed;
        float circle = MathHelper.Pi * 2;
        RotationAngle = RotationAngle % circle;

        Vector3 orientation = new Vector3(0, 0, 0);
        Vector3 position = new Vector3(0, 0, 0);


        if (keyState.IsKeyDown(Keys.W))
            orientation.X = RotationAngle;

        if (keyState.IsKeyDown(Keys.S))
            orientation.X = -RotationAngle;

        if (keyState.IsKeyDown(Keys.A))
            orientation.Y = RotationAngle;

        if (keyState.IsKeyDown(Keys.D))
            orientation.Y = -RotationAngle;

        if (keyState.IsKeyDown(Keys.Z))
            orientation.Z = RotationAngle;

        if (keyState.IsKeyDown(Keys.X))
            orientation.Z = -RotationAngle;


        //TO DO - Code two suitable keys to update position in the forward/backward direction of Ship travel at a suitable velocity


        if (keyState.IsKeyDown(Keys.F))
            position.Z = 1f;
        if (keyState.IsKeyDown(Keys.B))
            position.Z = 1f;


        //Update the first model i.e. the Ship
        scene[0].Update(position, orientation);

        base.Update(gameTime);
    }

问题是当我向左或向右旋转船头时,这些按钮仍然像向后和向前一样朝着我(相机)工作。我要添加什么让它在船“鼻子”的方向前后移动?

回答!!!!我所要做的就是将矩阵与不同的矩阵相乘:首先旋转而不是平移,最后是本地!!!谢谢大家的回答。它真的很重要!

this.local = Matrix.CreateFromYawPitchRoll(orientation.Y, orientation.X, orientation.Z) * Matrix.CreateTranslation(position.X, position.Y, position.Z) * this.local;
4

4 回答 4

0

我可能不正确,因为我已经在 AS3 中这样做了。

当你旋转船时,你需要重新计算它的运动。

为简化起见,如果只有XY,并且该按键使您移动 10 个单位(无论您的单位是什么(例如像素))。当您将船旋转到某个角度时,您需要重新计算它在两个轴上X的运动。Y

他的移动函数如下所示:

Ship.X += Math.Cos(currentAngle) * Ship.DefaultMoveUnits;
Ship.Y += Math.Sin(currentAngle) * Ship.DefaultMoveUnits;

的原理相同XYZ

于 2012-11-19T10:36:44.590 回答
0

记住你在学校的数学课!你的“船”在某一点,你有你想要移动它的速度/距离和角度。这是一些帮助的伪代码:

float a = math.rad(angle);
float newX = currentX + math.sin(a) * distanceToMove;
float newZ = currentZ - math.cos(a) * distanceToMove;

这是一个基本的向量计算,但我现在不确定轴,但如果你稍微修改一下 X、Y 和 Z,你应该弄清楚!抱歉,如果上面的公式是错误的,那是很久以前的事了,因为我实际上是这样计算的;)

于 2012-11-19T10:33:23.810 回答
0

为了前进,您需要了解船的方向。这不是问题,因为您已经在代码中设置了方向:Matrix.CreateFromYawPitchRoll(orientation.Y, orientation.X, orientation.Z);
使用此 RotationMatrix 您可以提取船头指向的方向所需的值:

//this method uses 'orientation' as the current orientation of the ship
public Vector3 GetForward()
{
    Matrix rotation = Matrix.CreateFromYawPitchRoll(orientation.Y, orientation.X, orientation.Z);
    //i don't know the matrix structure of XNA, but it should be possible
    //to access each field seperately
    //M13 is here: row 1, column 3
    //M23 is here: row 2, column 3 and so on
    return new Vector3(rotation.M13, rotation.M23, rotation.M33);
}

//now that you got the appropriate vector
//you just can move into the direction of this vector like
Vector3 position = new Vector3(0, 0, 0);
if(keyState.IsKeyDown(Keys.F))
{
    position += ship.GetForward();
}

position *= elapsed;

//update the position of the ship here

您可以使用相同的方法获得右向量和上向量,只需使用旋转矩阵的其他列:

public Vector3 GetRight()
{
    Matrix rotation = Matrix.CreateFromYawPitchRoll(orientation.Y, orientation.X, orientation.Z);
    return new Vector3(rotation.M11, rotation.M21, rotation.M31);
}

public Vector3 GetUp()
{
    Matrix rotation = Matrix.CreateFromYawPitchRoll(orientation.Y, orientation.X, orientation.Z);
    return new Vector3(rotation.M12, rotation.M22, rotation.M32);
}

您可以通过否定相应的向量来获得所有其他方向(向后、向左、向下)。所以要得到你使用的向后方向-GetForward()

于 2012-11-19T10:53:44.407 回答
0

为了让它工作,我所要做的就是改变矩阵乘法:

this.local = Matrix.CreateFromYawPitchRoll(orientation.Y,orientation.X,orientation.Z) * Matrix.CreateTranslation(position.X, position.Y, position.Z) * this.local;

于 2012-11-20T19:52:29.483 回答