0

I am making a 3D game in Monogame and I am still very early on the the development of it, I am currently making a health system for the player so that when the player (currently a ball) hits the other ball text saying "You have died!" pops up.

I have that all working, that isn't the issue, the issue is when it does, the models go horrible, these imgurs are screenshots to help show what I am talking about: before https://i.stack.imgur.com/a6Tuw.png and after https://i.stack.imgur.com/xGVsT.png

The code for my drawing and adding the models is all very simple:

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();
        }
    }
}

So yeah, hoping that this is more of an effect thing that I can fix with some kind of lighting effect, but i have had issues where lighting makes my models just display as black.

jayelj
  • 47
  • 6

1 Answers1

1

The SpriteBatch changes properties of your GraphicsDevice when SpriteBatch.End() is called (so when it presents to the device). Resets them to the defaults (or the ones you need) after drawing your health text.

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