Beispiel #1
0
    private List <AstarTile> GetWalkableTiles(int[] map, AstarTile currentTile, AstarTile targetTile)
    {
        var possibleTiles = new List <AstarTile>()
        {
            new AstarTile {
                X = currentTile.X, Y = currentTile.Y - 1, Parent = currentTile, Cost = currentTile.Cost + 1
            },
            new AstarTile {
                X = currentTile.X, Y = currentTile.Y + 1, Parent = currentTile, Cost = currentTile.Cost + 1
            },
            new AstarTile {
                X = currentTile.X - 1, Y = currentTile.Y, Parent = currentTile, Cost = currentTile.Cost + 1
            },
            new AstarTile {
                X = currentTile.X + 1, Y = currentTile.Y, Parent = currentTile, Cost = currentTile.Cost + 1
            },
        };

        possibleTiles.ForEach(tile => tile.SetDistance(targetTile.X, targetTile.Y));

        return(possibleTiles
               .Where(tile => tile.X >= 0 && tile.X < _width)
               .Where(tile => tile.Y >= 0 && tile.Y < _height)
               .Where(tile => map[tile.Y * 8 + tile.X] == 0)  // || tile.Y =   // map[tile.Y * 8 + tile.X] == 'B')
               .ToList());
    }
Beispiel #2
0
    public void SetTile(AstarTile _lastindex, List <AstarTile> _openlist, Position _endpos)
    {
        if (tileData.tileRestriction == TILE_RESTRICTION.FORBIDDEN ||
            tileData.tileRestriction == TILE_RESTRICTION.OCCUPIED)
        {
            return;                                                        //이동 할 수 없는 타일이면 리턴
        }
        //비행형일시 다른 제한값 필요
        //몬스터의 검색범위 한정 필요

        if (!isListed)               //오픈 리스트에 없다면
        {
            isListed = true;         //트루로 바꾸고
            _openlist.Add(this);     //오픈 리스트에 추가
            CalcH(_endpos);          //H값 계산 적용
            G = _lastindex.G + 14;   //G값 계산 적용
            CalcF();                 //F계산
            parentTile = _lastindex; //검색타일을 부모로 설정
        }
        else //오픈 리스트에 있다면
        {
            if (_lastindex.G + 14 < G)   //기존 G보다 새로운 G가 작다면
            {
                G = _lastindex.G + 14;   //G값 다시 적용
                CalcF();                 //새로운 F계산
                parentTile = _lastindex; //검색타일을 부모로 설정
            }
        }
    }
Beispiel #3
0
    public void AstarInit()
    {
        //해당 층에서 필요한 타일맵 정보를 받아온다.

        mapHeight   = TileManager.Instance.mapHeight;
        mapWidth    = TileManager.Instance.mapWidth;
        tileMapInfo = TileManager.Instance.tileMapInfoArray;

        astarTiles = new AstarTile[mapWidth, mapHeight];

        for (int i = 0; i < mapHeight; i++)
        {
            for (int j = 0; j < mapWidth; j++)
            {
                astarTiles[j, i]            = new AstarTile();
                astarTiles[j, i].tileData   = new TileData();
                astarTiles[j, i].parentTile = new AstarTile();
                astarTiles[j, i].Init();
                astarTiles[j, i].position.PosX = j;
                astarTiles[j, i].position.PosY = i;
                astarTiles[j, i].tileData      = tileMapInfo[j, i].tileData; //참조 형식 X
            }
        }

        lastIndex = 0;
        openList  = new List <AstarTile>();
        closeList = new List <AstarTile>();
        pathList  = new List <TileData>();
    }
Beispiel #4
0
    public int H; //여기부터 끝까지

    public void Init()
    {
        parentTile = null;
        isListed   = false;
        F          = 5000;
        G          = 0;
        H          = 0;
    }
Beispiel #5
0
    void MakePath(AstarTile _tile, Position _beginpos)
    {
        pathList.Add(_tile.tileData);

        _tile = _tile.parentTile; //타일의 부모를 참조

        if (_tile.tileData.position.PosX == _beginpos.PosX &&
            _tile.tileData.position.PosY == _beginpos.PosY) //시작점까지 왔으면 그만
        {
            pathList.Reverse();
            return;
        }
        else
        {
            MakePath(_tile, _beginpos); //다시 호출
        }
    }
Beispiel #6
0
    public bool WalkToTarget(int sx, int sy, int fx, int fy, int[] usable)
    {
        NextTile = null;

        Array.Clear(_map, 0, _map.Length);

        for (int i = 0; i < _map.Length; i++)
        {
            if (!usable.Contains(i))
            {
                _map[i] = 1;
            }
        }

        // Set the start to walkable ;)
        _map[sy * 8 + sx] = 0;

        var start = new AstarTile()
        {
            X = sx, Y = sy
        };
        var finish = new AstarTile()
        {
            X = fx, Y = fy
        };

        start.SetDistance(finish.X, finish.Y);

        var activeTiles = new List <AstarTile>();

        activeTiles.Add(start);
        var visitedTiles = new List <AstarTile>();

        while (activeTiles.Any())
        {
            var checkTile = activeTiles.OrderBy(x => x.CostDistance).First();

            if (checkTile != null && checkTile.X == finish.X && checkTile.Y == finish.Y)
            {
                // Walk back through the tiles to the tile AFTER the start.
                // That's going to be our next tile
                var tile = checkTile;
                while (tile?.Parent != null && tile?.Parent != start)
                {
                    tile = tile?.Parent;
                }

                NextTile = tile;
                // Only return true if we have a tile and it's NOT the player's tile
                return(NextTile != null && NextTile.X != fx && NextTile.Y != fy);
            }

            visitedTiles.Add(checkTile);
            activeTiles.Remove(checkTile);

            var walkableTiles = GetWalkableTiles(_map, checkTile, finish);

            foreach (var walkableTile in walkableTiles)
            {
                //We have already visited this tile so we don't need to do so again!
                if (visitedTiles.Any(x => x.X == walkableTile.X && x.Y == walkableTile.Y))
                {
                    continue;
                }

                //It's already in the active list, but that's OK, maybe this new tile has a better value (e.g. We might zigzag earlier but this is now straighter).
                if (activeTiles.Any(x => x.X == walkableTile.X && x.Y == walkableTile.Y))
                {
                    var existingTile = activeTiles.First(x => x.X == walkableTile.X && x.Y == walkableTile.Y);
                    if (existingTile.CostDistance > checkTile.CostDistance)
                    {
                        activeTiles.Remove(existingTile);
                        activeTiles.Add(walkableTile);
                    }
                }
                else
                {
                    //We've never seen this tile before so add it to the list.
                    activeTiles.Add(walkableTile);
                }
            }
        }

        // No path found
        return(false);
    }