2014-07-26 5 views
2

타일을 사용하여 무작위로 도시를 만들려고하는데 배열을 만들고 도시 가장자리를 설정하고 교회 나 공장과 같은 임의의 건물을 배치하고 타일을 배치 할 수 있습니다 설정된 영역 내에서 무작위로 회전합니다.랜덤 도시 거리 생성 타일 사용

하지만 내가 필요한 것은 올바른 타일을 선택하고 올바른 방향으로 회전하여 어떤 방식 으로든 도달 할 수없는 영역으로 끝나도록 거리의 상호 연결된 미로를 만드는 일종의 알고리즘 또는 루틴입니다. 내가의 톤을 발견했다 직선 도로 t 접합 교차로 코너 왼쪽 코너 바로 사각/원형/안뜰

(예 : 교회 나 공장 등) 기능 타일 - 내가있는 한

타일 던전을 기반으로 한 예제이지만 고정 된 타일을 사용하고 설정된 영역에서 일치/회전하는 선을 따르는 것은 10 타일 x 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