/// <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" /> < 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); } } } }
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; } }
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(); }
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(); }