04. 生成地图上的房间

最终目标

每一列上面的关卡之间有间距,并且 x 坐标有左右偏移,最后一个房间的位置是固定的

实现方法

我们现在已经知道屏幕的宽度screenWidth,也知道了屏幕的高度screenHeight,同时还知道一共有多少列mapConfig.roomBlueprints.Count

那么可以算出

每一列的宽度columnWidth = screenWidth / mapConfig.roomBlueprints.Count

每列中,会有amount = Random.Range(min, max + 1)个地点

一列中每行的高度roomGapY = screenHeight / (amount + 1)

那么每一列的上面每个塔的坐标应该是(-screenWidth / 2 + border + columnWidth * colIndex, screenHeight / 2 - roomGapY * (rowIndex + 1))

知道了塔的 X 坐标是-screenWidth / 2 + border + columnWidth * colIndex,那么我可以让它稍微左右移动一点,显得更随机一些newPosition.x = generatePoint.x + Random.Range(-border / 2, border)

最后一列是 Boss 房间,需要固定 X 轴坐标newPosition.x = screenWidth / 2 - border * 2;

最终代码

    
    private List<Room> rooms = new List<Room>();

    private void Awake()
    {
        // 获取屏幕的高度和宽度
        screenHeight = Camera.main.orthographicSize * 2;
        screenWidth = screenHeight * Camera.main.aspect;

        // 获取一列的宽度,为了防止最后一列显示在屏幕外面,所以分母加1,现在看来还行,就不用加了
        columnWidth = screenWidth / mapConfig.roomBlueprints.Count;
    }

    public void CreateMap()
    {
        for (int column = 0; column < mapConfig.roomBlueprints.Count; column++)
        {
            var blueprint = mapConfig.roomBlueprints[column];

            var amount = Random.Range(blueprint.min, blueprint.max + 1);

            var startHeight = screenHeight / 2 - screenHeight / (amount + 1);

            generatePoint = new Vector3(-screenWidth / 2 + border + columnWidth * column, startHeight, 0);

            var newPosition = generatePoint;
            
            
            var roomGapY = screenHeight / (amount + 1);

            // 循环当前列的所有房间数量生成房间
            for (int i = 0; i < amount; i++)
            {
                if (column == mapConfig.roomBlueprints.Count - 1)
                {
                    // 判断为最后一列,Boss 房间
                    newPosition.x = screenWidth / 2 - border * 2;
                }
                else if (column != 0)
                {
                    newPosition.x = generatePoint.x + Random.Range(-border / 2, border);
                }                 

                newPosition.y = startHeight - roomGapY * i;
                var room = Instantiate(roomPrefab, newPosition, Quaternion.identity, transform);
                rooms.Add(room);
            }
        }
    }

使生成更加便利

每次运行才生成地图,效率太低了。我们可以新增一个ReGenerateRoom方法,并给它添加ContextMenu注解

    // 重新生成地图
    [ContextMenu("ReGenerateRoom")]
    public void ReGenerateRoom()
    {
        foreach (var room in rooms)
        {
            Destroy(room.gameObject);
        }

        rooms.Clear();

        CreateMap();
    }

使用的位置是在 MapGenerator 组件上右键,然后单击 ReGenerateRoom

这样就能在不重启的前提下,再次快速生成地图了

项目相关代码

代码仓库:https://gitee.com/nbda1121440/DreamOfTheKingdom.git

标签:20240301_2218

posted @   hellozjf  阅读(115)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示