/// <summary>
        ///     Field Of View.
        ///     Returns All visiable <see cref="IHexCoordinate" /> within <paramref name="radius" />.
        /// </summary>
        /// <param name="coordinate">Current <see cref="IHexCoordinate" />.</param>
        /// <param name="radius">Radius from <paramref name="coordinate" />. 0 returns <paramref name="coordinate" />.</param>
        /// <param name="isOpaque">Returns if <see cref="IHexCoordinate" /> is opaque.</param>
        /// <returns>All visiable <see cref="IHexCoordinate" />.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="radius" /> &lt; 0. </exception>
        /// <exception cref="ArgumentNullException"><paramref name="coordinate" /> or <paramref name="isOpaque" /> is null.</exception>
        public static IEnumerable <IHexCoordinate> FieldOfView(this IHexCoordinate coordinate, int radius,
                                                               Func <IHexCoordinate, bool> isOpaque)
        {
            if (coordinate == null)
            {
                throw new ArgumentNullException("coordinate");
            }
            if (isOpaque == null)
            {
                throw new ArgumentNullException("isOpaque");
            }
            if (radius < 0)
            {
                throw new ArgumentOutOfRangeException();
            }
            if (isOpaque(coordinate))
            {
                yield break;
            }
            yield return(coordinate);

            if (radius == 0)
            {
                yield break;
            }
            var shadowCast = new ShadowCast();

            for (var ringIndex = 1; ringIndex <= radius; ringIndex++)
            {
                var isEven = ringIndex % 2 == 0;
                var slide  = (double)360 / (6 * ringIndex);
                for (var hexIndex = 0; hexIndex < ringIndex * 6; hexIndex++)
                {
                    var ring     = new RingHexCoordinate(coordinate, ringIndex, hexIndex);
                    var current  = ring.ConvertTo();
                    var minAngle = hexIndex * slide;
                    if (isEven)
                    {
                        minAngle -= slide / 2;
                    }
                    var maxAngle = minAngle + slide;
                    var center   = (maxAngle + minAngle) / 2.0;
                    // Ignore if the center of the hex cannot be seen
                    if (shadowCast.Hide(center))
                    {
                        continue;
                    }
                    yield return(current);

                    // Add to shadow if the hex is opaque
                    if (isOpaque(current))
                    {
                        shadowCast.AddShadow(minAngle, maxAngle);
                    }
                }
            }
        }
示例#2
0
        public void HandleKey(RLKeyPress keyPress)
        {
            switch (keyPress.Key)
            {
            case RLKey.Up:
            {
                if (!map.canMove(Players[LocalName].pos, 0, -1))
                {
                    return;
                }
                map.resetLight();
                Players[LocalName].move(0, -1);
                var pos = new Vector2(Players[LocalName].pos.x, Players[LocalName].pos.y);
                ShadowCast.ComputeVisibility(map.grid, pos, 7.5f);
                updatePlayer();
            }
            break;

            case RLKey.Down:
            {
                if (!map.canMove(Players[LocalName].pos, 0, 1))
                {
                    return;
                }
                map.resetLight();
                Players[LocalName].move(0, 1);
                var pos = new Vector2(Players[LocalName].pos.x, Players[LocalName].pos.y);
                ShadowCast.ComputeVisibility(map.grid, pos, 7.5f);
                updatePlayer();
            }
            break;

            case RLKey.Left:
            {
                if (!map.canMove(Players[LocalName].pos, -1, 0))
                {
                    return;
                }
                map.resetLight();
                Players[LocalName].move(-1, 0);
                var pos = new Vector2(Players[LocalName].pos.x, Players[LocalName].pos.y);
                ShadowCast.ComputeVisibility(map.grid, pos, 7.5f);
                updatePlayer();
            }
            break;

            case RLKey.Right:
            {
                if (!map.canMove(Players[LocalName].pos, 1, 0))
                {
                    return;
                }
                map.resetLight();
                Players[LocalName].move(1, 0);
                var pos = new Vector2(Players[LocalName].pos.x, Players[LocalName].pos.y);
                ShadowCast.ComputeVisibility(map.grid, pos, 7.5f);
                updatePlayer();
            }
            break;

            default:
                break;
            }
        }
示例#3
0
    public void Set_Manager(GameManager gamemanager)  //Awake에 해당한다. 시작시 호출
    {
        this.GameManager = gamemanager;
        PlayerManager    = GameManager.PlayerManager; //게임 매니저로 부터 Manager를 받아온다
        CameraManager    = GameManager.CameraManager;

        ShadowCast = new ShadowCast(this); //전장의 안개
        A_Star     = new A_Star(this);     //A*알고리즘
        MapPattern = new MapPattern(this); //맵 패턴 함수
        MapHightLight.Set_Map(this);
        Tile_Event.Set_Map(this);

        VisibleOctants = new List <int>()
        {
            1, 2, 3, 4, 5, 6, 7, 8
        };
        Map_Gimmick_List = new List <GameObject>();
        Pooling_Count    = 15;
        Tiles            = new Tile_Obj[Pooling_Count, Pooling_Count];
        MapSize          = 64;
        VisualRange      = 5;
        roomMin          = 6;
        roomMax          = 13;

        if (GameManager.Get_GameData() != null)    //게임 데이터가 있을때 Load 해준다
        {
        }
        else                    //게임 데이터가 없을때 시작
        {
            Current_Stage = 1;
            MapData       = new Tile[MapSize + 1, MapSize + 1];
            RoomData_List = new List <RoomData>();

            BuildMap();                     //맵 정보 생성
        }

        for (int i = 0; i < Pooling_Count; i++)                //풀링 Object 할당
        {
            for (int j = 0; j < Pooling_Count; j++)
            {
                Tiles[i, j] = Tile_Objs.transform.GetChild(Get_Array_Count(i, j)).GetComponent <Tile_Obj>();
                Tiles[i, j].Set_Tile(this, new Array_Index(i, j));
            }
        }

        //while(GetTile(6, 6).Tile_Sort.TileBase == eTileBase.NULL ||
        //    GetTile(57, 57).Tile_Sort.TileBase == eTileBase.NULL ||
        //    GetTile(6, 6).Tile_Sort.TileObject == eTileObject.WALL ||
        //    GetTile(57, 57).Tile_Sort.TileObject == eTileObject.WALL)
        //{
        //    MapData = new Tile[MapSize + 1, MapSize + 1];


        //    BuildMap();
        //}



        //Update_TT();
        Update_Sight();
        Update_Tiles();                   //맵 정보를 기반으로 Tile 업데이트
        MapTarget.Set_Map(this);
        //link();
    }
示例#4
0
    public void UpdateFogOfWar(Vector3 playerPosition)
    {
        Vector3Int tilePosition = WorldToTile(playerPosition - new Vector3(0.5f, 0.5f, 0f));
        int        intViewRange = (int)_viewRange + 1;
        BoundsInt  fowBounds    = new BoundsInt(tilePosition - new Vector3Int(intViewRange, intViewRange, 0), new Vector3Int(2 * intViewRange + 1, 2 * intViewRange + 1, 0));

        float[,] visibility = new float[fowBounds.size.x, fowBounds.size.y];
        ShadowCast.CalculateVisibility(playerPosition - _origin, fowBounds, _tiles, visibility);

        for (int x = fowBounds.xMin; x < fowBounds.xMax; x++)
        {
            if (x < 0 || x >= _size.x)
            {
                continue;
            }

            for (int y = fowBounds.yMin; y < fowBounds.yMax; y++)
            {
                if (y < 0 || y >= _size.y)
                {
                    continue;
                }

                Vector3Int pos      = new Vector3Int(x, y, 0);
                TileType   tileType = _tiles[x, y];

                float distance    = Vector3.Distance(playerPosition - new Vector3(0.5f, 0.5f, 0f), TileToWorld(pos));
                Color pixelColor  = FoWTexture.GetPixel(pos.x, pos.y);
                Color targetColor = pixelColor;
                float fuzzRange   = 2f;
                float vis         = visibility[x - fowBounds.xMin, y - fowBounds.yMin];
                if (distance < _viewRange - fuzzRange)
                {
                    targetColor.r = 1f;
                    //targetColor.g = 1f;
                }
                else if (distance > _viewRange)
                {
                    targetColor.r = 0f;
                }
                else
                {
                    float frac = (_viewRange - distance) / fuzzRange;
                    targetColor.r = frac;
                    //targetColor.g = Mathf.Max(pixelColor.g, frac);
                }

                targetColor.r *= vis;
                targetColor.g  = Mathf.Max(targetColor.g, targetColor.r);

                if (targetColor.r > 0f)
                {
                    if (x == tilePosition.x && y == tilePosition.y)
                    {
                        targetColor.b = 1.0f;
                    }
                    else if (tileType.HasFlag(TileType.Wall))
                    {
                        targetColor.b = 0.75f;
                    }
                    else if (tileType.HasFlag(TileType.Floor))
                    {
                        targetColor.b = 0.5f;
                    }
                }

                FoWTexture.SetPixel(pos.x, pos.y, targetColor);
            }
        }


        SetTexture();
    }