Example #1
0
 /// <summary>
 /// Retrieve all GameObject with a particular Classifications.
 /// </summary>
 /// <param name="classification">A classification the GameObject must have (although not exclusively).</param>
 /// <returns>A list of all GameObject which have the specified Classifications.</returns>
 public List <GameObject> GetGameObjectsOfClassification(GameObjectDefinition.Classifications classification)
 {
     return(mGameObjectsByClassification[classification]);
 }
Example #2
0
        /// <summary>
        /// Should be called once per frame.
        /// </summary>
        /// <param name="gameTime">The amount of time passed since last update.</param>
        public void Update(GameTime gameTime)
        {
#if DEBUG
            // Draw cell boundaries.
            //

            Int32 size = mNumCells * mCellSize;

            for (Int32 y = 0; y < mNumCells; y++)
            {
                DebugShapeDisplay.pInstance.AddSegment(new Vector2(0, y * mCellSize), new Vector2(size, y * mCellSize), Color.Black);
            }

            for (Int32 x = 0; x < mNumCells; x++)
            {
                DebugShapeDisplay.pInstance.AddSegment(new Vector2(x * mCellSize, 0), new Vector2(x * mCellSize, size), Color.Black);
            }
#endif
            DebugMessageDisplay.pInstance.AddDynamicMessage("Objects Rendered: " + mLastNumObjectsRendered);

            mCurrentUpdateState = UpdatePhase.Update;

            // Keep track of how many objects were updated this frame.
            int count = 0;

            // Some behaviours require some logic to be done prior to the standard update.  This is their chance.
            //
            for (int i = 0; i < mGameObjects.Count; i++)
            {
                if (mGameObjects[i].pDoUpdate)
                {
                    mGameObjects[i].PreUpdate(gameTime);
                }
            }

            // Update every object we are managing.
            //
            for (int i = 0; i < mGameObjects.Count; i++)
            {
                if (mGameObjects[i].pDoUpdate)
                {
                    mGameObjects[i].Update(gameTime);
                }

                count++;
            }

            // A final chance to update behaviours after all the updates have been completed.
            //
            for (int i = 0; i < mGameObjects.Count; i++)
            {
                if (mGameObjects[i].pDoUpdate)
                {
                    mGameObjects[i].PostUpdate(gameTime);
                }
            }

            DebugMessageDisplay.pInstance.AddDynamicMessage("Updated " + count + " GameObjects");

            mCurrentUpdateState = UpdatePhase.Remove;

            // Now loop through our list of objects which need to be removed and
            // remove them.
            //
            for (int i = 0; i < mGameObjectsToRemove.Count; i++)
            {
                // If this is a GameObject that was spawned through a Factory then it needs to be
                // returned to that Factory.
                if (mGameObjectsToRemove[i].pFactoryInfo.pIsManaged)
                {
                    GameObjectFactory.pInstance.RecycleTemplate(mGameObjectsToRemove[i]);
                }

                // See if this is also going to be referenced in the dynamic objects list.
                if (!mGameObjectsToRemove[i].pIsStatic)
                {
                    mDynamicGameObjects.Remove(mGameObjectsToRemove[i]);
                }

                // See if this is going to be reference in the static objects list.
                if (mGameObjectsToRemove[i].pIsStatic)
                {
                    // Figure out which cell this object would be in.
                    Vector2 index = CellIndexFromPosition(mGameObjectsToRemove[i].pPosition);

                    // Remove it from the cell it should be in.
                    mStaticGameObjects[(Int32)index.X, (Int32)index.Y].Remove(mGameObjectsToRemove[i]);
                }

                for (Int32 tag = 0; tag < mGameObjectsToRemove[i].pClassifications.Count; tag++)
                {
                    mGameObjectsByClassification[(GameObjectDefinition.Classifications)tag].Remove(mGameObjectsToRemove[i]);
                }

                // What happens if someone adds and removes an element within the same
                // update?  It would mean we are about to remove an item that hasn't
                // actually been added yet!  To get around this flaw, we will attempt to
                // remove the item from the main list and if that fails, try to remove it
                // from the list of items about to be added.
                if (mGameObjectsToRemove[i] != null && mGameObjects.Remove(mGameObjectsToRemove[i]) == false)
                {
                    if (mGameObjectsToAdd.Remove(mGameObjectsToRemove[i]) == false)
                    {
                        //System.Diagnostics.Debug.Assert(false, "Attempting to remove a game object which isn't in any of the managed lists.");
                    }
                }
            }

            mCurrentUpdateState = UpdatePhase.Add;

            // Loop through all the game objects that exist.  We want to insert the new game objects
            // in the order that they were added, based on render priority.  If the new object shares
            // a render priority with another object, it is inserted in front of the first same-priority
            // object it hits.
            //
            // This bit of code assumes that the mGameObjectsToAdd and mGameObjects are both sorted
            // based on render priority.
            //
            int curIndex = 0;
            for (int i = 0; i < mGameObjectsToAdd.Count; i++)
            {
                // Check if this is a dynamic object which isn't already being managed by this list.
                if (!mGameObjectsToAdd[i].pIsStatic)
                {
                    System.Diagnostics.Debug.Assert(!mDynamicGameObjects.Contains(mGameObjectsToAdd[i]), "Attempting to add GameObject already in mDynamicGameObjects.");

                    mDynamicGameObjects.Add(mGameObjectsToAdd[i]);
                }

                // Has this object been flagged as being static?
                if (mGameObjectsToAdd[i].pIsStatic)
                {
                    // Figure out which cell this object would be in.
                    Vector2 index = CellIndexFromPosition(mGameObjectsToAdd[i].pPosition);

                    System.Diagnostics.Debug.Assert(!mStaticGameObjects[(Int32)index.X, (Int32)index.Y].Contains(mGameObjectsToAdd[i]), "Attempting to add GameObject already in mStaticGameObjects.");

                    mStaticGameObjects[(Int32)index.X, (Int32)index.Y].Add(mGameObjectsToAdd[i]);
                }

                for (Int32 tagIndex = 0; tagIndex < mGameObjectsToAdd[i].pClassifications.Count; tagIndex++)
                {
                    GameObjectDefinition.Classifications tag = mGameObjectsToAdd[i].pClassifications[tagIndex];

                    mGameObjectsByClassification[tag].Add(mGameObjectsToAdd[i]);
                }

                // If this game object is already in the list, don't add it again.
                if (!mGameObjects.Contains(mGameObjectsToAdd[i]))
                {
                    bool alreadyAdded = false;

                    // Loop through all the currently exisiting game objects.  We continue moving
                    // forward even after inserting a new object.  This can be done because we assume
                    // the mGameObjectsToAdd is also sorted by render priority, which means the next
                    // element must be placed somewhere after the current one.
                    for (; curIndex < mGameObjects.Count; curIndex++)
                    {
                        if (mGameObjectsToAdd[i].pRenderPriority < mGameObjects[curIndex].pRenderPriority)
                        {
                            // We have found the proper place for this element.
                            mGameObjects.Insert(curIndex, mGameObjectsToAdd[i]);

                            // We don't want to test against the elemt we just added.  Since it was
                            // inserted at i, the object we just compared against is actually at i + 1
                            // now.  Let's start the next comparison there.
                            curIndex++;

                            alreadyAdded = true;

                            break;
                        }
                    }

                    if (!alreadyAdded)
                    {
                        // If we make it to this point all the remaining elements have a greater or equal
                        // render priority to the highest priority item already existing.
                        // This will also take care of the cases where this is the first item being added.
                        mGameObjects.Add(mGameObjectsToAdd[i]);

                        // We don't want to test against the element we just added.  Since it was
                        // inserted at i, the object we just compared against is actually at i + 1
                        // now.  Let's start the next comparison there.
                        curIndex++;
                    }
                }
            }

            mCurrentUpdateState = UpdatePhase.OnRemove;

            if (mGameObjectsToRemove.Count != 0)
            {
                // At this point all objects for the frame have been removed from
                // the GameObjectManager. This is an ideal time to give objects
                // a chance to do some cleanup which requires objects to
                // be removed (eg. Delete stuff).
                for (Int32 i = 0; i < mGameObjectsToRemove.Count; i++)
                {
                    mGameObjectsToRemove[i].OnRemove();
                }

                mGameObjectsToRemove.Clear();
            }

            mCurrentUpdateState = UpdatePhase.OnAdd;

            if (mGameObjectsToAdd.Count != 0)
            {
                // At this point all objects for the frame have been added to
                // the GameObjectManager. This is an ideal time to give objects
                // a chance to do some initization which requires objects to
                // be added (eg. BroadCastMessage).
                for (Int32 i = 0; i < mGameObjectsToAdd.Count; i++)
                {
                    mGameObjectsToAdd[i].OnAdd();
                }

                mGameObjectsToAdd.Clear();
            }

            mCurrentUpdateState = UpdatePhase.None;

            if (mGameObjectsToRemoveNextFrame.Count > 0)
            {
                mGameObjectsToRemove.AddRange(mGameObjectsToRemoveNextFrame);

                mGameObjectsToRemoveNextFrame.Clear();
            }

            if (mGameObjectsToAddNextFrame.Count > 0)
            {
                mGameObjectsToAdd.AddRange(mGameObjectsToAddNextFrame);

                mGameObjectsToAddNextFrame.Clear();
            }
        }