예제 #1
0
    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);
    }
예제 #2
0
    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);
    }
예제 #3
0
    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);
    }
예제 #4
0
 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);
     }
 }
예제 #5
0
 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);
     }
 }
예제 #6
0
 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;
 }
예제 #7
0
    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);
    }
예제 #8
0
    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);
    }
예제 #9
0
    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);
    }
예제 #10
0
    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());
    }
예제 #11
0
    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;
            }
        }
    }
예제 #12
0
    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);
    }
예제 #13
0
    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;
            }
        }
    }
예제 #14
0
    // 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_);
        }
    }