zoukankan      html  css  js  c++  java
  • roguelike地图的随机生成算法

    如果要想自己设计一个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 ();
        }
    
    }
    运行效果图:
    最开始随机出来的地图,后面是逐步处理的效果:
    
    
    
    
  • 相关阅读:
    Spring Boot入门
    Spring MVC文件上传和下载
    Spring MVC异常处理
    SpringMVC
    linux(2)
    linux(1)
    白盒测试
    LoadRunner(8)
    LoadRunner(7)
    LoadRunner(6)
  • 原文地址:https://www.cnblogs.com/sufferingStriver/p/8834299.html
Copyright © 2011-2022 走看看