Advertisement

refractoring some code

Started by November 06, 2013 12:29 AM
2 comments, last by Khaiy 11 years, 3 months ago

Hi I have been going over a few xna tutorials to get me started in programing however most of the tutorials i have gone over all have the code in the one class so I have been trying to seperate some code into a player class I have made but when i run the program no player is rendered on the screen. Im not entirly understanding how to do this, anyone with more experience take a look over my code and point me i the right direction. thanks

This is the new player class I created


namespace Tutorial
{
    public class Player : Game
    {
        Space space;
        public EntityModel shipModel;

        public Player()
        {

        }

        public void PlayerInitialize()
        {


        }

        public void LoadModel(ContentManager content)
        {
            space = new Space();
            Box shipColBox = new Box(new Vector3(0, 4f, 0), 0.9f, 0.9f, 0.9f);
            space.Add(shipColBox);
            shipModel = new EntityModel(shipColBox, content.Load<Model>("Models/Ship"), Matrix.Identity* Matrix.CreateScale(0.005f), this);
            shipColBox.Tag = shipModel;
            shipColBox.BecomeDynamic(1);
            Components.Add(shipModel);
        }


        public void PlayerUpdate()
        {



        }


        public void PlayerDraw()
        {




        }

    }
}


This is the game class i have removed the DrawPlayerShip method and tried to place it in the player class and just call the method from the game load content but i dont realy understand what code Im doing wrong


namespace Tutorial
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        //GraphicsDevice device;
        /// <summary>
        /// World in which the simulation runs.
        /// </summary>
        public Space space;

        Player player;
        
        /// <summary>
        /// Controls the viewpoint and how the user can see the world.
        /// </summary>
        public Camera Camera;
        /// <summary>
        /// Graphical model to use for the boxes in the scene.
        /// </summary>
        public Model CubeModel;
        /// <summary>
        /// Graphical model to use for the environment.
        /// </summary>
        public Model terrain;
        /// <summary>
        /// Contains the latest snapshot of the keyboard's input state.
        /// </summary>
        public KeyboardState KeyboardState;
        /// <summary>
        /// Contains the latest snapshot of the mouse's input state.
        /// </summary>
        public MouseState MouseState;

        //public EntityModel shipModel;

        public EntityModel playerModel;

        //public ModelDrawer ModelDrawer;

        public MobileMesh shipMesh;
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredBackBufferWidth = 800;
            graphics.PreferredBackBufferHeight = 600;
            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()
        {
            //Setup the camera.
            Camera = new Camera(this, new Vector3(0, 3, 10), 5);
            
            
           

            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()
        {
            player = new Player();
            //This 1x1x1 cube model will represent the box entities in the space.
            CubeModel = Content.Load<Model>("Models/cube");            

            terrain = Content.Load<Model>("Models/desert");            

            //ModelDrawer = new InstancedModelDrawer(this);
            
            //Construct a new space for the physics simulation to occur within.
            space = new Space();
            space.ForceUpdater.Gravity = new Vector3(0, -9.81f, 0);
           
            DrawTerrain();
            //DrawPlayerShip();
            player.LoadModel(Content);
            
            
        }

        public void DrawTerrain()
        {
            //===============================TERRAIN================================================
            //Create a physical environment from a triangle mesh.
            //First, collect the the mesh data from the model using a helper function.
            //This special kind of vertex inherits from the TriangleMeshVertex and optionally includes
            //friction/bounciness data.
            //The StaticTriangleGroup requires that this special vertex type is used in lieu of a normal TriangleMeshVertex array.
            Vector3[] vertices;
            int[] indices;
            TriangleMesh.GetVerticesAndIndicesFromModel(terrain, out vertices, out indices);
            //Give the mesh information to a new StaticMesh.  
            //Give it a transformation which scoots it down below the kinematic box entity we created earlier.
            var mesh = new StaticMesh(vertices, indices, new AffineTransform(new Vector3(0, -40, 0)));

            //Add it to the space!
            space.Add(mesh);
            //Make it visible too.
            Components.Add(new StaticModel(terrain, mesh.WorldTransform.Matrix, this));
            //======================================================================================         
            
        }

        public void DrawPlayerShip()
        {
            //Box shipColBox = new Box(new Vector3(0, 4f, 0), 0.9f, 0.9f, 0.9f);
            //space.Add(shipColBox);
            //shipModel = new EntityModel(shipColBox, Content.Load<Model>("Models/Ship"), Matrix.Identity * Matrix.CreateScale(0.0005f), this);
            //shipColBox.Tag = shipModel;
            ////shipColBox.LinearVelocity = new Vector3(0,-1,0);
            ////shipColBox.Mass = 0.1f;
            ////shipColBox.BecomeDynamic(1);
            //Components.Add(shipModel);

            //shipColBox.CollisionInformation.Events.DetectingInitialCollision += HandleCollision;

        }

        void HandleCollision(EntityCollidable sender, Collidable other, CollidablePairHandler pair)
        {
            //This type of event can occur when an entity hits any other object which can be collided with.
            //They aren't always entities; for example, hitting a StaticMesh would trigger this.
            //Entities use EntityCollidables as collision proxies; see if the thing we hit is one.
            var otherEntityInformation = other as EntityCollidable;
            if (otherEntityInformation != null)
            {
               // We hit an entity! remove it.
                space.Remove(otherEntityInformation.Entity);
                //Remove the graphics too.
                Components.Remove((EntityModel)otherEntityInformation.Entity.Tag);
            }
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all 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)
        {

            KeyboardState = Keyboard.GetState();
            MouseState = Mouse.GetState();
            //ModelDrawer.Update();

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

            //Update the camera.
            Camera.Update((float)gameTime.ElapsedGameTime.TotalSeconds);            

            #region Block shooting

            if (MouseState.LeftButton == ButtonState.Pressed)
            {
                //If the user is clicking, start firing some boxes.
                //First, create a new dynamic box at the camera's location.
                Box toAdd = new Box(Camera.Position, 1, 1, 1, 1);
                //Set the velocity of the new box to fly in the direction the camera is pointing.
                //Entities have a whole bunch of properties that can be read from and written to.
                //Try looking around in the entity's available properties to get an idea of what is available.
                toAdd.LinearVelocity = Camera.WorldMatrix.Forward * 10;
                //Add the new box to the simulation.
                space.Add(toAdd);

                //Add a graphical representation of the box to the drawable game components.
                EntityModel model = new EntityModel(toAdd, CubeModel, Matrix.Identity, this);
                Components.Add(model);
                toAdd.Tag = model;  //set the object tag of this entity to the model so that it's easy to delete the graphics component later if the entity is removed.
            }


            #endregion

            //Steps the simulation forward one time step.
            space.Update();

            base.Update(gameTime);
        }

        /// <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);

            RasterizerState rasterizerState = new RasterizerState();
            rasterizerState.FillMode = FillMode.Solid;
            GraphicsDevice.RasterizerState = rasterizerState;

            // TODO: Add your drawing code here
            //DrawModels(shipModel, Matrix.CreateScale(0.0005f));
            //ModelDrawer.Draw(Camera.ViewMatrix, Camera.ProjectionMatrix);           
            
            base.Draw(gameTime);
        }

        private void DrawModels(Model model, Matrix world)
        {
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.World = transforms[mesh.ParentBone.Index] * world;

                     //Use the matrices provided by the chase camera
                    effect.View = Camera.ViewMatrix;
                    effect.Projection = Camera.ProjectionMatrix;
                }
                mesh.Draw();
            }
        }

        
    }
}

I'll ask you a couple of questions that might help:

Which method or methods in your code renders things to the screen?

[spoiler]The Draw method in Game1.[/spoiler]

In the code segments you've posted, where is it that you think the player ship should be rendered to the screen? I don't mean which method or code block do you think should handle that, I mean which method calls do you think would cause the player ship to be rendered as the program runs?

[spoiler]I don't see one. I would expect such a method call to be located in the Draw method of the Game1 class, but there isn't one in there. Nor do I see a method call which itself calls a method to render the player's ship on screen.[/spoiler]

Which method, when called, would render the player ship?

[spoiler]To me, it looks like you intend this to be done by the PlayerDraw method in the Player class. But this method is empty, and so even if it were called nothing would happen. But as above, this method isn't called. Also, the way that you have the code laid out suggests that your intent may have been to define Player as a game component, and then call an overloaded Player.Draw method in Game1.Draw. The additional code needed to do something like this isn't there, however, nor does it go well with the PlayerDraw method.[/spoiler]

What are you intending to do/doing when loading content into Player?

[spoiler]Generally you would do something like load a picture or mesh into memory, then store a reference to the picture or mesh in an instantiated Player object. This gives the instance something to be drawn, but does nothing to actually do the drawing.[/spoiler]

There are some other issues, not necessarily related to the problem you're asking about. For example, why does Player inherit from Game? Doing something like this would cause all kinds of issues when trying to draw game components, but all of that is secondary to the fact that in no way is Player a descendant of Game.

It seems like you're maybe punching a bit above your weight on this one. I strongly suggest working on a much smaller and simpler project than this 3D spaceship bit, and ideally do it without a tutorial. From what I see here, I don't think that you have a strong enough command of programming to tackle something this big and complicated just yet.

-------R.I.P.-------

Selective Quote

~Too Late - Too Soon~

Advertisement

thanks yes your right ill shelve this for the time being to do somthing with 2d to get me into the swing of things :(

thanks yes your right ill shelve this for the time being to do somthing with 2d to get me into the swing of things sad.png

It's not as disappointing as it might seem, moving to a smaller project. And some of the organizational stuff that you learn from it will make working on a project like this one much, much easier.

-------R.I.P.-------

Selective Quote

~Too Late - Too Soon~

This topic is closed to new replies.

Advertisement