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 ();
        }
    
    }
    运行效果图:
    最开始随机出来的地图,后面是逐步处理的效果:
    
    
    
    
  • 相关阅读:
    POJ 3114 Tarjan+Dijkstra
    278. First Bad Version
    209. Minimum Size Subarray Sum
    154. Find Minimum in Rotated Sorted Array II
    153. Find Minimum in Rotated Sorted Array
    710. Random Pick with Blacklist
    767. Reorganize String
    524. Longest Word in Dictionary through Deleting
    349. Intersection of Two Arrays
    350. Intersection of Two Arrays II
  • 原文地址:https://www.cnblogs.com/sufferingStriver/p/8834299.html
Copyright © 2011-2022 走看看