Getting started creating games from scratch - random generation of minerals

Since the principle of mineral generation is the same as that of map generation, corresponding bricks are generated based on random noise images, so the function that generates the noise map needs to be reconstructed, and then each mineral generates a unique texture to refer to the generation location. .


  • Reconstruct the noise function

Three parameters have been added to ensure that each brick can generate its own unique image. Since my seed value range is

seed = Random.Range(10000, 20000)

Therefore, the parameters of Mathf.PerlinNoise are divided by 1000 in order to increase the value range of frequency. When debugging in the Unity page, the parameters can be modified more comprehensively and the effect diagram can be more obvious.

In addition, the generated pixel color has been modified and optimized to only black and white images, so that the effect can be seen more clearly.

    public void GenerateNoiseTexture(float frequent, float limit ,Texture2D noiseTexture)
    //frequent 噪音频率,越小噪音越不明显,越大越明显
    //limit    临界值,大于临界值则为白,小于临界值为黑
    //noiseTexture    最终生成的噪音图像
    {
        for (int x = 0; x < noiseTexture.width; x++)
        {
            for (int y = 0; y < noiseTexture.height; y++)
            {
                float v = Mathf.PerlinNoise((x + seed)* frequent/1000, (y + seed ) * frequent/1000);
                if (v > limit)
                    noiseTexture.SetPixel(x, y, Color.white);
                else noiseTexture.SetPixel(x, y, Color.black);
                //SetPixel函数根据像素位置,只有当噪音值大于阈值才会生成对应x,y坐标下的像素颜色为白色像素,否则生成黑色像素
            }
        }
        noiseTexture.Apply();  //将上面点生成对应的二位噪音图保存
    }

  • Generate noise maps of minerals and maps

The following parameters have been added, and the corresponding functions have also been annotated.

public class Sandbox_seed : MonoBehaviour
{
    [Header("世界参数")]
    public Texture2D mapNoiseTexture;  //地图噪音材质图
    public float caveFreq = 50;        //山洞参数,数值越大洞越多
    public float caveSize = 0.25f;

    [Header("矿物参数")]
    public Texture2D copperNoiseTexture;  //铜矿噪音材质图
    public Texture2D goldNoiseTexture;    //金矿噪音材质图

    public int copperFreq = 100;          //铜矿噪音参数
    public int goldFreq = 200;            //金矿噪音参数

    public float copperSize = 0.3f;       //铜矿生成概率
    public float goldSize = 0.25f;        //金矿生成概率
}

 In order to facilitate parameter debugging, the following function OnValidate() that comes with the system has been added. The function of this function is to immediately update the corresponding object when the parameters are modified on the Unity page. In this code, it is to make it easier to debug the noise parameters. Note that the second parameter of the mineral material is different from the world map material.

public class Sandbox_seed : MonoBehaviour
{
    public void OnValidate()
    {
        if (mapNoiseTexture == null)
        //如果一开始的mapNoiseTexture为空,则重新生成一个。
        //因为原本mapNoiseTexture是只有在开始运行才会生成的,如果不加这句话就会报错
        {
            mapNoiseTexture = new Texture2D(worldwidth, worldheight);
            copperNoiseTexture = new Texture2D(worldwidth, worldheight);
            goldNoiseTexture = new Texture2D(worldwidth, worldheight);
        }
        GenerateNoiseTexture(caveFreq, caveSize, mapNoiseTexture);
        //注意这里的是 1 减去矿物尺寸,临界值为1时全部为白即全图生成对应矿物,而0为黑即不生成矿物
        //这点是和地图的洞穴参数相反。
        GenerateNoiseTexture(copperFreq, 1f - copperSize, copperNoiseTexture);
        GenerateNoiseTexture(goldFreq, 1f - goldSize, goldNoiseTexture);
    }
}

This is the noise texture map of the world map. The white color is the location of the floor tiles.

This is the noise texture map of minerals. The white ones are the positions of minerals.


  • Add mineral floor tiles

Just like the previous stones, grass, and soil, manually create the floor tile class in Unity and add a name and texture.

Then add these two tiles in the class of the floor tile set

 At the same time, drag the floor tile class into the class of the generated floor tile set.

 In this way, the corresponding bricks can be created when generating the map.


  • Generate map

 Due to the addition of minerals, the order and logic of generating bricks need to be adjusted.

Note that since our judgment logic for generating bricks is

1. This position is less than the height of the surface [y < surfaceNoise]

2. This position is white in the world noise material [mapNoiseTexture.GetPixel(x, y).r == 1]

Bricks can only be generated if these two conditions are met. 【PlaceTile(tileClass, x, y);】

According to the order of judgment, the minerals here will be generated on the surface, and copper ore will be generated first. And no trees will grow on copper mines.

    public void GenerateTexture()
    {
         /* 前面代码不动 */

                TileClass tileClass;       //创建局部变量用来进行判断该地砖应该是什么类型

                //判断该生成的是什么地貌
                if(y < surfaceNoise && mapNoiseTexture.GetPixel(x, y).r == 1)
                { 
                    if (copperNoiseTexture.GetPixel(x,y).r == 1)     //判断在铜矿材质中这个位置是否为白色,是白色就生成铜矿,不是则进行下面的判断
                    {
                        tileClass = tileAtlas.copper;
                    }
                    else if (goldNoiseTexture.GetPixel(x, y).r == 1) //判断在铜矿材质中这个位置是否为白色,是白色就生成金矿,不是则进行下面的判断
                    {
                        tileClass = tileAtlas.gold;
                    }
                    else if (y < surfaceNoise - dirtNoise) tileClass = tileAtlas.stone;          //地表高度减去泥土厚度的为岩石

                    else if (y <= surfaceNoise - 1) tileClass = GetTileClass(tileAtlas.dirts);   //距离地表1且不是岩石的为泥土
                    
                    else tileClass = GetTileClass(tileAtlas.grasses);                            //剩下的,即地表高度等于1的为草地

                    PlaceTile(tileClass, x, y);       //在(x,y)坐标生成砖块

                    if (tileClass.tileName.Contains("Grass") && worldTileVectorList.Contains(new Vector2(x, y)))    //如果这个砖块是草地砖块且生成成功,则进行判断是否生成树
                    {
                        float treeRandom = Random.Range(0f, 1f);
                        if (treeChance >= treeRandom)            //当参数大于随机值,则生成树
                        {
                            PlaceTree(x, y);
                        }
                    }
                }
            }
        }
    }

add another point:

The RGBA value of Color.white is as follows. It will also be displayed when the mouse moves to this parameter.

The RGBA values ​​of Color.black are as follows


  • final effect 

 Add a function to generate materials and a function to generate map tiles in the Start() function

    void Start()
    {
        seed = Random.Range(10000, 20000);

        //先声明噪音图的材质类
        mapNoiseTexture = new Texture2D(worldwidth, worldheight);
        copperNoiseTexture = new Texture2D(worldwidth, worldheight);
        goldNoiseTexture = new Texture2D(worldwidth, worldheight);

        //再生成材质
        GenerateNoiseTexture(caveFreq, caveSize, mapNoiseTexture);
        GenerateNoiseTexture(copperFreq, 1f - copperSize, copperNoiseTexture);
        GenerateNoiseTexture(goldFreq, 1f- goldSize, goldNoiseTexture);

        GenerateTexture();
    }

The final generated map effect is as follows. The number of minerals generated (copperSize/goldSize) can be adjusted by yourself.

 

Guess you like

Origin blog.csdn.net/dwe147/article/details/130646608