roguelike地图的随机生成算法

摘要:
如果你想自己设计一个Roguelike游戏,你需要随机生成地图。我在indienova上看到了一篇描述Roguelike算法的文章,然后统一实现了它。根据该算法的代码:usingSystem。收藏;使用System.Collections.Generic;使用UnityEngine;PublicenumTile{Floor,//Floor Wall/Wall}publicclasscreateMap:MonoBehavior{publicintrow=30;publicintcol=30;privateTile[,]mapArray;publicGameObjectwall,Floor,player;privateGameObjectmap;privateTransformmaps;privateintforTimes=0;//SmoothMapArray循环//使用thisfornializationvoid Start(){mapArray=newTile[row,col];maps=GameObject.FindGameObjectWithTag.transform;map=newGameObject() ; map.transform.SetParent;//CreateMap();GenerateMap();}//UpdateiscalledonceperframewoidUpdate(){if{Destroy;GenerateMap();}if{InitMap());}/如果{CreateMap();}}privateevoidInitMapArray(),则下一步{//使用<50%生成wall mapArray[i,j]=Random.Range<40?Tile.wall:Tile.Floor;}如果{newMapArray[i,j]=Tile.wall;}}则返回newMapArray;}//4-5规则//当前墙:周围有4面以上的墙保留为墙//当前地板:周围有5面以上的墙壁变为墙//循环4-5次privateTile[,]SmoothMapArray1(){Tile[、]newMapArray=newTile[row,col];intwallCount=0;对于{for{wallCount=CheckNeighborWalls;如果{newMapArray[i,j]=?

如果要想自己设计一个roguelike游戏,那么需要你有一个随机地图生成,我在indienova上看到一篇文章,描述了一个roguelike算法,然后自己用unity实现了一个下。

原文地址:随机生成 Tile Based 地图之——洞穴

原文有这个算法的各种讲解,还有动态的演示图,不理解算法原理的可以去看一下。

根据这个算法的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum Tile
{
    Floor,//地板
    Wall//墙
}

public class createMap : MonoBehaviour {

    public int row = 30;
    public int col = 30;
    private Tile[,] mapArray;
    public GameObject wall, floor,player;
    private GameObject map;
    private Transform maps;
    private int forTimes=0;//SmoothMapArray循环次数
    // Use this for initialization
    void Start () {
        mapArray = new Tile[row,col];
        maps = GameObject.FindGameObjectWithTag ("map").transform;
        map = new GameObject ();
        map.transform.SetParent (maps);
        //CreateMap ();

        GenerateMap ();
    }
    
    // Update is called once per frame
    void Update () {
        if (Input.GetKeyDown (KeyCode.Q)) {
            Destroy (map);
            GenerateMap ();
        }
        if (Input.GetKeyDown (KeyCode.W)) {
            InitMap ();
        }
        //下一步
        if (Input.GetKeyDown (KeyCode.E)) {
            CreateMap ();
        }
    }
    private void InitMapArray(){
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                //采用<50%生成墙
                mapArray[i,j] = Random.Range(0,100)<40?Tile.Wall:Tile.Floor;
                //边界置为墙
                if (i == 0 || j == 0 || i == row - 1 || j == col - 1) {
                    mapArray [i, j] = Tile.Wall;
                }
            }
        }
    }

    private Tile[,] SmoothMapArray0(){
        Tile[,] newMapArray = new Tile[row,col];
        int wallCount1 = 0,wallCount2 = 0;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                wallCount1 = CheckNeighborWalls (mapArray, i, j, 1);
                wallCount2 = CheckNeighborWalls (mapArray, i, j, 2);
                if (mapArray [i, j] == Tile.Wall) {
                    newMapArray [i, j] = (wallCount1 >= 4) ? Tile.Wall : Tile.Floor;
                } else {
                    newMapArray [i, j] = (wallCount1 >= 5 || wallCount2<=2) ? Tile.Wall : Tile.Floor;
                }
                if (i == 0 || i == row - 1 || j == 0 || j == col - 1) {
                    newMapArray [i, j] = Tile.Wall;
                }
            }
        }
        return newMapArray;
    }

    //4-5规则 
    //当前墙:周围超过4个保持为墙
    //当前地板:周围超过5个墙变为墙
    //循环4-5次
    private Tile[,] SmoothMapArray1(){
        Tile[,] newMapArray = new Tile[row,col];
        int wallCount = 0;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                wallCount = CheckNeighborWalls (mapArray, i, j, 1);
                if (mapArray [i, j] == Tile.Wall) {
                    newMapArray [i, j] = (wallCount >= 4) ? Tile.Wall : Tile.Floor;
                } else {
                    newMapArray [i, j] = (wallCount >= 5) ? Tile.Wall : Tile.Floor;
                }
                if (i == 0 || i == row - 1 || j == 0 || j == col - 1) {
                    newMapArray [i, j] = Tile.Wall;
                }
            }
        }
        return newMapArray;
    }

    //判断周围墙的数量
    private int CheckNeighborWalls(Tile[,] mapArray, int i,int j,int t){
        int count = 0;
        for (int k = i - t; k <= i + t; k++) {
            for (int l = j - t; l <= j + t; l++) {
                if (k >= 0 && k < row && l >= 0 && l < col) {
                    if (mapArray[k,l] == Tile.Wall) {
                        count++;
                    }
                }
            }
        }
        //去除本身是否为墙
        if (mapArray[i,j] == Tile.Wall) {
            count--;
        }
        return count;
    }

    private void InstanceMap (){
        bool setPlayer = true;
        map = new GameObject ();
        map.transform.SetParent (maps);
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (mapArray [i, j] == Tile.Floor) {
                    GameObject go = Instantiate (floor, new Vector3 (i, j, 1), Quaternion.identity) as GameObject;
                    go.transform.SetParent (map.transform);
                    //设置层级
                    go.layer = LayerMask.NameToLayer ("floor");

                    if (setPlayer) {
                        //设置角色
                        GameObject g_player = Instantiate (player, new Vector3 (i, j, 1), Quaternion.identity) as GameObject;
                        g_player.transform.SetParent (map.transform);
                        setPlayer = false;
                    }
                } else if (mapArray [i, j] == Tile.Wall) {
                    GameObject go = Instantiate (wall, new Vector3 (i, j, 1), Quaternion.identity) as GameObject;
                    go.transform.SetParent (map.transform);
                    go.layer = LayerMask.NameToLayer ("wall");
                }
            }
        }
    }


    private void InitMap (){
        forTimes = 0;
        Destroy (map);
        map = new GameObject ();
        map.transform.SetParent (maps);
        InitMapArray ();
        InstanceMap ();
    }

    private void CreateMap (){
        Destroy (map);
        map = new GameObject ();
        map.transform.SetParent (maps);
        if (forTimes < 7) {
            if (forTimes < 4) {
                mapArray = SmoothMapArray0 ();
            } else {
                mapArray = SmoothMapArray1 ();
            }
            forTimes++;
        }
        InstanceMap ();
    }

    private void GenerateMap (){
        forTimes = 0;
        map = new GameObject ();
        map.transform.SetParent (maps);
        InitMapArray ();
        while (forTimes < 7) {
            if (forTimes < 4) {
                mapArray = SmoothMapArray0 ();
            } else {
                mapArray = SmoothMapArray1 ();
            }
            forTimes++;
        }
        InstanceMap ();
    }

}
运行效果图:
最开始随机出来的地图,后面是逐步处理的效果:
roguelike地图的随机生成算法第1张roguelike地图的随机生成算法第2张
roguelike地图的随机生成算法第3张roguelike地图的随机生成算法第4张
roguelike地图的随机生成算法第5张roguelike地图的随机生成算法第6张
roguelike地图的随机生成算法第7张roguelike地图的随机生成算法第8张

免责声明:文章转载自《roguelike地图的随机生成算法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Linux网络编程笔记(修订版)R包ropls的偏最小二乘判别分析(PLS-DA)和正交偏最小二乘判别分析(OPLS-DA)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

ML基础06-数据不平衡问题

0、什么是数据不平衡问题 在机器学习的分类问题中,不同类别的样本数据量存在差异。在某些场景,比如网页点击率预估(网页点击率低),购物推荐(浏览产生的购买少),信用卡欺诈,网络攻击识别等,这种差异可能会较大。传统的学习算法,对不同类别的数据一视同仁地处理,会产生在多数类样本效果较好,但是在少数类样本上效果差的问题。而在上述的四种场景中,我们更关注的是少数类的...

YOLOv3和YOLOv4长篇核心综述(上)

YOLOv3和YOLOv4长篇核心综述(上) 对目标检测算法会经常使用和关注,比如Yolov3、Yolov4算法。 实际项目进行目标检测任务,比如人脸识别、多目标追踪、REID、客流统计等项目。因此目标检测是计算机视觉项目中非常重要的一部分。 从2018年Yolov3年提出的两年后,在原作者声名放弃更新Yolo算法后,俄罗斯的Alexey大神扛起了Yolo...

java.security KeyPairGenerator

KeyPairGenerator 类用于生成公钥和私钥对。密钥对生成器是使用 getInstance 工厂方法(返回一个给定类的实例的静态方法)构造的。 特定算法的密钥对生成器可以创建能够与此算法一起使用的公钥/私钥对。它还可以将特定于算法的参数与每个生成的密钥关联。 有两种生成密钥对的方式:与算法无关的方式和特定于算法的方式。两种方式的唯一区别在于对象的...

机器学习算法与Python实践之(七)逻辑回归(Logistic Regression)

http://blog.csdn.net/zouxy09/article/details/20319673 机器学习算法与Python实践之(七)逻辑回归(Logistic Regression) zouxy09@qq.com http://blog.csdn.net/zouxy09 机器学习算法与Python实践这个系列主要是参考《机器学习实战》这本书...

SFLA混合蛙跳算法

SFLA=SCE+PSO SCE: shuffled complex evolution algorithm(Duan 1992) = CRS(controlled radom search Price 1978)+Competive evolution(Holland 1975)+shuffling 一、前言 1.1  SCE(混合复杂进化方法)的一些重...

Logistic模型原理详解以及Python项目实现

此文转载自:https://blog.csdn.net/master_hunter/article/details/111158447#commentBox 目录 前言 一、Logistic回归模型 二、Logit模型 三、几率 四、Logistic模型 五、基于最优化方法的最佳回归系数确定 5.1梯度上升算法 5.1.1梯度 5.1.2使用梯度上升找到最...