TD_Tile GetTileByPosition(Vector3 argPos) { for (int y = 0; y < map_.map_size_.x; y++) { for (int x = 0; x < map_.map_size_.y; x++) { if (null == map_.map_tiles_[y, x]) { continue; } TD_Tile ls_tile = map_.map_tiles_[y, x]; //check x axis bounds if (ls_tile.transform.position.x + delta >= argPos.x && ls_tile.transform.position.x - delta <= argPos.x) { //check z axis bounds if (ls_tile.transform.position.z + delta >= argPos.z && ls_tile.transform.position.z - delta <= argPos.z) { return(ls_tile); } } } } return(null); }
private List <TD_Tile> GetNeighbours(TD_Tile arg_node) { //adjusted the algorithm to only allow non diagonal movement List <TD_Tile> ls_neighbours = new List <TD_Tile>(); if (arg_node.IndexX - 1 >= 0) { //left ls_neighbours.Add(map_.map_tiles_[arg_node.IndexY, arg_node.IndexX - 1]); } if (arg_node.IndexX + 1 < map_.map_size_.x) { //right ls_neighbours.Add(map_.map_tiles_[arg_node.IndexY, arg_node.IndexX + 1]); } //behind if (arg_node.IndexY - 1 >= 0) { ls_neighbours.Add(map_.map_tiles_[arg_node.IndexY - 1, arg_node.IndexX]); } //forward if (arg_node.IndexY + 1 < map_.map_size_.y) { ls_neighbours.Add(map_.map_tiles_[arg_node.IndexY + 1, arg_node.IndexX]); } return(ls_neighbours); }
float GetDistance(TD_Tile arg_tile_a, TD_Tile arg_tile_b) { //currently uses manhattan distance to change to euclidian we find dxy = sqrt((a-b)^2) float lsDeltaX = Mathf.Abs(arg_tile_a.transform.position.x - arg_tile_b.transform.position.x); float lsDeltaY = Mathf.Abs(arg_tile_a.transform.position.z - arg_tile_b.transform.position.z); return(lsDeltaX + lsDeltaY); //return (lsDeltaX > lsDeltaY) ? CalcDistance(lsDeltaX, lsDeltaY) : CalcDistance(lsDeltaY, lsDeltaX); }
public void SetDestination(TD_Tile arg_tile) { if (null != destination_ && arg_tile.Content.Type == TileContentType.EMPTY) { destination_.Content = tile_factory_.Get(TileContentType.EMPTY); } if (arg_tile.Content.Type == TileContentType.EMPTY) { destination_ = arg_tile; arg_tile.Content = tile_factory_.Get(TileContentType.DESTINATION); } }
public void ToggleSpawn(TD_Tile arg_tile) { if (null != spawn_ && arg_tile.Content.Type == TileContentType.EMPTY) { spawn_.Content = tile_factory_.Get(TileContentType.EMPTY); } if (arg_tile.Content.Type == TileContentType.EMPTY) { spawn_ = arg_tile; arg_tile.Content = tile_factory_.Get(TileContentType.SPAWN); } }
public void ToggleWall(TD_Tile arg_tile) { if (arg_tile.Content.Type == TileContentType.WALL) { //set blocking of tile too arg_tile.Content = tile_factory_.Get(TileContentType.EMPTY); arg_tile.is_blocking_ = false; return; } //ditto arg_tile.Content = tile_factory_.Get(TileContentType.WALL); arg_tile.is_blocking_ = true; }
public bool ToggleTower(TD_Tile arg_tile) { if (arg_tile.Content.Type == TileContentType.WALL) { arg_tile.Content = tile_factory_.Get(TileContentType.TOWER); return(true); } else if (arg_tile.Content.Type == TileContentType.TOWER) { arg_tile.Content = tile_factory_.Get(TileContentType.WALL); return(false); } return(false); }
public bool ToggleOil(TD_Tile arg_tile) { if (arg_tile.Content.Type == TileContentType.OIL) { arg_tile.Content = tile_factory_.Get(TileContentType.EMPTY); return(false); } else if (arg_tile.Content.Type == TileContentType.EMPTY) { arg_tile.Content = tile_factory_.Get(TileContentType.OIL); return(true); } return(false); }
private List <TD_Tile> TracePath(TD_Tile arg_start, TD_Tile arg_dest) { Debug.Log("Start Trace"); List <TD_Tile> ls_path = new List <TD_Tile>(); TD_Tile ls_current = arg_dest; ls_path.Add(arg_dest); //traverse parents from dest to start while (ls_current.Parent != null) { ls_path.Add(ls_current.Parent); //ls_current.GetComponentInChildren<MeshRenderer>().material = (Material)(Resources.Load("pathing")); ls_current = ls_current.Parent; } ls_path.Reverse(); return(ls_path); }
private void GetTileInformation() { for (int i_y = 0; i_y < map_.map_size_.y; i_y++) { for (int i_x = 0; i_x < map_.map_size_.x; i_x++) { TD_Tile ls_tile = map_.map_tiles_[i_y, i_x]; //only save the tiles that arent empty if (TileContentType.EMPTY == ls_tile.Content.Type) { continue; } //saves the index of the tile and the type of content the tile holds tile_attributes_.Add(i_y + BREAK_CHAR_ + i_x + BREAK_CHAR_ + (int)(ls_tile.content_.Type) + BREAK_CHAR_ + "\n"); } } //add in map size to init then the non empty tiles file_contents_to_add_ = map_.map_size_.x + BREAK_CHAR_ + map_.map_size_.y + BREAK_CHAR_ + "\n" + string.Concat(tile_attributes_.ToArray()); }
public void Init(int arg_x, int arg_y, TD_Tile_Factory arg_factory) { spawn_points_ = new List <TD_Tile>(); this.map_size_ = new Vector2Int(arg_x, arg_y); this.tile_factory_ = arg_factory; map_tiles_ = new TD_Tile[arg_y, arg_x]; //offset caries on tile scale; this could be 0.5 for performance sake Vector2 ls_offset = new Vector2((map_size_.x - 1) * (prefab_tile_.transform.localScale.x / 2), (map_size_.y - 1) * (prefab_tile_.transform.localScale.y / 2)); for (int i_y = 0; i_y < map_size_.y; i_y++) { for (int i_x = 0; i_x < map_size_.x; i_x++) { TD_Tile ls_tile = map_tiles_[i_y, i_x] = Instantiate(prefab_tile_); ls_tile.transform.position = new Vector3(i_x - ls_offset.x, 0, i_y - ls_offset.y); ls_tile.Content = tile_factory_.Get(TileContentType.EMPTY); ls_tile.Parent = null; ls_tile.g = int.MaxValue; ls_tile.IndexX = i_x; ls_tile.IndexY = i_y; } } }
public List <TD_Tile> ResolveAStar(TD_Tile arg_start, TD_Tile arg_dest, EnemyType arg_type) { if (null == arg_start || null == arg_dest) { return(null); } for (int y = 0; y < map_.map_tiles_.GetLength(0); y++) { for (int x = 0; x < map_.map_tiles_.GetLength(1); x++) { map_.map_tiles_[y, x].g = int.MaxValue; } } List <TD_Tile> ls_open_items = new List <TD_Tile> { arg_start }; HashSet <TD_Tile> ls_closed_items = new HashSet <TD_Tile>(); arg_start.g = 0; arg_start.h = GetDistance(arg_start, arg_dest); arg_start.fCost(); TD_Tile ls_current_tile = ls_open_items[0]; while (ls_open_items.Count > 0) { if (ls_current_tile == arg_dest) { return(TracePath(arg_start, arg_dest)); } ls_current_tile = ls_open_items[0]; for (int i = 1; i < ls_open_items.Count; i++) { if (ls_open_items[i].GetFCost() < ls_current_tile.GetFCost()) { ls_current_tile = ls_open_items[i]; } } ls_open_items.Remove(ls_current_tile); ls_closed_items.Add(ls_current_tile); foreach (TD_Tile neighbour in GetNeighbours(ls_current_tile)) { if (ls_closed_items.Contains(neighbour)) { continue; } if (neighbour.is_blocking_) { continue; } double modifier_ = 1.0f; //if there is an oil slick and the enemy isnt floating //scalable version would use GetTileModifier and have that saved per tile type if (TileContentType.OIL == neighbour.Content.Type && arg_type != EnemyType.HOVERING) { modifier_ = 5.0f; } double lsPredictedGCost = ls_current_tile.g + (GetDistance(ls_current_tile, neighbour) * modifier_); if (lsPredictedGCost < neighbour.g) { neighbour.Parent = ls_current_tile; neighbour.g = lsPredictedGCost; //we can adjust this value to perform djikstras by making the heuristic = 0; currently using the best first neighbour.h = GetDistance(neighbour, arg_dest); neighbour.fCost(); if (!ls_open_items.Contains(neighbour)) { //neighbour.GetComponentInChildren<MeshRenderer>().material = (Material)(Resources.Load("pathing")); if (neighbour == arg_dest) { return(TracePath(arg_start, arg_dest)); } ls_open_items.Add(neighbour); } } } } return(null); }
public void Init(TD_Tile_Factory arg_factory, List <Vector3Int> arg_loaded_tiles) { spawn_points_ = new List <TD_Tile>(); this.map_size_ = new Vector2Int(arg_loaded_tiles[0].x, arg_loaded_tiles[0].y); this.tile_factory_ = arg_factory; map_tiles_ = new TD_Tile[map_size_.y, map_size_.x]; //offset caries on tile scale; this could be 0.5 for performance sake Vector2 ls_offset = new Vector2((map_size_.x - 1) * (prefab_tile_.transform.localScale.x / 2), (map_size_.y - 1) * (prefab_tile_.transform.localScale.y / 2)); int ls_loaded_tiles_index = 1; for (int i_y = 0; i_y < map_size_.y; i_y++) { for (int i_x = 0; i_x < map_size_.x; i_x++) { TD_Tile ls_tile; if (ls_loaded_tiles_index < arg_loaded_tiles.Count) { if (arg_loaded_tiles[ls_loaded_tiles_index].x == i_x && arg_loaded_tiles[ls_loaded_tiles_index].y == i_y) { ls_tile = map_tiles_[i_y, i_x] = Instantiate(prefab_tile_); ls_tile.transform.position = new Vector3(i_x - ls_offset.x, 0, i_y - ls_offset.y); ls_tile.Content = tile_factory_.Get((TileContentType)(arg_loaded_tiles[ls_loaded_tiles_index].z)); //should be a switch here if (TileContentType.DESTINATION == ls_tile.Content.Type) { destination_ = ls_tile; ls_tile.is_blocking_ = false; ls_tile.Parent = null; ls_tile.g = int.MaxValue; ls_tile.IndexX = i_x; ls_tile.IndexY = i_y; ls_loaded_tiles_index++; continue; } else if (TileContentType.SPAWN == ls_tile.Content.Type) { spawn_points_.Add(ls_tile); ls_tile.is_blocking_ = false; ls_tile.Parent = null; ls_tile.g = int.MaxValue; ls_tile.IndexX = i_x; ls_tile.IndexY = i_y; ls_loaded_tiles_index++; continue; } else if (TileContentType.OIL == ls_tile.Content.Type) { ls_tile.is_blocking_ = false; ls_tile.Parent = null; ls_tile.g = int.MaxValue; ls_tile.IndexX = i_x; ls_tile.IndexY = i_y; ls_loaded_tiles_index++; continue; } ls_tile.is_blocking_ = true; ls_tile.Parent = null; ls_tile.g = int.MaxValue; ls_tile.IndexX = i_x; ls_tile.IndexY = i_y; ls_loaded_tiles_index++; continue; } } ls_tile = map_tiles_[i_y, i_x] = Instantiate(prefab_tile_); ls_tile.transform.position = new Vector3(i_x - ls_offset.x, 0, i_y - ls_offset.y); ls_tile.Content = tile_factory_.Get(TileContentType.EMPTY); ls_tile.Parent = null; ls_tile.g = int.MaxValue; ls_tile.IndexX = i_x; ls_tile.IndexY = i_y; } } }
// Update is called once per frame void Update() { if (player_lives_ <= 0) { Debug.Log("GAME OVER"); Application.Quit(); } TD_Tile ls_tile = map_.GetTile(ray_); if (is_edit_mode_) { if (Input.GetKeyDown(bind_place_destination_)) { if (ls_tile != null) { map_.SetDestination(ls_tile); } } else if (Input.GetKeyDown(bind_place_wall_)) { if (ls_tile != null) { map_.ToggleWall(ls_tile); } } if (Input.GetKeyDown(bind_place_spawn_)) { map_.ToggleSpawn(ls_tile); //ls_tile.Content = tile_factory_.Get(TileContentType.SPAWN); } if (Input.GetKeyDown(TD_Map_Manager.SAVE_KEY_)) { map_manager_.Save(); } } if (!round_has_started_) { if (Input.GetKeyDown(bind_place_tower_)) { if (money_ >= TOWER_COST_) { if (map_.ToggleTower(ls_tile)) { money_ -= TOWER_COST_; } } } else if (Input.GetKeyDown(bind_place_oil_)) { if (money_ >= OIL_COST_) { if (map_.ToggleOil(ls_tile)) { money_ -= OIL_COST_; } } } if (Input.GetKeyDown(KeyCode.Space) && !is_edit_mode_) { list_path_default_ = pathfinding_.Resolve(map_.spawn_points_[0].transform.position, EnemyType.DEFAULT); list_path_hovering_ = pathfinding_.Resolve(map_.spawn_points_[0].transform.position, EnemyType.HOVERING); //delay can be changed as difficulty increases InvokeRepeating("SpawnEnemy", 0.0f, 0.25f); round_has_started_ = true; } } if (round_has_started_ && list_enemies_.Count <= 0) { round_has_started_ = false; //this can also incrementally increase for difficulty enemies_to_spawn_++; Debug.Log(money_); } }