1

我真的不知道这里出了什么问题。游戏看起来很有趣。我注意到的第一件事是,当玩家移动时,相机会先于头像移动,因此相机会稍微从头像的头部伸出。然后我注意到,当你从侧面看化身时,你可以看到他的肩膀和胸腔(在我构建的动画播放器和 Maya 中都没有这样做)。我注意到的下一件事是当玩家向前移动时,地面开始闪烁。我是在调用draw方法错误还是什么?

这是我正在使用的相机类

public class Camera : Microsoft.Xna.Framework.GameComponent 
{ 
    //Cam Matrices 
    //viw is composed of position, direction, and up vectors 
    public Matrix view { get; protected set; } 
    public Matrix projection { get; protected set; } 

    //to move the camera 
    //used to recreate view matrix each frame 
    public Vector3 cameraPosition { get; protected set; } 
    public Vector3 cameraDirection; //not the target/ point camera is looking at a relative direction camrea is faceing 
    //to find target add the cameraPosition and cameraDirection togeater 
    public Vector3 cameraUp; 
    public Vector3 target; 

    //camera controls 
    float speed = 3; 


    MouseState prevMouseState; 

    // Pi/180 = 1 degree 
    // Max yaw/pitch variables 
    //this is for moving the head only not the body 
    float totalYaw = MathHelper.PiOver2; 
    public float currentYaw = 0; 
    float totalPitch = MathHelper.PiOver2; 
    public float currentPitch = 0; 


    public float leftTrigYaw; 
    public float rightTrigYaw; 

    //constructor 
    public Camera(Game game, Vector3 pos, Vector3 target, Vector3 up) 
        : base(game) 
    { 
        //build camera view matrix 
        cameraPosition = pos; 
        cameraDirection = target - pos; 
        cameraDirection.Normalize(); //Convert to magintue 1 

        //make it easy to apply differt speeds to movement of camera 
        cameraUp = up; 
        CreateLookAt(); 



        projection = Matrix.CreatePerspectiveFieldOfView 
            ( 
            MathHelper.PiOver4, 
            (float)Game.Window.ClientBounds.Width / (float)Game.Window.ClientBounds.Height, 
            1, 3000); 
    } 

    private void CreateLookAt() 
    { 
        //middle variable is the target! 
        view = Matrix.CreateLookAt(cameraPosition, cameraPosition + cameraDirection, cameraUp); 

    } 


    public override void Initialize() 
    { 

        Mouse.SetPosition(Game.Window.ClientBounds.Width / 2, 
            Game.Window.ClientBounds.Height / 2); 
        prevMouseState = Mouse.GetState(); 
        base.Initialize(); 
    } 

    public override void Update(GameTime gameTime) 
    { 
        GamePadState currentState = GamePad.GetState(PlayerIndex.One); 

        //move forward 
        if (currentState.ThumbSticks.Left.Y > 0 || Keyboard.GetState().IsKeyDown(Keys.W)) 
        { 
            //move just on x and x axis Y is controled other places. 
            cameraPosition += new Vector3(cameraDirection.X, 0, cameraDirection.Z) * speed; 
        } 
        //move backward 
        if (currentState.ThumbSticks.Left.Y < 0 || Keyboard.GetState().IsKeyDown(Keys.S)) 
        { 
            //move just on x and x axis Y is controled other places. 
            cameraPosition -= new Vector3(cameraDirection.X, 0, cameraDirection.Z) * speed; 
        } 
        //move left 
        if (currentState.ThumbSticks.Left.X < 0 || Keyboard.GetState().IsKeyDown(Keys.A)) 
        { 
            //cross product of the up and direction vectors can give the side direction 
            cameraPosition += Vector3.Cross(cameraUp, cameraDirection) * speed; 
        } 
        //move right 
        if (currentState.ThumbSticks.Left.X > 0 || Keyboard.GetState().IsKeyDown(Keys.D)) 
        { 
            cameraPosition -= Vector3.Cross(cameraUp, cameraDirection) * speed; 
        } 


        //mouse movements 

        // Yaw rotation 
        float yawAngle = (-MathHelper.PiOver4 / 150) * 
                (Mouse.GetState().X - prevMouseState.X); 

        float padYaw = (-MathHelper.PiOver2 / 50) * 
             (currentState.ThumbSticks.Right.X); 

        if (Math.Abs(currentYaw + yawAngle) < totalYaw) 
        { 
            cameraDirection = Vector3.Transform(cameraDirection, 
                Matrix.CreateFromAxisAngle(cameraUp, yawAngle)); 
            currentYaw += yawAngle; 
        } 

        //rotate left and right  
        if (currentState.ThumbSticks.Right.X < 0 || currentState.ThumbSticks.Right.X > 0) 
        { 
            if (Math.Abs(currentYaw + padYaw) < totalYaw) 
            { 
                cameraDirection = Vector3.Transform(cameraDirection, 
                Matrix.CreateFromAxisAngle(cameraUp, padYaw)); 
                currentYaw += padYaw; 
            } 

        } 

         leftTrigYaw = (MathHelper.PiOver2 / 50) * 
           (currentState.Triggers.Left); 

        if (currentState.Triggers.Left > 0.0f) 
        { 
            cameraDirection = Vector3.Transform(cameraDirection, 
            Matrix.CreateFromAxisAngle(cameraUp, leftTrigYaw)); 
        } 

         rightTrigYaw = (-MathHelper.PiOver2 / 50) * 
           (currentState.Triggers.Right); 

        if (currentState.Triggers.Right > 0.0f) 
        { 
            cameraDirection = Vector3.Transform(cameraDirection, 
            Matrix.CreateFromAxisAngle(cameraUp, rightTrigYaw)); 
        } 


        // Pitch rotation 
        float pitchAngle = (MathHelper.PiOver4 / 150) * 
            (Mouse.GetState().Y - prevMouseState.Y); 

        float padPitch = (-MathHelper.PiOver2 / 50) * 
             (currentState.ThumbSticks.Right.Y); 


        if (Math.Abs(currentPitch + pitchAngle) < totalPitch) 
        { 
            cameraDirection = Vector3.Transform(cameraDirection, 
                Matrix.CreateFromAxisAngle( 
                    Vector3.Cross(cameraUp, cameraDirection), 
                pitchAngle)); 

            currentPitch += pitchAngle; 
        } 

        if (currentState.ThumbSticks.Right.Y < 0 || currentState.ThumbSticks.Right.Y > 0) 
        { 
            if (Math.Abs(currentPitch + padPitch) < totalPitch) 
            { 
                cameraDirection = Vector3.Transform(cameraDirection, 
                Matrix.CreateFromAxisAngle( 
                    Vector3.Cross(cameraUp, cameraDirection), 
                padPitch)); 

                currentPitch += padPitch; 
            } 

        } 


        //reset mouse state 
        target = cameraPosition + cameraDirection; 

        prevMouseState = Mouse.GetState(); 

        //for testing only!! get rid of this when done 
        if (currentState.Buttons.A == ButtonState.Pressed) 
        { 
            //fly upwar 
            cameraPosition += new Vector3(0, 15, 0); 
        } 

        if (currentState.Buttons.B == ButtonState.Pressed) 
        { 
            //fly upwar 
            cameraPosition -= new Vector3(0, 15, 0); 
        } 



        //call camera creat look at method to build new view matrix 
        CreateLookAt(); 

        if (Keyboard.GetState().IsKeyDown(Keys.Escape)) 
        { 
            Game.Exit(); 

        } 
        base.Update(gameTime); 
    } 
} 
 } 

我还使用自定义模型处理程序来绘制地面和头像

public class CModel 
{ 
    public Vector3 Position { get; set; } 
    public Vector3 Rotation { get; set; } 
    public Vector3 Scale { get; set; } 

    public Model Model { get; private set; } 
    private Matrix[] modelTransforms; 

    private GraphicsDevice graphicsDevice; 

    public CModel(Model Model, Vector3 Position, Vector3 Rotation, 
        Vector3 Scale, GraphicsDevice graphicsDevice) 
    { 
        this.Model = Model; 

        modelTransforms = new Matrix[Model.Bones.Count]; 
        Model.CopyAbsoluteBoneTransformsTo(modelTransforms); 

        this.Position = Position; 
        this.Rotation = Rotation; 
        this.Scale = Scale; 

        this.graphicsDevice = graphicsDevice; 
    } 

    public void Draw(Matrix View, Matrix Projection) 
    { 
        // Calculate the base transformation by combining 
        // translation, rotation, and scaling 
        Matrix baseWorld = Matrix.CreateScale(Scale) 
            * Matrix.CreateFromYawPitchRoll( 
                Rotation.Y, Rotation.X, Rotation.Z) 
            * Matrix.CreateTranslation(Position); 

        foreach (ModelMesh mesh in Model.Meshes) 
        { 
            Matrix localWorld = modelTransforms[mesh.ParentBone.Index] 
                * baseWorld; 

            foreach (ModelMeshPart meshPart in mesh.MeshParts) 
            { 
                BasicEffect effect = (BasicEffect)meshPart.Effect; 

                effect.World = localWorld; 
                effect.View = View; 
                effect.Projection = Projection; 

                effect.EnableDefaultLighting(); 
            } 

            mesh.Draw(); 
        } 
    } 
} 

} 

我不知道问题出在哪里,但这是我能想到的唯一两件事会导致问题。感谢您对此的任何帮助。

这是模型的情况。我确信正常情况在 Maya 中是正确的,因为我使用了 Microsoft 在教程中提供的简单模型抽屉,但是您可以在一定程度上看到这些家伙的肩膀和手臂。我无法拍到地面闪烁的照片,因为它发生得太快而无法真正进行屏幕捕捉。但是每次我移动相机时,地面都会上下跳动很多。然后当我停止移动相机环顾四周时停止。我没有调用 camera.Update() 方法,因为它是一个游戏组件并且与 game1 类相关联。 看模型

通过顶部看到他的手臂内侧!

这就是我绘制模型的方式,它是自定义模型类中的绘制方法

public void Draw(Matrix View, Matrix Projection)
    {
        // Calculate the base transformation by combining
        // translation, rotation, and scaling
        Matrix baseWorld = Matrix.CreateScale(Scale)
            * Matrix.CreateFromYawPitchRoll(
                Rotation.Y, Rotation.X, Rotation.Z)
            * Matrix.CreateTranslation(Position);

        foreach (ModelMesh mesh in Model.Meshes)
        {
            Matrix localWorld = modelTransforms[mesh.ParentBone.Index]
                * baseWorld;

            foreach (ModelMeshPart meshPart in mesh.MeshParts)
            {
                BasicEffect effect = (BasicEffect)meshPart.Effect;

                effect.World = localWorld;
                effect.View = View;
                effect.Projection = Projection;

                effect.EnableDefaultLighting();
            }

            mesh.Draw();
        }
    }
4

1 回答 1

1

对于模型上的工件:模型看起来没有正确渲染。您的 DrawPrimitives 调用可能没有为显卡提供正确的数据(您的顶点/索引缓冲区填充错误,或者您的基元类型/计数错误)。尝试以线框模式渲染它,您应该能够看到正在扭曲的三角形,从而产生这些伪影。

至于地面 - 我将通过代码查看更多内容,看看我是否能想到任何东西。

于 2012-05-31T14:03:46.633 回答