コード例 #1
0
        /// <summary>
        /// Finds a path between 2 position on a map
        /// </summary>
        /// <param name="startPosition">Starting position</param>
        /// <param name="endPosition">Destination</param>
        /// <param name="map">Game map currently being used</param>
        /// <param name="endNodeUnWalkable"></param>
        /// <returns>A list of Vector2 waypoints that the object must traverse to get to its destination</returns>
        internal Stack <Vector2> FindPath(Vector2 startPosition, Vector2 endPosition, ref Map.Map map, EndNodeUnWalkableTreatment endNodeUnWalkable = EndNodeUnWalkableTreatment.DISALLOW)
        {
            if (!Map.Map.IsOnTop(endPosition) || !map.GetCollisionMap().GetWalkabilityGrid().IsWalkableAt(VectorToGridPos(endPosition)))
            {
                return(new Stack <Vector2>());
            }

            var startGridPos = VectorToGridPos(startPosition);
            var endGridPos   = VectorToGridPos(endPosition);

            if (ClearDirectPath(startGridPos.x, startGridPos.y, endGridPos.x, endGridPos.y, ref map))
            {
                var pathVector = new Stack <Vector2>(1);
                pathVector.Push(endPosition);
                return(pathVector);
            }
            else
            {
                if (mJpParam != null)
                {
                    mJpParam.Reset(VectorToGridPos(startPosition), VectorToGridPos(endPosition));
                }
                else
                {
                    mJpParam = new JumpPointParam(map.GetCollisionMap().GetWalkabilityGrid(),
                                                  startGridPos,
                                                  iDiagonalMovement: DiagonalMovement.OnlyWhenNoObstacles,
                                                  iEndPos: endGridPos,
                                                  iAllowEndNodeUnWalkable: endNodeUnWalkable,
                                                  iMode: HeuristicMode.MANHATTAN);
                }

                var pathGrid = JumpPointFinder.FindPath(mJpParam);

                var pathVector = new Stack <Vector2>(pathGrid.Count);

                pathVector.Push(endPosition);


                for (var i = pathGrid.Count - 1; i > 0; i--)
                {
                    var gridPos = GridPosToVector2(pathGrid[i]);
                    pathVector.Push(gridPos);
                }

                return(pathVector);
            }
        }
コード例 #2
0
        /// <summary>
        /// Removes the given object from the game screens list of objects to handle.
        /// </summary>
        /// <typeparam name="T">The type of the object to be removed. Needs to inherit from IDraw or IUpdate</typeparam>
        /// <param name="toRemove">The object to be removed to the game screen</param>
        /// <returns>True if the given object could be removed, false otherwise</returns>
        public bool RemoveObject <T>(T toRemove)
        {
            var road           = toRemove as Road;
            var platform       = toRemove as PlatformBlank;
            var settler        = toRemove as Settler;
            var freeMovingUnit = toRemove as FreeMovingUnit;

            if (!typeof(IDraw).IsAssignableFrom(typeof(T)) && !typeof(IUpdate).IsAssignableFrom(typeof(T)) && road == null && platform == null)
            {
                return(false);
            }

            if (typeof(ICollider).IsAssignableFrom(typeof(T)))
            {
                mMap.GetCollisionMap().RemoveCollider((ICollider)toRemove);
            }

            if (road != null && !road.Blueprint)
            {
                mMap.RemoveRoad(road);
            }

            if (platform != null && !platform.mBlueprint)
            {
                mMap.RemovePlatform(platform);
                mDirector.GetMilitaryManager.RemovePlatform(platform);
            }

            if (settler != null)
            {
                settler.BuildCommandCenter -= SettlerBuild;
            }

            // unsubscribe from this military unit when deleted
            if (freeMovingUnit != null && freeMovingUnit.Friendly)
            {
                mSelBox.SelectingBox -= freeMovingUnit.BoxSelected;
            }

            if (typeof(IRevealing).IsAssignableFrom(typeof(T)))
            {
                mFow.RemoveRevealingObject((IRevealing)toRemove);
            }

            if (typeof(ISpatial).IsAssignableFrom(typeof(T)))
            {
                mSpatialObjects.Remove((ISpatial)toRemove);
                return(true);
            }

            if (typeof(IDraw).IsAssignableFrom(typeof(T)))
            {
                mDrawables.Remove((IDraw)toRemove);
            }
            if (typeof(IUpdate).IsAssignableFrom(typeof(T)))
            {
                mUpdateables.Remove((IUpdate)toRemove);
            }
            return(true);
        }
コード例 #3
0
        /// <summary>
        /// Checks if a direct plath is clear of obstacles. Based on Bresenham's
        /// line algorithm.
        /// </summary>
        /// <see cref="http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm"/>
        /// <param name="x">Starting x position.</param>
        /// <param name="y">Starting y position.</param>
        /// <param name="x2">Target x position.</param>
        /// <param name="y2">Target y position.</param>
        /// <param name="map">Reference to the game map.</param>
        /// <returns>True if there is a clear direct path to the target.</returns>
        public static bool ClearDirectPath(int x, int y, int x2, int y2, ref Map.Map map)
        {
            var w = x2 - x;
            var h = y2 - y;
            int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0;

            if (w < 0)
            {
                dx1 = -1;
            }
            else if (w > 0)
            {
                dx1 = 1;
            }

            if (h < 0)
            {
                dy1 = -1;
            }
            else if (h > 0)
            {
                dy1 = 1;
            }

            if (w < 0)
            {
                dx2 = -1;
            }
            else if (w > 0)
            {
                dx2 = 1;
            }

            var longest  = Math.Abs(w);
            var shortest = Math.Abs(h);

            if (!(longest > shortest))
            {
                longest  = Math.Abs(h);
                shortest = Math.Abs(w);
                if (h < 0)
                {
                    dy2 = -1;
                }
                else if (h > 0)
                {
                    dy2 = 1;
                }

                dx2 = 0;
            }
            var numerator = longest >> 1;

            for (var i = 0; i <= longest; i++)
            {
                if (!map.GetCollisionMap().GetWalkabilityGrid().IsWalkableAt(x, y))
                {
                    return(false);
                }

                numerator += shortest;
                if (!(numerator < longest))
                {
                    numerator -= longest;
                    x         += dx1;
                    y         += dy1;
                }
                else
                {
                    x += dx2;
                    y += dy2;
                }
            }

            return(true);
        }
コード例 #4
0
        public void Update(GameTime gametime)
        {
            switch (mCurrentState.GetState())
            {
            case 1:
                if (!mIsRoadPlacement)
                {
                    mNatureObjectThere = false;
                    mPlatform.ResetColor();
                    // for this, we want the platform to follow the mouse, and also be centered on the sprite.
                    mPlatform.AbsolutePosition = new Vector2(mMouseX - mPlatform.AbsoluteSize.X / 2f,
                                                             mMouseY - mPlatform.AbsoluteSize.Y / 2f);

                    for (int
                         x = (int)(mPlatform.AbsolutePosition.X /
                                   MapConstants.GridWidth); x < (int)((mPlatform.AbsolutePosition.X +
                                                                       mPlatform.AbsoluteSize.X) /
                                                                      MapConstants.GridWidth); x++)
                    {
                        for (int
                             y = (int)(mPlatform.AbsolutePosition.Y /
                                       MapConstants.GridWidth);
                             y < (int)((mPlatform.AbsolutePosition.Y +
                                        mPlatform.AbsoluteSize.Y) /
                                       MapConstants.GridWidth);
                             y++)
                        {
                            if (!mMap.GetCollisionMap().GetWalkabilityGrid().IsWalkableAt(x, y))
                            {
                                mNatureObjectThere = true;
                            }
                        }
                    }

                    if (mHoveringPlatform == null && !mNatureObjectThere)
                    {
                        break;
                    }

                    mPlatform.SetColor(Color.Red);
                    mPlaySound = false;
                }

                break;

            case 2:
                if (!mIsRoadPlacement)
                {
                    // now we want a road to follow our mouse
                    mConnectionRoad.Destination = new Vector2(mMouseX, mMouseY);

                    if (!mPlaySound)
                    {
                        // makes a sound once when platform is placed
                        mDirector.GetSoundManager.SetSoundPosition(mPlatformCreateSoundId, mMouseX, mMouseY);
                        mDirector.GetSoundManager.PlaySound(mPlatformCreateSoundId);
                        mPlaySound = true;
                    }

                    // we prematurely reset the color of the platform, so we don't have to worry about it being red
                    mPlatform.ResetColor();
                    if (mHoveringPlatform == null)
                    {
                        break;
                    }

                    // at this point we have a hovering platform, so we clip the road destination to its center
                    mConnectionRoad.Destination = mHoveringPlatform.Center;

                    // we only color the platform red if the distance to the platform hovered is too great
                    if (Vector2.Distance(mHoveringPlatform.Center, mPlatform.Center) >
                        mPlatform.RevelationRadius + mHoveringPlatform.RevelationRadius || !mHoveringPlatform.Friendly)
                    {
                        mPlatform.SetColor(Color.Red);
                    }
                }
                else
                {
                    mRoadToBuild.Destination = new Vector2(mMouseX, mMouseY);

                    if (mHoveringPlatform == null)
                    {
                        break;
                    }
                    mRoadToBuild.Destination = mHoveringPlatform.Center;
                }

                break;

            case 3:
                if (!mIsRoadPlacement)
                {
                    // this case is the 'finish' state, we set everything up, so the platform can get added to the game
                    mPlatform.SetLayer(LayerConstants.PlatformLayer);
                    mConnectionRoad.Place(mPlatform, mHoveringPlatform);
                    mHoveringPlatform.AddBlueprint(new BuildBluePrint(mHoveringPlatform, mPlatform, mConnectionRoad, ref mDirector));
                }
                else
                {
                    mRoadToBuild.Place(mOldHovering, mHoveringPlatform);
                }
                mIsFinished = true;
                mUnregister = true;
                mDirector.GetUserInterfaceController.BuildingProcessFinished();

                break;
            }

            if (mUnregister)
            {
                UnregisterFromInputManager();
            }

            // don't forget to always update the relative position since the camera might have moved.
            UpdateBounds();
        }