0

我有 3 个类:游戏类、相机类和模型类。项目构建并运行,模型出现,当我按下 w 并使其前进时,相机会跟随它,但是当我重新启动项目并旋转模型以面对任何其他方式时,它似乎在俯冲,而不是去是的,我试图实现的是遵循模型的相机,

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace test1
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;



    //Visual components
    Ship ship = new Ship();
    Camera _camera;

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";



    }

   protected override void Initialize()
    {
     //   this.graphics.ToggleFullScreen(); 
        this._camera = new Camera(graphics.GraphicsDevice.Viewport);
        this._camera.LookAt = new Vector3(0.0f, 0.0f, 0.0f);

        this._camera.Position = new Vector3(0.0f, -5000.0f, 1000.0f);


        base.Initialize();
    }


    protected override void LoadContent()
    {
        ship.Model = Content.Load<Model>("Models/p1_wedge");
        ship.Transforms = _camera.SetupEffectDefaults(ship.Model);


    }


    protected override void UnloadContent()
    {
        // TODO: Unload any non ContentManager content here
    }


    protected override void Update(GameTime gameTime)
    {

        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
            Keyboard.GetState().IsKeyDown(Keys.Escape))
            this.Exit();

        // Get some input.
        UpdateInput();




        base.Update(gameTime);
    }

    protected void UpdateInput()
    {
        // Get the game pad state.
        GamePadState currentState = GamePad.GetState(PlayerIndex.One);
        KeyboardState currentKeyState = Keyboard.GetState();

            ship.Update(currentState);



        }


    protected override void Draw(GameTime gameTime)
    {
        graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

        //camera
        this._camera.Update();
        _camera.LookAt = ship.Position;

        Matrix shipTransformMatrix = ship.RotationMatrix
                * Matrix.CreateTranslation(ship.Position);
        DrawModel(ship.Model, shipTransformMatrix, ship.Transforms);



        base.Draw(gameTime);

    }


    public void DrawModel(Model model, Matrix modelTransform, 
Matrix[] absoluteBoneTransforms)
{
//Draw the model, a model can have multiple meshes, so loop
foreach (ModelMesh mesh in model.Meshes)
{
    //This is where the mesh orientation is set
    foreach (BasicEffect effect in mesh.Effects)
    {
        effect.World = 
            absoluteBoneTransforms[mesh.ParentBone.Index] * 
            modelTransform;
        effect.Projection = _camera.ProjectionMatrix;
        effect.View = _camera.ViewMatrix; 
    }


    //Draw the mesh, will use the effects set above.
    mesh.Draw();
}
}


        }
    }

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace test1
{
public class Camera
{

    private Vector3 _position;
    private Vector3 _lookAt;
    private Matrix _viewMatrix;
    private Matrix _projectionMatrix;
    private float _aspectRatio;


 public Camera(Viewport viewport)
{
    this._aspectRatio = ((float)viewport.Width) / ((float)viewport.Height);

    this._projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
                                MathHelper.ToRadians(40.0f),
                                this._aspectRatio,
                                1.0f,
                                10000.0f);
}


 public Matrix[] SetupEffectDefaults(Model myModel)
{
 Matrix[] absoluteTransforms = new Matrix[myModel.Bones.Count];
 myModel.CopyAbsoluteBoneTransformsTo(absoluteTransforms);

 foreach (ModelMesh mesh in myModel.Meshes)
 {
     foreach (BasicEffect effect in mesh.Effects)
     {
         effect.EnableDefaultLighting();
         effect.Projection = ProjectionMatrix;
         effect.View = ViewMatrix;
     }
 }
 return absoluteTransforms;
 }



public Vector3 Position
{
    get { return this._position; }
    set { this._position = value; }
}
public Vector3 LookAt //= Vector3.Zero;

{
    get { return this._lookAt; }
    set { this._lookAt = value; }
}

public Matrix ViewMatrix
{
    get { return this._viewMatrix; }
}
public Matrix ProjectionMatrix
{
    get { return this._projectionMatrix; }
}
public void Update()
{
    this._viewMatrix = 
        Matrix.CreateLookAt(this._position, this._lookAt, Vector3.Up);

}


}
}

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;


namespace test1
{
class Ship
{
    public Model Model;
    public Matrix[] Transforms;

    //Position of the model in world space
    public Vector3 Position = Vector3.Zero;

    //Velocity of the model, applied each frame to the model's position
    public Vector3 Velocity = Vector3.Zero;
    private const float VelocityScale = 5.0f;

    public Matrix RotationMatrix =
 Matrix.CreateRotationX(MathHelper.PiOver2);

    private float rotation;

    public float Rotation
    {
        get { return rotation; }
        set
        {
            float newVal = value;
            while (newVal >= MathHelper.TwoPi)
            {
                newVal -= MathHelper.TwoPi;
            }
            while (newVal < 0)
            {
                newVal += MathHelper.TwoPi;
            }

            if (rotation != value)
            {
                rotation = value;
                RotationMatrix =
                    Matrix.CreateRotationX(MathHelper.PiOver2) *
                    Matrix.CreateRotationZ(rotation);
            }

        }
    }

    public void Update(GamePadState controllerState)
    {

        KeyboardState currentKeyState = Keyboard.GetState();
        if (currentKeyState.IsKeyDown(Keys.A))
            Rotation += 0.10f;
        else
        // Rotate the model using the left thumbstick, and scale it down.
        Rotation -= controllerState.ThumbSticks.Left.X * 0.10f;

        if (currentKeyState.IsKeyDown(Keys.D))
            Rotation -= 0.10f;

        if (currentKeyState.IsKeyDown(Keys.W))
            Velocity += RotationMatrix.Forward * VelocityScale;
        else
        // Finally, add this vector to our velocity.
        Velocity += RotationMatrix.Forward * VelocityScale *
         controllerState.Triggers.Right;

        // In case you get lost, press A to warp back to the center.
        if  (currentKeyState.IsKeyDown(Keys.Enter))
        {
            Position = Vector3.Zero;
            Velocity = Vector3.Zero;
            Rotation = 0.0f;

        }

        Position += Velocity;
        Velocity *= 0.95f;
    }



}
}
4

1 回答 1

1

我会这样做:

架构

我在飞机上展示它以便于理解,但不需要进行计算。

您只需要相机的前向矢量、船的前向矢量、相机到船的距离和相机的仰角矢量。

这样当船移动时会做类似的事情:

 Camera.Forward = Vector3.Lerp( Ship.Forward, Camera.Fordward, 0.05f);
 Camera.Forward.Normalize();
 Camera.Forward*=Camera.Distance;
 Camera.Target = Ship.Target;
 Camera.Source = Ship.Target - Camera.Forward;
 Camera.Position = Camera.Source + Camera.Elevation;

我希望这会有用。

于 2012-11-27T14:42:06.233 回答