SpriteFont让3D DAE模型变得隐蔽,看起来很糟糕

时间:2016-01-17 13:10:32

标签: c# text xna models monogame

我正在使用Monogame进行3D游戏,我现在还很早就开发了它,我正在为玩家制作一个健康系统,以便当玩家(目前是一个球)击中另一个球文时说“你已经死了!”弹出。

我认为一切正常,这不是问题,问题是什么时候,模型变得非常糟糕,这些图片是帮助显示我所说的内容的截图: 在http://i.imgur.com/vF2wCJv.png之前 在http://i.imgur.com/4VLdwqk.png之后

我的绘图代码和添加模型非常简单:

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

namespace Game7
{
    /// <summary>
    /// This is the main type for your game.
    /// </summary>
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SpriteFont font;

        float player_health = 100; 

        Camera camera;
        Floor floor;
        BasicEffect effect;

        Model ball;
        static float player_x = 15;
        static float  player_y = 1;
        static float player_z = 5;

        private Matrix world_ball = Matrix.CreateTranslation(new Vector3(15, 1, 20));
        private Matrix world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
        private Matrix view = Matrix.CreateLookAt(new Vector3(0, 0, 10), new Vector3(0, 0, 0), Vector3.UnitY);
        private Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 800f / 480f, 0.1f, 100f);

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

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            camera = new Camera(this, new Vector3(10f, 1f, 5f), Vector3.Zero, 5f);
            Components.Add(camera);
            floor = new Floor(GraphicsDevice, 40, 40);
            effect = new BasicEffect(GraphicsDevice);



            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            ball = Content.Load<Model>("Ball DAE");
            font = Content.Load<SpriteFont>("basicFont");




            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// game-specific content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here

        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            // TODO: Add your update logic here
            KeyboardState kb = Keyboard.GetState();
            if (kb.IsKeyDown(Keys.Escape))
            {
                this.Exit();
            }
            if (kb.IsKeyDown(Keys.Left))
            {
                player_x = player_x + 0.05f;
                world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
                if (IsCollision(ball, world_player, ball, world_ball))
                {
                    player_x = player_x - 0.05f;
                    world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
                    player_health = 0;
                }
            }
            if (kb.IsKeyDown(Keys.Right))
            {
                player_x = player_x - 0.05f;
                world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
                if (IsCollision(ball, world_player, ball, world_ball))
                {
                    player_x = player_x + 0.05f;
                    world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
                    player_health = 0;
                }
            }
            if (kb.IsKeyDown(Keys.Up))
            {
                player_z = player_z + 0.05f;
                world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
                if (IsCollision(ball, world_player, ball, world_ball))
                {
                    player_z = player_z - 0.05f;
                    world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
                    player_health = 0;
                }
            }
            if (kb.IsKeyDown(Keys.Down))
            {
                player_z = player_z - 0.05f;
                world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
                if (IsCollision(ball, world_player, ball, world_ball))
                {
                    player_z = player_z + 0.05f;
                    world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
                    player_health = 0;
                }
            }

            base.Update(gameTime);
        }

        private bool IsCollision(Model model1, Matrix world1, Model model2, Matrix world2)
        {
            for (int meshIndex1 = 0; meshIndex1 < model1.Meshes.Count; meshIndex1++)
            {
                BoundingSphere sphere1 = model1.Meshes[meshIndex1].BoundingSphere;
                sphere1 = sphere1.Transform(world1);

                for (int meshIndex2 = 0; meshIndex2 < model2.Meshes.Count; meshIndex2++)
                {
                    BoundingSphere sphere2 = model2.Meshes[meshIndex2].BoundingSphere;
                    sphere2 = sphere2.Transform(world2);

                    if (sphere1.Intersects(sphere2))
                        return true;
                }
            }
            return false;
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here
            if (player_health == 0)
            {
                drawHealth();
            }
            floor.Draw(camera, effect);
            DrawPlayer(ball, world_player, view, projection);
            DrawModel(ball, world_ball, camera.View, camera.Projection);


            base.Draw(gameTime);
        }

        private void DrawModel(Model model, Matrix world_ball, Matrix view, Matrix projection)
        {
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.World = world_ball;
                    effect.View = camera.View;
                    effect.Projection = camera.Projection;
                }

                mesh.Draw();
            }
        }

        private void DrawPlayer(Model model, Matrix world_player, Matrix view, Matrix projection)
        {
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.World = world_player;
                    effect.View = camera.View;
                    effect.Projection = camera.Projection;
                }

                mesh.Draw();
            }
        }

        private void drawHealth()
        {
            spriteBatch.Begin();

            spriteBatch.DrawString(font, "You have died", new Vector2(100, 100), Color.Black);

            spriteBatch.End();
        }
    }
}

所以是的,希望这更像是一种效果,我可以通过某种照明效果来修复,但我遇到的问题是灯光使我的模型只显示为黑色。

1 个答案:

答案 0 :(得分:1)

当调用SpriteBatch.End()时,SpriteBatch会更改GraphicsDevice的属性(因此当它呈现给设备时)。 在绘制健康文本后,将它们重置为默认值(或您需要的默认值)。

GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
GraphicsDevice.DepthStencilState = DepthStencilState.Default; // this should be the one you are looking for