gpt4 book ai didi

c# - 使用瓷砖随机生成城市街道

转载 作者:太空宇宙 更新时间:2023-11-03 15:53:05 25 4
gpt4 key购买 nike

关闭。这个问题需要更多focused .它目前不接受答案。












想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .

7年前关闭。




Improve this question




我正在尝试构建一个由瓷砖制成的随机城市,到目前为止我可以构建一个阵列,设置城市边缘,放置一个随机建筑物,例如教堂或工厂,并且可以在设置区域内放置具有随机旋转的瓷砖。

但我需要的是某种算法或例程,通过选择正确的瓷砖并以正确的方式旋转它来创建一个相互连接的街道迷宫,以免最终出现无法以某种方式到达的区域。

我拥有的瓷砖是-
特色瓷砖(如教堂或工厂)
直路
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;
}
}
}

最佳答案

你能不能不使用数组(或多维数组,如果需要)并用位置填充它然后使用“随机”类从数组中提取这些位置?

喜欢...

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

但这只有在瓷砖是方形的情况下才有效,否则你可以用阵列来调味。

我希望它对您有所帮助,并让您对该怎么做有一个基本的了解:)

关于c# - 使用瓷砖随机生成城市街道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24972880/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com