相机在随机时间后出现口吃

时间:2016-12-09 18:48:19

标签: c# visual-studio-2015 camera xna-4.0

我有一个问题,即我的相机在经过一段时间后移动时会开始断断续续。这不是运动本身的情况。这运行得非常顺利。只是相机开始口吃。小通知我在monogame工作

这是主要的代码

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Cube_chaser
{ 
    public class CubeChaserGame : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Camera camera;
        Map map;
        BasicEffect effect;

    private Vector2 mouseRotationBuffer;
    private MouseState currentMouseState, previousMouseState;
    public Vector3 moveVector = Vector3.Zero;


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

    }

    protected override void Initialize()
    {
        camera = new Camera(this, new Vector3(0.5f, 0.5f, 0.5f), Vector3.Zero, 5f);
        Components.Add(camera);
        effect = new BasicEffect(GraphicsDevice);
        map = new Map(GraphicsDevice);
        IsMouseVisible = false;
        graphics.IsFullScreen = true;
        previousMouseState = Mouse.GetState();
        base.Initialize();

    }

    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);
    }

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

    protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
            Exit();
        float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

        KeyboardState keyState = Keyboard.GetState();
        currentMouseState = Mouse.GetState();
        moveVector = Vector3.Zero;


        //Handle the mouse movement for rotation

        float deltaX, deltaY;

        if (currentMouseState != previousMouseState)
        {
            //We need to save the mouse location for further use
            deltaX = (currentMouseState.X - (GraphicsDevice.Viewport.Width / 2));
            deltaY = (currentMouseState.Y - (GraphicsDevice.Viewport.Height / 2));

            mouseRotationBuffer.X -= (0.09f * deltaX * dt);
            mouseRotationBuffer.Y -= (0.09f * deltaY * dt);

            if (mouseRotationBuffer.Y < MathHelper.ToRadians(-75.0f))
            {
                mouseRotationBuffer.Y = mouseRotationBuffer.Y - (mouseRotationBuffer.Y - MathHelper.ToRadians(-75.0f));
            }

            if (mouseRotationBuffer.Y > MathHelper.ToRadians(75.0f))
            {
                mouseRotationBuffer.Y = mouseRotationBuffer.Y - (mouseRotationBuffer.Y - MathHelper.ToRadians(75.0f));
            }

            camera.Rotation = new Vector3(-MathHelper.Clamp(mouseRotationBuffer.Y, MathHelper.ToRadians(-75.0f), MathHelper.ToRadians(75.0f)), MathHelper.WrapAngle(mouseRotationBuffer.X), 0);

            deltaX = 0;
            deltaY = 0;
        }

        try { Mouse.SetPosition(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2); }
        catch { }

        if (keyState.IsKeyDown(Keys.W)) moveVector.Z = 1;
        if (keyState.IsKeyDown(Keys.S)) moveVector.Z = -1;
        if (keyState.IsKeyDown(Keys.A)) moveVector.X = 1;
        if (keyState.IsKeyDown(Keys.D)) moveVector.X = -1;
        if (keyState.IsKeyDown(Keys.Space) && camera.Position.Y >= 0.5f && camera.Position.Y <= 0.8f) moveVector.Y = 0.05f;
        // if (camera.Position.Y == 0.8f&&camera.Position.Y>=0.5f)camera.moveVector.Y=-0.01f;
        if (moveVector != Vector3.Zero)
        {
            //We don't want to make the player move faster when it is going diagonally.
            moveVector.Normalize();
            //Now we add the smoothing factor and speed factor
            moveVector *= (dt * camera.cameraSpeed);

            Vector3 newPosition = camera.PreviewMove(moveVector);

            bool moveTrue = true;

            if (newPosition.X < 0 || newPosition.X > Map.mazeWidth) moveTrue = false;
            if (newPosition.Z < 0 || newPosition.Z > Map.mazeHeight) moveTrue = false;
            foreach (BoundingBox boxes in map.GetBoundsForCell((int)newPosition.X, (int)newPosition.Z))
            {
                if (boxes.Contains(newPosition) == ContainmentType.Contains)
                {
                    moveTrue = false;
                }
            }

            if (moveTrue) camera.Move(moveVector);
            previousMouseState = currentMouseState;
            camera.Update(gameTime);
            base.Update(gameTime);
        }
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.Black);
        map.Draw(camera, effect);
        // TODO: Add your drawing code here

        base.Draw(gameTime);
    }
}
}

这是相机的代码:

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;

namespace Cube_chaser
{
    public class Camera: GameComponent
    {
        #region Fields
        public Vector3 cameraPosition;
        public Vector3 cameraRotation;
        public float cameraSpeed;
        private Vector3 cameraLookAt;



        #endregion
    #region Properties
    public Matrix Projection
    {
        get;
        protected set;
    }       

    public Matrix View
    {
        get
        {
            return Matrix.CreateLookAt(cameraPosition, cameraLookAt, Vector3.Up);
        }
    }

    public Vector3 Position
    {
        get { return cameraPosition; }
        set
        {
            cameraPosition = value;
            UpdateLookAt();
        }
    }

    public Vector3 Rotation
    {
        get { return cameraRotation; }
        set
        {
            cameraRotation = value;
            UpdateLookAt();
        }
    }

    #endregion

    #region Constructor
    public Camera (Game game, Vector3 position, Vector3 rotation, float speed):base(game)
    {

        cameraSpeed = speed;

        //Setup the projection Matrix
        Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, game.GraphicsDevice.Viewport.AspectRatio, 0.05f, 100.0f);

        MoveTo(position, rotation);


    }

    #endregion

    #region Helper Methods
    //Set the camera its position and rotation
    public void MoveTo(Vector3 pos, Vector3 rot)
    {
        Position = pos;
        Rotation = rot;

    }

    //Updating the look at vector
    public void UpdateLookAt()
    {
        //Built a rotation matrix to rotate the direction we are looking
        Matrix rotationMatrix = Matrix.CreateRotationX(cameraRotation.X) * Matrix.CreateRotationY(cameraRotation.Y);

        // Build a look at offset vector 
        Vector3 lookAtOffset = Vector3.Transform(Vector3.UnitZ, rotationMatrix);

        //Update our camera's look at the vector
        cameraLookAt = (cameraPosition + lookAtOffset);

    }


    //Method to create movement and to check if it can move:)
    public Vector3 PreviewMove(Vector3 amount)
    {
        //Create a rotation matrix to move the camera
        Matrix rotate = Matrix.CreateRotationY(cameraRotation.Y);

        //Create the vector for movement
        Vector3 movement = new Vector3(amount.X, amount.Y, amount.Z);
        movement = Vector3.Transform(movement, rotate);

        // Give the value of the camera position +ze movement
        return (cameraPosition+movement);
    }

    //Method that moves the camera when it hasnt'collided with anything
    public void Move(Vector3 scale)
    {
        //Moveto the location
        MoveTo(PreviewMove(scale), Rotation);
    }

    #endregion

    /*public void Update(GameTime gameTime)
    {

    }*/
}
}

知道为什么相机会在一段时间后断断续续? 谢谢,

Jeromer

1 个答案:

答案 0 :(得分:1)

忘记为遇到同样问题的人发布问题的答案。

进行了以下更改以解决问题: 在game1类的构造函数中  IsFixedTimeStep = true; TargetElapsedTime = TimeSpan.FromMilliseconds(16); 这导致固定的时间步长,从而实现平滑的计算