Unity 2D随机地图

最近翻起以前下载的一些老的教学视频,于是决定重新看一遍,且每周所学做个记录,下面就直接开始。

这篇文章就讲讲教程里面的随机2D地图的实现原理,以及代码展示。

首先效果如下:

Unity 2D随机地图_第1张图片Unity 2D随机地图_第2张图片

右边是使用UntiyEditor所编辑的一个生成面板。左边是实际所生成的地图。

下面是实际源码展示


	public void CreateTiles(){
		var total = tiles.Length;
		for (int i = 0; i < total; i++)
		{
			var tile = new Tile_();
			tile.id = i;
			tiles[i] = tile;
		}
		FindNeighbors();
	}

	private void FindNeighbors()
	{
		for (int r = 0; r < rows; r++)
		{
			for (int c = 0; c < columns; c++)
			{
				var tile = tiles[columns*r+c];
				if (r0)
				{
					tile.AddNeighbor(Sides.Left,tiles[columns*r+c-1]);
				}
				if (r>0)
				{
					tile.AddNeighbor(Sides.Top,tiles[columns*(r-1)+c]);
				}
			}
		}
	}

首先要想实现2D地图,最简单的就是先能按照自己所设定的尺寸生成一个矩形的地图,且每一个单位是由一张sprite组成,这个应该不难。然后,按照面向对象的思维,每一个sprite身上都有一个tile的脚本,用来记录自身的信息,以及他周围的邻居,以上代码就是简单的生成了tile,然后下面对他上下左右的tile都进行了储存。

 

接下来就是如何把这个地图包围起来,始现效果如下

 

Unity 2D随机地图_第3张图片

首先大家的疑问都是这个地图是如何知道,他的边缘应该是如何进行填充的。这个时候就是用到了一个很简单的知识点,二进制。

	private void CalculateAutotileID(){
		var sideValues = new StringBuilder();
		foreach (Tile_ tile in neighbors)
		{
			sideValues.Append(tile == null ? "0":"1");
		}
		autotileID = Convert.ToInt32(sideValues.ToString(),2);
	}

在生成完地图的每个Tile以及记录了他们的邻居时候,根据他们邻居有或者没,用0和1来表示。那么就可以遍历出所有的情况,比如这个tile如果他周围都是空的只有他自己,那么他上下左右都是0,换成二进制就是 0,0,0,0,如果他周围都有方块,那么换成二进制就是1,1,1,1。这就是两种极端的情况。以此类推,我们根据每个tile储存的他自己周围的邻居,就可以得到每个tile当前处于什么状态,然后转换为10进制的数字,这就是上文的autotileID,并储存在他们每个tile自身的类身上,然后只要在合适的时机。根据这个ID加载对应的sprite,就能实现一个最简单的四四方方的地图。


接下来我们讲讲,当我们生成了一个矩型的地图之后我们如何让他周围被腐蚀掉,从而实现如下图的效果

Unity 2D随机地图_第4张图片

	public void CreateIsland(
		float erodePrecent,
		int erodeIterations,
		float treePercent,
		float hillPercent,
		float mountainPercent,
		float townsPercent,
		float monsterPercent,
		float lakePercent
	)
	{	


		DecorateTiles(landTiles,lakePercent,TileType.Empty);
		for (int i = 0; i < erodeIterations; i++)
		{
			DecorateTiles(coastTiles,erodePrecent,TileType.Empty);
		}



		var openTiles = landTiles;
		RandomizeTileArray(openTiles);
		if (openTiles!= null && openTiles[0] != null)
		{
			openTiles[0].autotileID = (int)TileType.Castle;
		}

		DecorateTiles(landTiles,treePercent,TileType.Tree);
		DecorateTiles(landTiles,hillPercent,TileType.Hills);
		DecorateTiles(landTiles,mountainPercent,TileType.Mountain);
		DecorateTiles(landTiles,townsPercent,TileType.Towns);
		DecorateTiles(landTiles,monsterPercent,TileType.Monster);
	}

	public void DecorateTiles(Tile_[] tiles,float percent,TileType type)
	{	
		var total = Mathf.FloorToInt(tiles.Length*percent);
		RandomizeTileArray(tiles);
		for (int i = 0; i < total; i++)
		{	
			var tile = tiles[i];
			if(type == TileType.Empty)
			{
				tile.ClearNeighbors();
			}
			tile.autotileID = (int)type;
		}
	}

上面的代码,创建了一个简单的方法,DecorateTiles,传入指定的tile数组,然后根据百分比,把他们换成制定的tile类型。

腐蚀的方法很简单,就在第一个方法的for循环里面,他是找到了所有autotileID小于15的方块,小于15就代表了他们都是边缘tile,然后对他们随机进行置空,然后根据unityEditor所填下的值。决定执行几次置空循环。

里面的其他代码也很容易理解,就是获取了数值为15的autotileID的方块,数值为15就是都为里面填充的方块,只要根据百分比转换成你需要的树,山,之类的,就能实现上图最简单的效果。

 

总结一下,这个简单的2D随机地图,就是通过二进制获得了所有地图的关系信息,用这个关系信息进行数据的处理,填充,置空。来实现出如上图的效果。

你可能感兴趣的:(Unity 2D随机地图)