2014-07-26 44 views
2

我想建立一個由瓷磚製成的隨機城市,到目前爲止,我可以建立一個數組,設置城市邊緣,放置一個隨機建築,如教堂或工廠,並可以放置瓷磚在設定區域內隨機旋轉。隨機城市街道一代使用瓷磚

但我需要的是某種算法或例程,通過選擇正確的瓷磚並以正確的方式旋轉以創建街道的互連迷宮,從而不會以某種方式無法達到的區域。 功能區塊(如教堂或工廠) 直路 丁字路口 十字路口 左角 右角 平方米/迴旋/庭院

我發現噸 -

我已經是瓷磚基於地下城的例子,但沒有任何沿着使用固定磚和匹配/旋轉設置區域的線說10個瓷磚×10個瓷磚。

任何腳本提示將非常讚賞,因爲我轉圈圈使窘況複雜的循環功能苫仍然不工作的我至今

碼 -

public GameObject playerPrefab; 
public GameObject cullGroup; 
public GameObject cullPrefab; 

//tile objects 
public List<GameObject> _grid = new List<GameObject>();   //general buildings 
public List<GameObject> _industrial = new List<GameObject>(); //industrial 
public List<GameObject> _feature = new List<GameObject>();  //city feature 
public List<GameObject> _largeSpecial = new List<GameObject>(); //large special building 
public List<GameObject> _smallSpecial = new List<GameObject>(); //large special building 
public List<GameObject> _docks = new List<GameObject>();  //docks 
public List<GameObject> _roads = new List<GameObject>();  //outgoing roads 
public List<GameObject> _edge = new List<GameObject>();   //city edge 

public Vector2 citySize = new Vector2(10,10);  //how many tiles in total 
private int[] tileRoatation = new int[5] {0,90,180,270,0}; 
private int[,,] _cityMap; 
private int mapType = 0; 

//ingress vars 
public int[,] roadIngress; 

//feature vars 
private int _tmpFeature; 
private Vector2 _tmpPlacement; 

//special vars 
private int _tmpFeature1; 
private Vector2 _tmpPlacement1; 

//docks vars 
private Vector2 _tmpDock; 
private string _strDock; 
private float _xAdjustment; 
private float _zAdjustment; 

//industrial vars 
private Vector2 _indSector; 
private int _indTotal = 0; 

// Use this for initialization 
void Start() 
{ 
    _cityMap = new int[(int)citySize.x, (int)citySize.y, 2]; 

    CreateMap(); 
} 

// Update is called once per frame 
void Update() 
{ 

} 

void CreateMap() 
{ 
    //calc roads into city 
    RoadIngress(); 

    //calc feature 
    Features(); 

    //calculate tile adjustment from center 
    _xAdjustment = (_grid[0].transform.localScale.x * (citySize.x/2) - (_grid[0].transform.localScale.x)/2); 
    _zAdjustment = (_grid[0].transform.localScale.z * (citySize.y/2) - (_grid[0].transform.localScale.x)/2); 

    //place tiles 
    for(int z = 0; z < citySize.y; z++) 
    { 
     for(int x = 0; x < citySize.x; x++) 
     { 
      //instantiate tile 
      int tmpRot = tileRoatation[Random.Range(0,5)]; 
      GameObject go = Instantiate(_grid[Random.Range(0, _grid.Count-1)], 
             new Vector3(
         (x * _grid[0].transform.localScale.x) - _xAdjustment, 
         0 , 
         (z * _grid[0].transform.localScale.z) - _zAdjustment), 
         Quaternion.Euler(0,tmpRot, 0) 
       ) as GameObject; 

      _cityMap[x ,z ,1 ] = 1;; 
      _cityMap[x ,z ,0 ] = tmpRot;; 
      go.name = x +"/"+z; 
      go.transform.parent = this.transform; 

      //instantiate culling areas 
      /* 
      GameObject go2 = Instantiate(cullPrefab, 
             new Vector3(
       (x * _grid[0].transform.localScale.x) - _xAdjustment, 
       0 , 
       (z * _grid[0].transform.localScale.z) - _zAdjustment), 
             Quaternion.Euler(0,0, 0) 
             ) as GameObject; 
      go2.name = x +"/"+z; 
      go2.transform.parent = cullGroup.transform; 
      go2.transform.localScale = new Vector3(51, 20, 51); 
      */ 

      //set map edges 
      if(x == 0 || z == 0 || x == citySize.x-1 || z == citySize.y-1) 
      { 
       //does map have beach 
       if(mapType == 1 && z == 0) 
       { 
        go.GetComponent<MeshRenderer>().material.color = Color.blue; 
       }else if(roadIngress[x,z] == 1){ 
        //set exit roads 
         go.SetActive(false); 
         GameObject rp = Instantiate(_roads[0], new Vector3(go.transform.position.x, 0 ,go.transform.position.z), Quaternion.Euler(0, 0, 0)) as GameObject; 
         rp.name = go.name; 
         rp.transform.parent = this.transform; 
         //go.name = "disabled"; 

         //extend road 
       }else{ 
        //go.GetComponent<MeshRenderer>().material.color = Color.green; 
        int tmpRot1 = tileRoatation[Random.Range(0,5)]; 
        go.SetActive(false); 
        GameObject ep = Instantiate(_edge[Random.Range(0, _edge.Count-1)], new Vector3(go.transform.position.x, 0 ,go.transform.position.z), Quaternion.Euler(0, tmpRot, 0)) as GameObject; 
        ep.name = go.name; 
        ep.transform.parent = this.transform; 

        go.name = "disabled"; 
       } 

      } 
     } 
    } 

    Debug.Log((citySize.x * citySize.y) * 0.1f); 
    Industrial(); 
    Industrial(); 
    Debug.Log(_indTotal); 
    if(citySize.x <((citySize.x * citySize.y) * 0.2f)) 
     Industrial(); 

    PlaceFeature(); 
    PlaceLargeSpecial(); 

    //docks 
    if(mapType == 1) 
    { 
     //go.GetComponent<MeshRenderer>().material.color = Color.red; 
     _tmpDock = new Vector2(Random.Range(1,citySize.y-1),0); 
     //_strDock = _tmpDock.x +"/"+_tmpDock.y; 

    } 

    PlaceDocks(); 

    // spawn player 
    Instantiate(playerPrefab, new Vector3(0,2,0),Quaternion.identity); 
} 


//set roads leaving city 
void RoadIngress() 
{ 
    //set roads leaving city 
    roadIngress = new int[(int)citySize.x, (int)citySize.y]; 
    roadIngress[(int)Random.Range(1,citySize.x-1), 0] = 1;     //east road or dock 
    roadIngress[0, (int)Random.Range(1,citySize.y-1)] = 1;     //south road 
    roadIngress[(int)Random.Range(1,citySize.x-1), (int)citySize.y-1] = 1; //west road 
    roadIngress[(int)citySize.x-1, (int)Random.Range(1,citySize.y-1)] = 1; //north road 
} 

// choose main feature 
void Features() 
{ 
    //choose main feature and placement 
    _tmpFeature = Random.Range(0,4);// 5x feature tiles 
    _tmpPlacement = new Vector2((int)Random.Range(2,citySize.x-2),(int)Random.Range(2,citySize.y-2)); 

    //choose special large building and placement 
    _tmpFeature1 = Random.Range(0,4);// 5x feature tiles 
    _tmpPlacement1 = new Vector2((int)Random.Range(2,citySize.x-2),(int)Random.Range(2,citySize.y-2)); 
    if(_tmpPlacement1 == _tmpPlacement) 
    { 
     _tmpPlacement1.x = _tmpPlacement1.x + 4; 
     if(_tmpPlacement1.x > citySize.x-2) 
      _tmpPlacement1.x -= citySize.x; 
     _tmpPlacement1.y = _tmpPlacement1.y + 4; 
     if(_tmpPlacement1.y > citySize.y-2) 
      _tmpPlacement1.y -= citySize.y; 
    } 
} 

//place feature 
void PlaceFeature() 
{ 

    int tmpRot1 = tileRoatation[Random.Range(0,5)]; 
    GameObject go1 = Instantiate(_feature[Random.Range(0, _feature.Count-1)], 
           new Vector3((_tmpPlacement.x * _grid[0].transform.localScale.x - (_grid[0].transform.localScale.x *.5f) - _xAdjustment), 
       0, 
       (_tmpPlacement.y * _grid[0].transform.localScale.z + (_grid[0].transform.localScale.z*.5f) - _zAdjustment)), 
           Quaternion.Euler(0,tmpRot1, 0)) as GameObject; 

    //clear feature area 
    GameObject tp = GameObject.Find(_tmpPlacement.x + "/" + _tmpPlacement.y); 
    tp.SetActive(false); 
    tp.name = "disabled"; 
    tp = GameObject.Find(_tmpPlacement.x + "/" + (_tmpPlacement.y+1)); 
    tp.SetActive(false); 
    tp.name = "disabled"; 
    tp = GameObject.Find(_tmpPlacement.x-1 + "/" + _tmpPlacement.y); 
    tp.SetActive(false); 
    tp.name = "disabled"; 
    tp = GameObject.Find(_tmpPlacement.x-1 + "/" + (_tmpPlacement.y+1)); 
    tp.SetActive(false); 
    tp.name = "disabled"; 
} 

//place large special 
void PlaceLargeSpecial() 
{ 
    //check distance between feature and large special 
    int dist = (int)Vector2.Distance(_tmpPlacement, _tmpPlacement1); 

    //if to close move away 
    if((int)Vector2.Distance(_tmpPlacement, _tmpPlacement1)<3) 
    { 
     _tmpPlacement1.x = _tmpPlacement1.x+3; 
     if(_tmpPlacement1.x > citySize.x-2) 
      _tmpPlacement1.x = 3; 
     _tmpPlacement1.y = _tmpPlacement1.y+3; 
     if(_tmpPlacement1.y > citySize.y-2) 
      _tmpPlacement1.y = 3; 
    } 

    //Debug.Log(dist); 
    int tmpRot2 = tileRoatation[Random.Range(0,5)]; 
    GameObject go2 = Instantiate(_largeSpecial[Random.Range(0, _largeSpecial.Count-1)], 
           new Vector3((_tmpPlacement1.x * _grid[0].transform.localScale.x - (_grid[0].transform.localScale.x *.5f) - _xAdjustment), 
       0, 
       (_tmpPlacement1.y * _grid[0].transform.localScale.z + (_grid[0].transform.localScale.z*.5f)) - _zAdjustment), 
           Quaternion.Euler(0,tmpRot2, 0)) as GameObject; 

    //clear large special area 
    GameObject tp = GameObject.Find(_tmpPlacement1.x + "/" + _tmpPlacement1.y); 
    tp.SetActive(false); 
    tp.name = "disabled"; 
    tp = GameObject.Find(_tmpPlacement1.x + "/" + (_tmpPlacement1.y+1)); 
    tp.SetActive(false); 
    tp.name = "disabled"; 
    tp = GameObject.Find(_tmpPlacement1.x-1 + "/" + _tmpPlacement1.y); 
    tp.SetActive(false); 
    tp.name = "disabled"; 
    tp = GameObject.Find(_tmpPlacement1.x-1 + "/" + (_tmpPlacement1.y+1)); 
    tp.SetActive(false); 
    tp.name = "disabled"; 

} 

//place docks 
void PlaceDocks() 
{ 
    if(mapType == 1) 
    { 
     GameObject go3 = Instantiate(_docks[Random.Range(0, _docks.Count-1)], 
            new Vector3((_tmpDock.x * _grid[0].transform.localScale.x - (_grid[0].transform.localScale.x) - _xAdjustment), 
        0, 
        (_tmpDock.y * _grid[0].transform.localScale.z) - _zAdjustment), 
            Quaternion.Euler(0,0, 0)) as GameObject; 

     //clear dock area 
     /* 
     string[] tmp = _strDock.Split("/"[0]); 
     int t1 = int.Parse(tmp[0]); 
     for(int a=0; a<3; a++) 
     { 
      GameObject.Find(t1-a + "/" + 0).SetActive(false); 
     } 
     for(int b=0; b<3; b++) 
     { 
      GameObject.Find(t1-b + "/" + 1).SetActive(false); 
     } 
     */ 
    } 
} 

//set out industrial area 
void Industrial() 
{ 
    //pick random spot industrial area 
    _indSector = new Vector2((int)Random.Range(2,citySize.x-2),(int)Random.Range(2,citySize.y-2)); 

    int indSizeX = Random.Range(2,5); 
    int indSizeY = Random.Range(2,4); 
    _indTotal += (indSizeX*indSizeY); 

    //create area 
    for(int y = (int)_indSector.y; y < (int)_indSector.y+indSizeY; y++) 
    { 
     for(int x = (int)_indSector.x; x < (int)_indSector.x+indSizeX; x++) 
     { 
      //GameObject.Find(x + "/" + y).GetComponent<MeshRenderer>().material.color = Color.magenta; 
      GameObject tp = GameObject.Find(x + "/" + y); 
      //Debug.Log(x + "/" + y); 
      GameObject go4 = Instantiate(_industrial[Random.Range(0, _industrial.Count-1)], 
              new Vector3(tp.transform.position.x, 0, tp.transform.position.z), Quaternion.Euler(0,0, 0)) as GameObject; 
      tp.SetActive(false); 
      tp.name = "disabled"; 
      go4.name = x +"/"+y; 
      go4.transform.parent = this.transform; 
     } 
    } 
} 

+0

見例如:http://gamedev.stackexchange.com/questions/59314/procedural-river-or-road -generation-for-infinite-terrain – LearnCocos2D

+0

這篇文章涵蓋了地形生成的大部分*基礎*:http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/ – LearnCocos2D

+0

謝謝但我對地形生成不感興趣,因爲我有這個覆蓋,它的城市由我感興趣的瓷磚製成 – Hybrid1969

回答

0

莫非你不使用數組(如果需要的話可以使用多維數組)並填充它的位置,然後使用「隨機」類從數組中提取這些位置?

像...

s 
Random rnd = new Random(); 
int i; 
i = rnd.next(1,5); 

Random rnd = new Random(); 
int i; 
i = rnd.next(1,5); 

int Positions[] = new Positions[5] {100, 200, 300, 400, 500}; 
Tilepos1 = Positions[i]; 
Tilepos2 = Positions[i]; 
Tilepos3 = Positions[i]; 
Tilepos4 = Positions[i]; 
Tilepos5 = Positions[i]; 


//you would have to make up your own Tileposition and figure out how to implement it into your system 

//then make sure that the Tilepositions (Tilepos) don´t land on the same place 

if (Tilepos1 == Tilepos2) 
    { 
    Tilepos1 = Positions[i]; 
    } 
if (Tilepos1 == Tilepos3) 
    { 
    Tilepos1 = Positions[i]; 
    } 
if (Tilepos1 == Tilepos4) 
    { 
    Tilepos1 = Positions[i]; 
    } 
if (Tilepos1 == Tilepos5) 
    { 
    Tilepos1 = Positions[i]; 
    } 


//then just repeat this process with Tilepos 2, 3, 4,`int i; 
i = rnd.next(1,5); 

int Positions[] = new Positions[5] {100, 200, 300, 400, 500}; 
Tilepos1 = Positions[i]; 
Tilepos2 = Positions[i]; 
Tilepos3 = Positions[i]; 
Tilepos4 = Positions[i]; 
Tilepos5 = Positions[i]; 


//you would have to make up your own Tileposition and figure out how to implement it into your system 

//then make sure that the Tilepositions (Tilepos) don´t land on the same place 

if (Tilepos1 == Tilepos2) 
    { 
    Tilepos1 = Positions[i]; 
    } 
if (Tilepos1 == Tilepos3) 
    { 
    Tilepos1 = Positions[i]; 
    } 
if (Tilepos1 == Tilepos4) 
    { 
    Tilepos1 = Positions[i]; 
    } 
if (Tilepos1 == Tilepos5) 
    { 
    Tilepos1 = Positions[i]; 
    } 


//then just repeat this process with Tilepos 2, 3, 4, 5 

但如果瓷磚的平方這隻會工作,否則你只是香料的東西與陣列一點。

我希望它幫助一點,給你什麼就做一個基本的想法:)

+0

對不起,我顯然沒有讓自己清楚。 – Hybrid1969

+0

所以我有一個數組說10x10,然後我遍歷數組設置瓷磚類型和它的旋轉。所以我試圖找到的方法是通過改變或旋轉它們的方塊來改變或旋轉它們,所以我最終得到通過改變或旋轉預定義的道路瓦片來創建道路網絡的路徑 – Hybrid1969

+0

希望我本來可以得到更多的幫助但我還沒有擅長編程,儘管我不得不承認,這是一些令人印象深刻的代碼 – Rawmouse

相關問題