예제 #1
0
        /// <summary>
        /// Inserts a game object in the quad tree.
        /// </summary>
        /// <param name="gameObject">The object that is being inserted</param>
        /// <param name="insertInThisQuad">If true, then force add object in the current quad. (Should never be used outside of the quad tree)</param>
        /// <returns>true, if insert is successful, otherwise false</returns>
        public bool InsertGameObject(BGameObject gameObject, bool insertInThisQuad = false)
        {
            if (insertInThisQuad)
            {
                mGameObjects.Add(gameObject);
                gameObject.CurrentQuadTree = this;
                DecrementCountOfNodeAndParents(-1);
                InsertInSubQuadTrees(gameObject);
                return(true);
            }

            if (IsGameObjectOutOfBounds(gameObject))
            {
                return(false);
            }

            if (mGameObjects.Count < NodeCapacity && mSubQuadTrees[0] == null)
            {
                return(InsertGameObject(gameObject, true));
            }

            if (mSubQuadTrees[0] == null)
            {
                SubdivideQuadTree();
            }

            if (!mSubQuadTrees[GetQuadrantIndex(gameObject.Position)].InsertGameObject(gameObject))
            {
                InsertGameObject(gameObject, true);
            }

            return(true);
        }
예제 #2
0
        private void InsertInSubQuadTrees(BGameObject gameObject)
        {
            if (!AreRegionsIntersecting(gameObject.CollisionBoxCenter - gameObject.CollisionBoxOffset,
                                        gameObject.CollisionBoxCenter + gameObject.CollisionBoxOffset,
                                        mLowerBound,
                                        mUpperBound))
            {
                return;
            }
            if (gameObject.CurrentQuadTree != this)
            {
                mGameObjectsFromUpperQuad.Add(gameObject);
                gameObject.CurrentSubQuadTrees.Add(this);
            }

            if (mSubQuadTrees[0] == null)
            {
                return;
            }

            for (var i = 0; i < 4; i++)
            {
                mSubQuadTrees[i].InsertInSubQuadTrees(gameObject);
            }
        }
예제 #3
0
 public static bool AreGameObjectsColliding(BGameObject gameObject1, BGameObject gameObject2)
 {
     return(AreRegionsIntersecting(gameObject1.CollisionBoxCenter - gameObject1.CollisionBoxSize / 2,
                                   gameObject1.CollisionBoxCenter + gameObject1.CollisionBoxSize / 2,
                                   gameObject2.CollisionBoxCenter - gameObject2.CollisionBoxSize / 2,
                                   gameObject2.CollisionBoxCenter + gameObject2.CollisionBoxSize / 2));
 }
예제 #4
0
        /// <summary>
        /// Remove a game object from the quad tree
        /// </summary>
        /// <param name="gameObject">The object that is being removed</param>
        /// <param name="removeInThisQuad">If true, then force remove object in the current quad. (Should never be used outside of the quad tree)</param>
        /// <returns>true, if remove is successful, otherwise false</returns>
        public bool RemoveGameObject(BGameObject gameObject, bool removeInThisQuad = false)
        {
            if (removeInThisQuad)
            {
                if (!mGameObjects.Remove(gameObject))
                {
                    return(false);
                }
                DecrementCountOfNodeAndParents();
                var currentQuadTree = this;
                while (currentQuadTree != null && currentQuadTree.mGameObjectCount <= NodeCapacity)
                {
                    currentQuadTree.MergeQuadTrees();
                    currentQuadTree = currentQuadTree.mParentQuadTree;
                }
                gameObject.CurrentQuadTree = null;
                foreach (var subtree in gameObject.CurrentSubQuadTrees)
                {
                    subtree.mGameObjectsFromUpperQuad.Remove(gameObject);
                }
                gameObject.CurrentSubQuadTrees.Clear();
                return(true);
            }

            return(gameObject.CurrentQuadTree != null &&
                   gameObject.CurrentQuadTree.RemoveGameObject(gameObject, true));
        }
        public bool Queue(string action, BGameObject objectToDo)
        {
            var farmer = ObjectManager.Instance.GetFarmer();

            if (farmer == null)
            {
                return(false);
            }
            mObject = objectToDo;
            if (mObject == null)
            {
                return(false);
            }
            var farmerPosition = farmer.Position;
            var distance       = mObject.Position - farmerPosition;

            mInRange = distance.Length() < mFarmerActionRange;
            if (mInRange)
            {
                return(mInRange);
            }
            ChangeQueue(action, mObject.Position);
            SendFarmer();
            return(mInRange);
        }
예제 #6
0
        private static bool LocationContainsGameObject(Vector2 location, BGameObject gameObject, bool useTextureBoxes)
        {
            var center = useTextureBoxes ? GetTextureBoxPosition(gameObject) : gameObject.CollisionBoxCenter;
            var size   = useTextureBoxes ? gameObject.TextureBoxSize : gameObject.CollisionBoxSize;

            return(Math.Abs(center.X - location.X) <= size.X / 2 &&
                   Math.Abs(center.Y - location.Y) <= size.Y / 2);
        }
예제 #7
0
 private bool IsGameObjectOutOfBounds(BGameObject gameObject)
 {
     return(IsBoxOutOfBounds(gameObject.CollisionBoxCenter, gameObject.CollisionBoxSize) ||
            IsBoxOutOfBounds(GetTextureBoxPosition(gameObject), gameObject.TextureBoxSize) ||
            IsBoxOutOfBounds(gameObject.CollisionBoxCenter,
                             gameObject.CollisionBoxSize,
                             sGlobalCollisionBoxBoundaryCenter,
                             sGlobalCollisionBoxBoundarySize));
 }
예제 #8
0
        public void Add(BGameObject obj)
        {
            if (EndScreen)
            {
                AddMoonwalkZombie(obj);
                return;
            }

            mQuadTree.InsertGameObject(obj);

            if (obj is Farmer farmer)
            {
                if (mFarmer == null)
                {
                    mFarmer = farmer;
                }
                else
                {
                    mQuadTree.RemoveGameObject(obj);
                }
            }
            else if (obj is Farmhouse house)
            {
                if (mFarmhouse == null)
                {
                    mFarmhouse = house;
                }
                else
                {
                    mQuadTree.RemoveGameObject(obj);
                }
            }
            else if (obj is Tower tower)
            {
                mTowers.Add(tower);
            }
            else if (obj is Fence fence)
            {
                mFences.Add(fence);
            }
            else if (obj is PreviewFence previewFence)
            {
                mPreviewFences.Add(previewFence);
            }
            else if (obj is Zombie zombie && !(obj is TreasureZombie))
            {
                mZombies.Add(zombie);
            }
        public void EmptyFQueue()
        {
            if (mIsempty)
            {
                return;
            }
            var farmer = ObjectManager.Instance.GetFarmer();

            if (farmer != null)
            {
                Instance.ChangeQueue("nothing", farmer.CollisionBoxCenter);
                farmer.RequestPath(farmer.CollisionBoxCenter);
            }
            mIsempty = true;
            mObject  = null;
            mObjects = null;
        }
예제 #10
0
        private static List <Vector2> GetCollidingWaterTiles(BGameObject gameObject, Vector2 position)
        {
            var waterTiles = new List <Vector2>();
            var lowerBound = position + gameObject.CollisionBoxOffset - gameObject.CollisionBoxSize / 2;
            var upperBound = position + gameObject.CollisionBoxOffset + gameObject.CollisionBoxSize / 2;

            for (var i = (int)lowerBound.X; i < upperBound.X; i++)
            {
                for (var j = (int)lowerBound.Y; j < upperBound.Y; j++)
                {
                    if (Game1.sTileMap.GetTileType(i, j) == Tile.Water)
                    {
                        waterTiles.Add(new Vector2(i, j));
                    }
                }
            }

            return(waterTiles);
        }
예제 #11
0
        private static Wheat.WheatType CheckType(BGameObject o)
        {
            var type = Wheat.WheatType.Wheat1;

            if (o == null)
            {
                return(type);
            }

            var wheats = ObjectManager.Instance.GetWheat();

            foreach (var wheat in wheats)
            {
                if (o.Position == wheat.Position)
                {
                    type = wheat.Type;
                }
            }
            return(type);
        }
예제 #12
0
        private static int CheckStage(BGameObject a)
        {
            var stage = 0;

            if (a == null)
            {
                return(stage);
            }
            var list = ObjectManager.Instance.GetWheat();

            foreach (var wheat in list)
            {
                if (a.Position == wheat.Position)
                {
                    stage = wheat.mStage;
                }
            }

            return(stage);
        }
예제 #13
0
        public List <ICollidable> GetCollidingObjects(BGameObject gameObject, float range)
        {
            var currentQuadTree = this;

            while (currentQuadTree.IsBoxOutOfBounds(gameObject.CollisionBoxCenter, 2 * new Vector2(range, range)) && currentQuadTree.mParentQuadTree != null)
            {
                currentQuadTree = currentQuadTree.mParentQuadTree;
            }

            var collidingObjects =
                currentQuadTree.GetGameObjects(gameObject.CollisionBoxCenter, range,
                                               false,
                                               typeof(ICollidable));

            collidingObjects.AddRange(currentQuadTree.GetGameObjects(gameObject.CollisionBoxCenter, range,
                                                                     false,
                                                                     typeof(ICollidable), true, true));
            collidingObjects.Remove(gameObject);
            return(ConvertListToType <BGameObject, ICollidable>(collidingObjects));
        }
예제 #14
0
        private void SetObject(BGameObject obj)
        {
            mButtons.Clear();
            if (!obj.Selected)
            {
                Clear();
                return;
            }
            mWorldPosition = new Vector2(obj.Position.X, obj.Position.Y);
            mObject        = obj;
            var buttons         = GetButtons();
            var buttonPositions = GetButtonPositions(buttons.Count);

            for (var i = 0; i < buttons.Count; i++)
            {
                buttons[i].SetPosition(buttonPositions[i]);
                mButtons.Add(buttons[i]);
            }

            Visible = true;
        }
        public static bool Select(IEnumerable <BGameObject> list, bool box, Vector2 mousePosition)
        {
            if (box)
            {
                BGameObject selected = null;
                foreach (var i in list)
                {
                    if (selected == null)
                    {
                        selected = i;
                    }
                    else if (Math.Abs(mousePosition.X - i.Position.X) + Math.Abs(mousePosition.Y - i.Position.Y) < Math.Abs(mousePosition.X - selected.Position.X) + Math.Abs(mousePosition.Y - selected.Position.Y))
                    {
                        selected = i;
                    }
                }
                selected?.Select();
                if (selected is Wheat wheat)
                {
                    if (wheat.Type == Wheat.WheatType.Corn)
                    {
                        if (wheat.Position.Y > (mousePosition.Y))
                        {
                            wheat.Deselect();
                            return(false);
                        }
                    }
                }
                return(true);
            }
            else
            {
                foreach (var i in list)
                {
                    i?.Select();
                }

                return(true);
            }
        }
예제 #16
0
        /// <summary>
        /// Returns a list of all objects that collide with gameObject if it were at a certain position.
        /// </summary>
        /// <param name="gameObject">The object whose collisions are being looked at</param>
        /// <param name="position">The position where the collisions are looked at</param>
        /// <returns>The list of objects that collide with gameObject</returns>
        public List <ICollidable> GetCollidingObjects(BGameObject gameObject, Vector2 position)
        {
            var currentQuadTree = this;

            while (currentQuadTree.IsBoxOutOfBounds(position + gameObject.CollisionBoxOffset, gameObject.CollisionBoxSize) && currentQuadTree.mParentQuadTree != null)
            {
                currentQuadTree = currentQuadTree.mParentQuadTree;
            }

            var collidingObjects =
                currentQuadTree.GetGameObjects(position + gameObject.CollisionBoxOffset - gameObject.CollisionBoxSize / 2,
                                               position + gameObject.CollisionBoxOffset + gameObject.CollisionBoxSize / 2,
                                               false,
                                               typeof(ICollidable));

            collidingObjects.AddRange(currentQuadTree.GetGameObjects(position + gameObject.CollisionBoxOffset - gameObject.CollisionBoxSize / 2,
                                                                     position + gameObject.CollisionBoxOffset + gameObject.CollisionBoxSize / 2,
                                                                     false,
                                                                     typeof(ICollidable), true, true));
            collidingObjects.Remove(gameObject);
            return(ConvertListToType <BGameObject, ICollidable>(collidingObjects));
        }
예제 #17
0
        public static Vector2 ClampPosition(BGameObject gameObject)
        {
            if (!IsBoxOutOfBounds(gameObject.CollisionBoxCenter,
                                  gameObject.CollisionBoxSize,
                                  sGlobalCollisionBoxBoundaryCenter,
                                  sGlobalCollisionBoxBoundarySize))
            {
                return(Vector2.Zero);
            }
            var correctionVector = Vector2.Zero;

            correctionVector +=
                MathHelper.Clamp(
                    sGlobalCollisionBoxBoundaryCenter.X - sGlobalCollisionBoxBoundarySize.X / 2 -
                    (gameObject.CollisionBoxCenter.X - gameObject.CollisionBoxSize.X / 2),
                    0,
                    float.PositiveInfinity) * Vector2.UnitX;
            correctionVector +=
                MathHelper.Clamp(
                    sGlobalCollisionBoxBoundaryCenter.Y - sGlobalCollisionBoxBoundarySize.Y / 2 -
                    (gameObject.CollisionBoxCenter.Y - gameObject.CollisionBoxSize.Y / 2),
                    0,
                    float.PositiveInfinity) * Vector2.UnitY;
            correctionVector -=
                MathHelper.Clamp(
                    gameObject.CollisionBoxCenter.X + gameObject.CollisionBoxSize.X / 2 -
                    (sGlobalCollisionBoxBoundaryCenter.X + sGlobalCollisionBoxBoundarySize.X / 2),
                    0,
                    float.PositiveInfinity) * Vector2.UnitX;
            correctionVector -=
                MathHelper.Clamp(
                    gameObject.CollisionBoxCenter.Y + gameObject.CollisionBoxSize.Y / 2 -
                    (sGlobalCollisionBoxBoundaryCenter.Y + sGlobalCollisionBoxBoundarySize.Y / 2),
                    0,
                    float.PositiveInfinity) * Vector2.UnitY;
            return(correctionVector);
        }
예제 #18
0
        /// <summary>
        /// Updates the placement of the game object in the quad tree data structure. Use this whenever the position of the object has changed.
        /// </summary>
        /// <param name="gameObject">That object that is being moved in the quad tree</param>
        /// <returns>true, if moving is successful, otherwise false</returns>
        public bool UpdateGameObjectPosition(BGameObject gameObject)
        {
            if (gameObject.CurrentQuadTree != this)
            {
                return(gameObject.CurrentQuadTree.UpdateGameObjectPosition(gameObject));
            }
            if (IsGameObjectOutOfBounds(gameObject))
            {
                if (!mRootQuadTree.InsertGameObject(gameObject))
                {
                    return(false);
                }
                var currentQuadTree = gameObject.CurrentQuadTree;
                RemoveGameObject(gameObject, true);
                gameObject.CurrentQuadTree = currentQuadTree;
                InsertInSubQuadTrees(gameObject);
            }
            else if (mSubQuadTrees[0] != null && mSubQuadTrees[GetQuadrantIndex(gameObject.Position)].InsertGameObject(gameObject))
            {
                var currentQuadTree = gameObject.CurrentQuadTree;
                RemoveGameObject(gameObject, true);
                gameObject.CurrentQuadTree = currentQuadTree;
                InsertInSubQuadTrees(gameObject);
            }
            else
            {
                foreach (var subtree in gameObject.CurrentSubQuadTrees)
                {
                    subtree.mGameObjectsFromUpperQuad.Remove(gameObject);
                }
                gameObject.CurrentSubQuadTrees.Clear();
                InsertInSubQuadTrees(gameObject);
            }

            return(true);
        }
예제 #19
0
        public void GoldIncrease(string action, BGameObject a)
        {
            var increaseGold = 0;

            if (mProfitDictionary.TryGetValue(action, out var result2))
            {
                increaseGold += result2;
            }
            else
            {
                Debug.WriteLine("Gold Amount was not changed. Could not find the specified key.");
            }

            if (result2 == 0) // Harvest Action
            {
                if (a is Chicken)
                {
                    GoldIncrease("ActionKillChicken");
                    return;
                }
                if (a is Cow)
                {
                    GoldIncrease("ActionKillCow");
                    return;
                }
                if (a is Pig)
                {
                    GoldIncrease("ActionKillPig");
                    return;
                }
                if (mStageDictionary.TryGetValue(CheckStage(a), out var result1))
                {
                    increaseGold += result1;
                }
                else
                {
                    Debug.WriteLine("Gold Amount was not changed. Could not find the specified stage of Wheat.");
                }

                if (result1 > 0) // Stage is not 0
                {
                    if (CheckType(a) == Wheat.WheatType.Wheat1)
                    {
                        increaseGold *= Wheat1Factor;
                    }

                    if (CheckType(a) == Wheat.WheatType.Wheat2)
                    {
                        increaseGold *= Wheat2Factor;
                    }

                    if (CheckType(a) == Wheat.WheatType.Corn)
                    {
                        increaseGold *= CornFactor;
                    }
                }
                else
                {
                    Debug.WriteLine("Gold Amount was not Changed, so no Type of Wheat was checked.");
                }
            }

            // Gold increased! Time for a sound
            Game1.sAchievements.GoldIncrease(increaseGold);
            GoldAmount += increaseGold;
            if (increaseGold > 0)
            {
                SoundManager.PlaySound("coin");
            }
        }
예제 #20
0
 private static Vector2 GetTextureBoxPosition(BGameObject gameObject)
 {
     return(gameObject.Position + gameObject.TextureOffset + new Vector2(gameObject.Width, gameObject.Height) / 64);
 }
예제 #21
0
 public static List <Vector2> GetCollidingWaterTiles(BGameObject gameObject)
 {
     return(GetCollidingWaterTiles(gameObject, gameObject.Position));
 }