Пример #1
0
    /// <summary>
    /// Moves the <c>LevelElement</c> by a delta and sets all <c>Tile</c>-references correspondingly
    /// </summary>
    /// <param name="delta"></param>
    private void MoveElement(Vector2Int delta)
    {
        ISet <ILevelTile> oldTiles = GetTiles();

        if (oldTiles == null)
        {
            return;
        }
        if (oldTiles.Count == 0)
        {
            return;
        }
        ISet <ILevelTile> newTiles = new HashSet <ILevelTile>();

        foreach (LevelTile tile in oldTiles)
        {
            tile.RemoveLevelElement(this);

            Vector2Int newTilePos = new Vector2Int(tile.Pos.x + delta.x, tile.Pos.y + delta.y);
            ILevelTile newTile    = LevelController.instance.GetTileAtWorldPos(newTilePos);
            if (newTile == null)
            {
                continue;
            }
            newTiles.Add(newTile);
            newTile.AddLevelElement(this);
        }
        oldTiles.Clear();
        oldTiles.UnionWith(newTiles);
    }
    public void AStarEuclidian_CorrectPathFound_OneCorrectPath()
    {
        List <ILevelTile> expected = new List <ILevelTile>()
        {
            graphProvider.GetTileAtPos(new Vector2Int(2, 5)),
            graphProvider.GetTileAtPos(new Vector2Int(1, 5)),
            graphProvider.GetTileAtPos(new Vector2Int(1, 6)),
            graphProvider.GetTileAtPos(new Vector2Int(1, 7)),
            graphProvider.GetTileAtPos(new Vector2Int(2, 7)),
            graphProvider.GetTileAtPos(new Vector2Int(3, 7)),
            graphProvider.GetTileAtPos(new Vector2Int(4, 7)),
            graphProvider.GetTileAtPos(new Vector2Int(4, 6)),
            graphProvider.GetTileAtPos(new Vector2Int(4, 5)),
            graphProvider.GetTileAtPos(new Vector2Int(4, 4)),
            graphProvider.GetTileAtPos(new Vector2Int(5, 4)),
            graphProvider.GetTileAtPos(new Vector2Int(6, 4))
        };

        IPathFindingAlgorithm algo   = new AStarAlgorithm(graphProvider, new EuclidianHeuristic());
        ILevelTile            from   = graphProvider.GetTileAtPos(new Vector2Int(2, 5));
        ILevelTile            to     = graphProvider.GetTileAtPos(new Vector2Int(6, 4));
        IList <ILevelTile>    result = algo.CalculatePath(from, to);

        NUnit.Framework.Assert.IsTrue(result.Count == expected.Count);
        for (int i = 0; i < result.Count; ++i)
        {
            NUnit.Framework.Assert.IsTrue(result[i].Equals(expected[i]));
        }
    }
Пример #3
0
    public IList <ILevelTile> CalculatePath(ILevelTile from, ILevelTile to)
    {
        target       = to;
        openNodes    = new FibonacciHeap <float>();
        closedNodes  = new HashSet <AStarNode>();
        tilesToNodes = new Dictionary <ILevelTile, AStarNode>();

        AStarNode startNode = new AStarNode(from, heuristic.GetDistance(from.CenterPos, to.CenterPos));

        startNode.cost = 0;
        tilesToNodes.Add(from, startNode);
        openNodes.Insert(startNode);

        do
        {
            AStarNode currNode = (AStarNode)openNodes.ExtractMin();
            if (currNode.tile.Equals(to))
            {
                return(GetPathToNode(currNode));
            }

            closedNodes.Add(currNode);

            ExpandNode(currNode);
        } while (openNodes.IsEmpty() == false);

        // No path found
        return(null);
    }
Пример #4
0
    public ILevelTile GetTileAtPos(Vector2 pos)
    {
        int        x   = (int)pos.x;
        int        y   = (int)pos.y;
        ILevelTile ret = GetTileAtPos(new Vector2Int(x, y));

        return(ret);
    }
    public override ISet <ILevelTile> GetTiles()
    {
        ILevelTile        tile = LevelController.instance.GetTileAtWorldPos(Pos);
        ISet <ILevelTile> ret  = new HashSet <ILevelTile> {
            tile
        };

        return(ret);
    }
    public void AStarEuclidian_StartSameAsEnd()
    {
        IPathFindingAlgorithm algo   = new AStarAlgorithm(graphProvider, new EuclidianHeuristic());
        ILevelTile            from   = graphProvider.GetTileAtPos(new Vector2Int(1, 1));
        ILevelTile            to     = graphProvider.GetTileAtPos(new Vector2Int(1, 1));
        IList <ILevelTile>    result = algo.CalculatePath(from, to);

        NUnit.Framework.Assert.IsTrue(result.Count == 1);
    }
    public void AStarEuclidian_NoPathExistent()
    {
        IPathFindingAlgorithm algo   = new AStarAlgorithm(graphProvider, new EuclidianHeuristic());
        ILevelTile            from   = graphProvider.GetTileAtPos(new Vector2Int(6, 7));
        ILevelTile            to     = graphProvider.GetTileAtPos(new Vector2Int(1, 1));
        IList <ILevelTile>    result = algo.CalculatePath(from, to);

        NUnit.Framework.Assert.IsNull(result);
    }
    public bool CheckIfObjectCanBeMoved(IPlacedObject selectedObject, Vector2 position)
    {
        ILevelTile levelTile = GetLevelTile(position);

        if (levelTile.IsTraversable())
        {
            return(true);
        }
        return(false);
    }
    public void GetTileAtWorldPos_FloatCoordinatesOutOfRange_ReturnNull(float xCoordinate, float yCoordinate)
    {
        // Arrange.
        Vector2 positionToFetch = new Vector2(xCoordinate, yCoordinate);

        // Act.
        ILevelTile actualResult = levelController.GetTileAtWorldPos(positionToFetch);

        // Assert.
        NUnit.Framework.Assert.IsNull(actualResult);
    }
 private void MoveObjectToPlaceToMousePosition()
 {
     if (stateInformation.objectToPlace.Type == PrefabType.LEVELELEMENT)
     {
         Vector2    offset    = objectInformationModule.GetOffset(stateInformation.objectToPlace);
         ILevelTile levelTile = level.GetTileAtPos(mousePosition);
         Vector2    position  = (Vector2)levelTile.Pos;
         ((PlacedObject)stateInformation.objectToPlace).transform.position = position + offset;
     }
     else
     {
         ((PlacedObject)stateInformation.objectToPlace).transform.position = mousePosition;
     }
 }
    public ISet <ILevelTile> GetConnectedNavPoints(ILevelTile tile)
    {
        ISet <ILevelTile> ret           = new HashSet <ILevelTile>();
        LevelController   lvlController = LevelController.instance;

        if (lvlController == null)
        {
            Debug.LogError("No active LevelController. Cannot provide navigation graph!");
            return(ret);
        }

        // Orthogonal connected points
        ILevelTile upper      = lvlController.GetTileAtWorldPos(new Vector2(tile.Pos.x, tile.Pos.y + TILE_SIZE));
        bool       upperValid = upper != null && upper.IsTraversable();

        if (upperValid)
        {
            ret.Add(upper);
        }

        ILevelTile right      = lvlController.GetTileAtWorldPos(new Vector2(tile.Pos.x + TILE_SIZE, tile.Pos.y));
        bool       rightValid = right != null && right.IsTraversable();

        if (rightValid)
        {
            ret.Add(right);
        }

        ILevelTile lower      = lvlController.GetTileAtWorldPos(new Vector2(tile.Pos.x, tile.Pos.y - TILE_SIZE));
        bool       lowerValid = lower != null && lower.IsTraversable();

        if (lowerValid)
        {
            ret.Add(lower);
        }

        ILevelTile left      = lvlController.GetTileAtWorldPos(new Vector2(tile.Pos.x - TILE_SIZE, tile.Pos.y));
        bool       leftValid = left != null && left.IsTraversable();

        if (leftValid)
        {
            ret.Add(left);
        }

        // Diagonal connected points
        ret.UnionWith(GetDiagonalConnectedPoints(tile, lvlController, upperValid, rightValid, lowerValid, leftValid));

        return(ret);
    }
        public void GetTileAtPos_PosCoordinatesOutOfRange_ReturnNull(int xCoordinate, int yCoordinate, int levelLength, int levelHeight)
        {
            // Arrange.
            Vector2Int levelSize = new Vector2Int(levelLength, levelHeight);
            Vector2Int spawnPos  = new Vector2Int(5, 5);
            Level      level     = new Level(levelSize, spawnPos);

            Vector2Int posToFetch = new Vector2Int(xCoordinate, yCoordinate);

            // Act.
            ILevelTile levelTile = level.GetTileAtPos(posToFetch);

            // Assert.
            NUnit.Framework.Assert.IsNull(levelTile);
        }
    public IList <ILevelTile> GetLevelTiles(IPlacedObject placedObject, Vector2 position, ILevelElement levelElement)
    {
        IList <ILevelTile> levelTiles;

        if (placedObject.Type == PrefabType.LEVELELEMENT)
        {
            levelTiles = ((HashSet <ILevelTile>)levelElement.GetTiles()).ToList();
        }
        else
        {
            levelTiles = new List <ILevelTile>();
            ILevelTile levelTile = level.GetTileAtPos(position);
            levelTiles.Add(levelTile);
        }

        return(levelTiles);
    }
    public void AStarEuclidian_CorrectPathFound_MultipleCorrectPaths()
    {
        IPathFindingAlgorithm algo   = new AStarAlgorithm(graphProvider, new EuclidianHeuristic());
        ILevelTile            from   = graphProvider.GetTileAtPos(new Vector2Int(2, 5));
        ILevelTile            to     = graphProvider.GetTileAtPos(new Vector2Int(0, 1));
        IList <ILevelTile>    result = algo.CalculatePath(from, to);

        NUnit.Framework.Assert.IsTrue(result.Count == 23);

        float pathLength = 0f;

        for (int i = 1; i < result.Count; ++i)
        {
            pathLength += Vector2.Distance(result[i - 1].Pos, result[i].Pos);
        }
        NUnit.Framework.Assert.AreEqual(pathLength, 22f, 0.1f);
    }
    public void UpdateLevelTiles(IPlacedObject selectedObject)
    {
        Vector2 position = ((PlacedObject)selectedObject).gameObject.transform.position;

        if (selectedObject.Type == PrefabType.LEVELELEMENT)
        {
            ISet <ILevelTile> levelTiles = objectInformationModule.GetLevelTilesOfLevelElement(selectedObject, position);
            selectedObject.LevelTiles = levelTiles.ToList();
        }
        else
        {
            ILevelTile         levelTile  = objectInformationModule.GetLevelTile(position);
            IList <ILevelTile> levelTiles = new List <ILevelTile>();
            levelTiles.Add(levelTile);
            selectedObject.LevelTiles = levelTiles;
        }
    }
        public void GetTileAtPos_PosCoordinatesAreValid_ReturnLevelTileAtPos(int xCoordinate, int yCoordinate, int levelLength, int levelHeight)
        {
            // Arrange.
            Vector2Int levelSize = new Vector2Int(levelLength, levelHeight);
            Vector2Int spawnPos  = new Vector2Int(5, 5);
            Level      level     = new Level(levelSize, spawnPos);

            Vector2Int posToFetch = new Vector2Int(xCoordinate, yCoordinate);

            // Act.
            ILevelTile actualILevelTile = level.GetTileAtPos(posToFetch);

            // Assert.
            NUnit.Framework.Assert.IsNotNull(actualILevelTile);
            NUnit.Framework.Assert.IsInstanceOf <ILevelTile>(actualILevelTile);
            NUnit.Framework.Assert.AreEqual(posToFetch.x, actualILevelTile.Pos.x);
            NUnit.Framework.Assert.AreEqual(posToFetch.y, actualILevelTile.Pos.y);
        }
    private void FillTilesWithFloor()
    {
        Vector2Int levelSize = level.GetLevelSize();

        for (int x = 0; x < levelSize.x; ++x)
        {
            for (int y = 0; y < levelSize.y; ++y)
            {
                Vector2Int pos  = new Vector2Int(x, y);
                ILevelTile tile = level.GetTileAtPos(pos);

                FloorData floorData = new FloorData(pos);

                ILevelElement floor = LevelElementFactory.InstantiateLevelElement(floorData, transform);
                levelDataManager.AddLevelElement(floor);
            }
        }
    }
    private ISet <ILevelTile> GetDiagonalConnectedPoints(ILevelTile tile, LevelController lvlController, bool upperValid, bool rightValid, bool lowerValid, bool leftValid)
    {
        ISet <ILevelTile> ret = new HashSet <ILevelTile>();

        if (upperValid && rightValid)
        {
            ILevelTile upperRight = lvlController.GetTileAtWorldPos(new Vector2(tile.Pos.x + TILE_SIZE, tile.Pos.y + TILE_SIZE));
            if (upperRight != null && upperRight.IsTraversable())
            {
                ret.Add(upperRight);
            }
        }

        if (rightValid && lowerValid)
        {
            ILevelTile lowerRight = lvlController.GetTileAtWorldPos(new Vector2(tile.Pos.x + TILE_SIZE, tile.Pos.y - TILE_SIZE));
            if (lowerRight != null && lowerRight.IsTraversable())
            {
                ret.Add(lowerRight);
            }
        }

        if (upperValid && leftValid)
        {
            ILevelTile upperLeft = lvlController.GetTileAtWorldPos(new Vector2(tile.Pos.x - TILE_SIZE, tile.Pos.y + TILE_SIZE));
            if (upperLeft != null && upperLeft.IsTraversable())
            {
                ret.Add(upperLeft);
            }
        }

        if (lowerValid && leftValid)
        {
            ILevelTile lowerLeft = lvlController.GetTileAtWorldPos(new Vector2(tile.Pos.x - TILE_SIZE, tile.Pos.y - TILE_SIZE));
            if (lowerLeft != null && lowerLeft.IsTraversable())
            {
                ret.Add(lowerLeft);
            }
        }

        return(ret);
    }
        public void GetTileAtPos_UseFloatArgument_ReturnLevelTileAtCuttedPos(float xCoordinate, float yCoordinate, int levelLength, int levelHeight)
        {
            // Arrange.
            Vector2Int levelSize = new Vector2Int(100, 100);
            Level      level     = new Level(levelSize, spawnPosition);

            Vector2    FloatPosToFetch = new Vector2(xCoordinate, yCoordinate);
            Vector2Int IntPosToFetch   = new Vector2Int((int)FloatPosToFetch.x, (int)FloatPosToFetch.y);

            // Act.
            ILevelTile actualILevelTile   = level.GetTileAtPos(FloatPosToFetch);
            ILevelTile expectedILevelTile = level.GetTileAtPos(IntPosToFetch);


            // Assert.
            NUnit.Framework.Assert.IsNotNull(actualILevelTile);
            NUnit.Framework.Assert.IsInstanceOf <ILevelTile>(actualILevelTile);
            NUnit.Framework.Assert.AreEqual(expectedILevelTile, actualILevelTile);
            NUnit.Framework.Assert.AreEqual(IntPosToFetch.x, actualILevelTile.Pos.x);
            NUnit.Framework.Assert.AreEqual(IntPosToFetch.y, actualILevelTile.Pos.y);
        }
    public IList <Vector2> GetPathTo(Vector2 from, Vector2 to)
    {
        if (pathFindingAlgorithm == null)
        {
            pathFindingAlgorithm = new AStarAlgorithm(this, new EuclidianHeuristic());
        }
        ILevelTile fromTile = LevelController.instance.GetTileAtWorldPos(from);
        ILevelTile toTile   = LevelController.instance.GetTileAtWorldPos(to);

        if (cache.TryGetPath(fromTile, toTile, out IList <ILevelTile> path) == false)
        {
            path = pathFindingAlgorithm.CalculatePath(fromTile, toTile);
            cache.CachePath(path);
        }
        if (path == null)
        {
            return(null);
        }
        // Convert Tile to Point-Path
        IList <Vector2> ret = new List <Vector2>();

        foreach (ILevelTile tile in path)
        {
            ret.Add(tile.CenterPos);
        }
        // Add last if not included in tilepath
        if (ret.Count != 0)
        {
            if ((ret[ret.Count - 1] - to).magnitude > 0.1f)
            {
                ret.Add(to);
            }
        }
        // insert start point in between for path processing, then remove it again as agents shoul always move to the next pont.
        ret.Insert(0, from);
        pathProcessor.ProcessPath(ret);
        ret.RemoveAt(0);

        return(ret);
    }
        public ISet <ILevelTile> GetConnectedNavPoints(ILevelTile tile)
        {
            ISet <ILevelTile> ret = new HashSet <ILevelTile>();

            if (tile.Pos.x > 0)
            {
                Vector2Int left = new Vector2Int(tile.Pos.x - 1, tile.Pos.y);
                if (excludedNavPoints.Contains(left) == false)
                {
                    ret.Add(GetTileAtPos(left));
                }
            }
            if (tile.Pos.x < size.x - 1)
            {
                Vector2Int right = new Vector2Int(tile.Pos.x + 1, tile.Pos.y);
                if (excludedNavPoints.Contains(right) == false)
                {
                    ret.Add(GetTileAtPos(right));
                }
            }
            if (tile.Pos.y > 0)
            {
                Vector2Int bottom = new Vector2Int(tile.Pos.x, tile.Pos.y - 1);
                if (excludedNavPoints.Contains(bottom) == false)
                {
                    ret.Add(GetTileAtPos(bottom));
                }
            }
            if (tile.Pos.y < size.y - 1)
            {
                Vector2Int top = new Vector2Int(tile.Pos.x, tile.Pos.y + 1);
                if (excludedNavPoints.Contains(top) == false)
                {
                    ret.Add(GetTileAtPos(top));
                }
            }

            return(ret);
        }
    public void GetTileAtWorldPos_FloatCoordinatesAreValid_ReturnWorldPosition(float xCoordinate, float yCoordinate)
    {
        // Arrange.
        Vector2Int dummyLevelSize = new Vector2Int(100, 100);
        Vector2Int spawnPos       = new Vector2Int(5, 5);
        Level      dummyLevel     = new Level(dummyLevelSize, spawnPos);

        PrivateObject internLevelController = new PrivateObject(levelController);

        internLevelController.SetField("level", dummyLevel);

        Vector2 positionToFetch = new Vector2(xCoordinate, yCoordinate);

        ILevelTile expectedResult = dummyLevel.GetTileAtPos(positionToFetch);

        // Act.
        ILevelTile actualResult = levelController.GetTileAtWorldPos(positionToFetch);

        // Assert.
        NUnit.Framework.Assert.IsNotNull(actualResult);
        NUnit.Framework.Assert.AreEqual(expectedResult, actualResult);
    }
Пример #23
0
    public ILevelTile GetTileAtPos(Vector2Int pos)
    {
        if (pos.x < 0)
        {
            return(null);
        }
        if (pos.y < 0)
        {
            return(null);
        }
        if (pos.x >= tiles.GetLength(0))
        {
            return(null);
        }
        if (pos.y >= tiles.GetLength(1))
        {
            return(null);
        }
        ILevelTile ret = tiles[pos.x, pos.y];

        return(ret);
    }
    public ISet <ILevelTile> GetLevelTilesOfLevelElement(IPlacedObject placedObject, Vector2 worldPosition)
    {
        Vector2 size     = GetSizeOfLevelElement(placedObject);
        Vector2 position = GetPositionOfLevelTile(worldPosition);

        ISet <ILevelTile> levelTiles = new HashSet <ILevelTile>();

        for (int x = 0; x < size.x; x++)
        {
            for (int y = 0; y < size.y; y++)
            {
                // position is the position of the lower left corner of the levelElement
                Vector2    levelTilePos = new Vector2(position.x + x, position.y + y);
                ILevelTile levelTile    = GetLevelTile(levelTilePos);
                if (levelTile == null)
                {
                    continue;
                }
                levelTiles.Add(levelTile);
            }
        }
        return(levelTiles);
    }
Пример #25
0
    private void FillEmptyTilesWithFloor(IList <ILevelElement> levelElements, Transform parent)
    {
        if (currentLevel == null)
        {
            return;
        }
        Vector2Int levelSize = currentLevel.GetLevelSize();

        for (int x = 0; x < levelSize.x; ++x)
        {
            for (int y = 0; y < levelSize.y; ++y)
            {
                Vector2Int pos  = new Vector2Int(x, y);
                ILevelTile tile = currentLevel.GetTileAtPos(pos);
                if (tile.LevelElements != null)
                {
                    bool containsSolidElement = false;
                    foreach (ILevelElement element in tile.LevelElements)
                    {
                        if (element.IsSolid())
                        {
                            containsSolidElement = true;
                            break;
                        }
                    }
                    if (containsSolidElement)
                    {
                        continue;
                    }
                }
                FloorData floorData = new FloorData(pos);

                ILevelElement floor = LevelElementFactory.InstantiateLevelElement(floorData, parent);
                levelElements.Add(floor);
            }
        }
    }
    public Vector2 GetPositionOfLevelTile(Vector2 position)
    {
        ILevelTile levelTile = GetLevelTile(position);

        return(levelTile.Pos);
    }
 public AStarNode(ILevelTile tile, float heuristicValue) : base(float.MaxValue)
 {
     this.tile           = tile;
     this.heuristicValue = heuristicValue;
     cost = float.MaxValue;
 }