/// <summary>
        /// Helper function for creating behaviours based on strings of matching names.
        /// </summary>
        /// <param name="behaviourType">The name of the behaviour class we are creating.</param>
        /// <param name="fileName">The name of the file containing the behaviour definition.</param>
        /// <returns>The newly created behaviour.</returns>
        protected virtual Behaviour.Behaviour CreateBehaviourByName(String behaviourType, String fileName)
        {
            // Allow the client a chance to create non-engine behaviours.
            for (Int16 i = 0; i < mBehaviourCreators.Count; i++)
            {
                Behaviour.Behaviour b = mBehaviourCreators[i].CreateBehaviourByName(this, behaviourType, fileName);

                // Once the behaviour has been created there is no reason to continue.
                if (b != null)
                {
                    return(b);
                }
            }

            switch (behaviourType)
            {
            case "MBHEngine.Behaviour.SpriteRender":
            {
                return(new MBHEngine.Behaviour.SpriteRender(this, fileName));
            }

            case "MBHEngine.Behaviour.SimulatedPhysics":
            {
                return(new MBHEngine.Behaviour.SimulatedPhysics(this, fileName));
            }

            case "MBHEngine.Behaviour.TileMapRender":
            {
                return(new MBHEngine.Behaviour.TileMapRender(this, fileName));
            }

            case "MBHEngine.Behaviour.FrameRateDisplay":
            {
                return(new MBHEngine.Behaviour.FrameRateDisplay(this, fileName));
            }

            case "MBHEngine.Behaviour.Level":
            {
                return(new MBHEngine.Behaviour.Level(this, fileName));
            }

            case "MBHEngine.Behaviour.TileCollision":
            {
                return(new MBHEngine.Behaviour.TileCollision(this, fileName));
            }

            case "MBHEngine.Behaviour.PathFind":
            {
                return(new MBHEngine.Behaviour.PathFind(this, fileName));
            }

            case "MBHEngine.Behaviour.PathFollow":
            {
                return(new MBHEngine.Behaviour.PathFollow(this, fileName));
            }

            case "MBHEngine.Behaviour.RemoveTileOnDeath":
            {
                return(new MBHEngine.Behaviour.RemoveTileOnDeath(this, fileName));
            }

            case "MBHEngine.Behaviour.Health":
            {
                return(new MBHEngine.Behaviour.Health(this, fileName));
            }

            case "MBHEngine.Behaviour.SpawnOnDeath":
            {
                return(new MBHEngine.Behaviour.SpawnOnDeath(this, fileName));
            }

            case "MBHEngine.Behaviour.SimpleMomentum":
            {
                return(new MBHEngine.Behaviour.SimpleMomentum(this, fileName));
            }

            case "MBHEngine.Behaviour.Magnetic":
            {
                return(new MBHEngine.Behaviour.Magnetic(this, fileName));
            }

            case "MBHEngine.Behaviour.ShapeRender":
            {
                return(new MBHEngine.Behaviour.ShapeRender(this, fileName));
            }

            case "MBHEngine.Behaviour.FaceForward":
            {
                return(new MBHEngine.Behaviour.FaceForward(this, fileName));
            }

            case "MBHEngine.Behaviour.HealNearby":
            {
                return(new MBHEngine.Behaviour.HealNearby(this, fileName));
            }

            default:
            {
                System.Diagnostics.Debug.Assert(false, "Attempting to create unknown behaviour type, " + behaviourType + " linked to file " + fileName + "!");
                return(null);
            }
            }
        }
        /// <summary>
        /// Call this to initialize an GameObject with data supplied in a file.
        /// </summary>
        /// <param name="fileName">The file to load from.</param>
        public virtual void LoadContent(String fileName)
        {
            // Give this object a unique id and increment the counter so that the next
            // object gets a unique id as well.
            mID = mUniqueIDCounter++;

            mDirection          = new Direction();
            mFactoryInfo        = new GameObjectFactory.FactoryInfo();
            mClassifications    = new List <GameObjectDefinition.Classifications>();
            mCollisionRectangle = new Math.Rectangle();
            mRenderRectangle    = new Math.Rectangle();

            mTemplateFileName = fileName;

            if (null != fileName)
            {
                GameObjectDefinition def = GameObjectManager.pInstance.pContentManager.Load <GameObjectDefinition>(fileName);

                mRenderPriority     = def.mRenderPriority;
                mDoUpdate           = def.mDoUpdate;
                mDoRender           = def.mDoRender;
                mPosition           = def.mPosition;
                mRotation           = def.mRotation;
                mScale              = def.mScale;
                mIsStatic           = def.mIsStatic;
                mCollisionRectangle = new Math.Rectangle(def.mCollisionBoxDimensions);
                mCollisionRectangle.pCenterPoint = mPosition;
                // Being lazy for now. Just assume that a scaler of collision box is big enough to always show character.
                mRenderRectangle = new Math.Rectangle(def.mCollisionBoxDimensions * 4f);
                mRenderRectangle.pCenterPoint = mPosition;
                mMotionRoot = def.mMotionRoot;
                if (def.mCollisionRoot == null)
                {
                    mCollisionRoot = Vector2.Zero;
                }
                else
                {
                    mCollisionRoot = def.mCollisionRoot;
                }

                for (Int32 i = 0; def.mClassifications != null && i < def.mClassifications.Count; i++)
                {
                    mClassifications.Add(def.mClassifications[i]);
                }

                mBlendMode = def.mBlendMode;

                for (Int32 i = 0; i < def.mBehaviourFileNames.Count; i++)
                {
                    String goRootPath        = System.IO.Path.GetDirectoryName(fileName);
                    Behaviour.Behaviour temp = CreateBehaviourByName(def.mBehaviourClassNames[i], goRootPath + "\\Behaviours\\" + def.mBehaviourFileNames[i]);
                    mBehaviours.Add(temp);
                }
            }
            else
            {
                mRenderPriority = 50;
                mDoUpdate       = true;
                mDoRender       = true;
                mBlendMode      = GameObjectDefinition.BlendMode.STANDARD;
            }
        }
 /// <summary>
 /// Attaches an already exisiting behaviour to this game object.  This is handy for manually
 /// creating GameObjects, instead of through the usually xml definitions.
 /// </summary>
 /// <param name="b">The behaviour to attach.</param>
 public virtual void AttachBehaviour(Behaviour.Behaviour b)
 {
     // Add the behaviour to the list of behaviours.
     mBehaviours.Add(b);
 }
Exemple #4
0
        /// <summary>
        /// Must be called once every update to check which objects are being picked.
        /// </summary>
        /// <param name="gameTime"></param>
        /// <param name="showDebugInfo">True if debug information should be shown this frame.</param>
        public void Update(GameTime gameTime, Boolean showDebugInfo)
        {
#if DEBUG
            // Get the current state of the mouse.
            MouseState ms = Mouse.GetState();

            // Only count mouse clicks that happen after the button was previously released.
            Boolean clickChanged = (mPreviousMouseState.LeftButton != ms.LeftButton);

            // Temp storing which object the mouse is currently over top of (if any).
            GameObject mousedObject = null;

            const String dbgLayer = "GameObjectPicker";

            // If while hovering over an object, the user presses the mouse button, that object
            // not becomes the new "selected" object.
            if (ms.LeftButton == ButtonState.Pressed && clickChanged)
            {
                // Project that mouse position into 2D world space so that it can be tested for collision.
                Vector2 proj = CameraManager.pInstance.ProjectMouseToWorldSpace(new Vector2(ms.X, ms.Y));

                // Reposition the collision rect of the mouse pointer to the position of the actual
                // mouse in world space.
                mMouseRect.pCenterPoint = proj;

                // Clear any objects that might still be stored from the previous frame.
                mCollidedObjects.Clear();

                // Check if any objects are colliding with the mouse.
                // NOTE: This is a really expensive call right now, so we don't want to be doing
                //       it every frame. Instead we only do it when you click.
                GameObjectManager.pInstance.GetGameObjectsInRange(mMouseRect, ref mCollidedObjects);

                // Did the mouse actually collide with any objects?
                if (mCollidedObjects.Count > 0)
                {
                    // We just use index 0 for now. Eventually we might need to determine some sort
                    // of sorting order, perhaps based on rect size, or render order.
                    mousedObject = mCollidedObjects[0];

                    if (mousedObject != mSelectedGameObject)
                    {
                        DebugMessageDisplay.pInstance.pCurrentTag = dbgLayer;

                        mSelectedGameObject = mousedObject;
                    }
                    else
                    {
                        DebugMessageDisplay.pInstance.pCurrentTag = null;

                        // If they click the same object which is already selected, consider that an
                        // attempt to unselect the GameObject.
                        mSelectedGameObject = null;
                    }
                }
            }
            else
            {
                // If the user clicks while not over any GameObject, unselect the currently selected.
                if (ms.LeftButton == ButtonState.Pressed && clickChanged)
                {
                    DebugMessageDisplay.pInstance.pCurrentTag = null;

                    mSelectedGameObject = null;
                }
            }

#if ALLOW_GARBAGE
            /* Removing this functionality for now because it is too expensive to search for collisions with
             * every object in the world, every frame.
             *
             * // Display some information about the object we are hovering over.
             * //
             * if (null != mousedObject)
             * {
             *  DebugMessageDisplay.pInstance.AddDynamicMessage("Picked GO (over): " + mousedObject.pID);
             *  DebugShapeDisplay.pInstance.AddAABB(mousedObject.pCollisionRect, Color.Orange);
             * }
             * else
             * {
             *  DebugMessageDisplay.pInstance.AddDynamicMessage("Picked GO (over): --");
             * }
             */

            // The Behaviour and GameObject classes expose a bunch of debug information through the GetDebugInfo
            // functions. If there is an object currently selected, we want to get that info about the selected
            // object and print it on screen for real-time debugging.
            if (null != mSelectedGameObject && showDebugInfo)
            {
                // So the user knows what is going on, highlight the object.
                DebugShapeDisplay.pInstance.AddAABB(mSelectedGameObject.pCollisionRect, Color.Red);

                // The the GameObject debug info. Every GameObject has this.
                String [] goInfo = mSelectedGameObject.GetDebugInfo();

                // Print the class name and the info.
                DebugMessageDisplay.pInstance.AddDynamicMessage(mSelectedGameObject.GetType().ToString(), dbgLayer);

                for (Int32 i = 0; i < goInfo.Length; i++)
                {
                    DebugMessageDisplay.pInstance.AddDynamicMessage(" - " + goInfo[i], dbgLayer);
                }

                // Loop through every Behaviour attached to this GameObject and call the corisponding
                // GetDebugInfo functions.
                for (Int32 i = 0; i < mSelectedGameObject.pBehaviours.Count; i++)
                {
                    Behaviour.Behaviour b = mSelectedGameObject.pBehaviours[i];

                    // Show the behaviour even if the GetDebugInfo isn't implmented for it since we
                    // may just want to know which behaviours it has.5
                    DebugMessageDisplay.pInstance.AddDynamicMessage(b.GetType().ToString(), dbgLayer);

                    String [] dbgInfo = b.GetDebugInfo();

                    // Not every Behaviour overrides the GetDebugInfo function. In those cases the
                    // default implementation will return null.
                    if (null != dbgInfo)
                    {
                        for (Int32 j = 0; j < dbgInfo.Length; j++)
                        {
                            DebugMessageDisplay.pInstance.AddDynamicMessage(" - " + dbgInfo[j], dbgLayer);
                        }
                    }
                }
            }
#endif // ALLOW_GARBAGE

            // Update the previous state with the current state.
            mPreviousMouseState = Mouse.GetState();
#endif // DEBUG
        }