Unity模拟<暗黑地牢>随机生成小地图

29 篇文章 3 订阅
13 篇文章 0 订阅

模拟<暗黑地牢>的随机地图

先上图, 绿色是起点, 蓝色是道路, 粉色是事件, 红色是战斗房间, 黄色是奖励房间
在这里插入图片描述


用的是2维数组, 思路很简单:
1个点, 作为房间, 上下左右随机选一个方向, 生成第2个房间, 连接这2个房间, 即是路
拿这2个房间, 随机选一个房间, 随机选一个方向, 生成第3个房间, 并生成路
依次生成很多房间和路…

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

public class Mgr : MonoBehaviour
{
    public static Mgr instance;

    [SerializeField]
    private Transform parentBlocks;

    public List<Vector2> vector2Map;
    private void Start()
    {
        instance = this;

        vector2Map = new List<Vector2>();

        CreateMap(Json.ReadJson());
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            int numRooms = Random.Range(5, 8);
            int numBattleRooms = Random.Range(1, 4);
            int numBattleRoads = Random.Range(2, 10);
            Debug.Log(string.Format("房间数{0},战斗房间数{1},战斗道路数{2}", numRooms, numBattleRooms, numBattleRoads));
            RandomMap.CreatMap(numRooms, numBattleRooms, numBattleRoads);
            SceneManager.LoadScene(0);
        }
    }

    private void CreateMap(MapData mapData)
    {
        GameObject blockPrefab = Resources.Load("Block") as GameObject;

        for (int i = 0; i < mapData.data.Count; i++)
        {
            for (int j = 0; j < mapData.data[i].Count; j++)
            {
                int mapNum = mapData.data[i][j];

                //5表示空白格, 什么都没有
                if (mapNum == 5)
                {
                    continue;
                }
                //可被行走的格子
                else
                {
                    vector2Map.Add(new Vector2(j, i));
                }

                GameObject block = Instantiate(blockPrefab, new Vector3(j, i), Quaternion.identity, parentBlocks);
                SpriteRenderer sprite = block.GetComponent<SpriteRenderer>();

                switch (mapNum)
                {
                    case 0:
                        sprite.color = Color.green;
                        CreatePlayer(new Vector2(j, i));
                        break;
                    case 1:
                        sprite.color = Color.blue;
                        break;
                    case 2:
                        sprite.color = Color.magenta;
                        break;
                    case 3:
                        sprite.color = Color.yellow;
                        break;
                    case 4:
                        sprite.color = Color.red;
                        break;
                }

            }
        }
        parentBlocks.gameObject.AddComponent<EdgeCollider2D>();
    }

    private void CreatePlayer(Vector2 startPos)
    {
        GameObject playerPrefab = Resources.Load("Player") as GameObject;
        Instantiate(playerPrefab, startPos, Quaternion.identity);
    }

}
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;

public class RandomMap
{
    //道路段数
    static int roadLength = 7;

    static List<Vector2> rooms = new List<Vector2>();
    static List<Vector2> roads = new List<Vector2>();

    static float columnCount;
    static float rowCount;

    public static void CreatMap(int numRoom, int numBattleRoom, int numBattleRoad)
    {
        rooms.Clear();
        roads.Clear();
        AddRoomsRoads(numRoom);

        Min(out columnCount, out rowCount);

        List<List<int>> mapData = GetJson(numBattleRoom, numBattleRoad);
        Json.SaveJson(new MapData(mapData));
    }

    static void AddRoomsRoads(int numRoom)
    {
        rooms.Add(Vector2.zero);

        Vector2 randomRoom = rooms[Random.Range(0, rooms.Count)];
        Vector2 randomDir = GetRandomDir();

        for (int i = 1; i < numRoom; i++)
        {
            while (rooms.Contains(randomRoom + randomDir * roadLength))
            {
                randomRoom = rooms[Random.Range(0, rooms.Count)];
                randomDir = GetRandomDir();
            }

            rooms.Add(randomRoom + randomDir * roadLength);
            for (int j = 1; j < roadLength; j++)
            {
                roads.Add(randomRoom + randomDir * j);
            }
        }
    }

    //修正
    static void Min(out float columnCount, out float rowCount)
    {
        float minX = 0;
        float maxX = 0;
        float minY = 0;
        float maxY = 0;

        for (int i = 0; i < rooms.Count; i++)
        {
            Vector2 temp = rooms[i];
            if (temp.x < minX)
            {
                minX = temp.x;
            }
            else if (temp.x > maxX)
            {
                maxX = temp.x;
            }

            if (temp.y < minY)
            {
                minY = temp.y;
            }
            else if (temp.y > maxY)
            {
                maxY = temp.y;
            }
        }

        for (int i = 0; i < rooms.Count; i++)
        {
            rooms[i] = new Vector2(rooms[i].x - minX, rooms[i].y - minY);
        }
        for (int i = 0; i < roads.Count; i++)
        {
            roads[i] = new Vector2(roads[i].x - minX, roads[i].y - minY);
        }

        columnCount = (maxX - minX);
        rowCount = (maxY - minY);
    }

    static List<Vector2> GetBattleRooms(int numBattleRoom)
    {
        List<Vector2> result = new List<Vector2>();
        List<Vector2> temp = new List<Vector2>();
        rooms.ForEach(i => temp.Add(i));
        for (int i = 0; i < numBattleRoom; i++)
        {
            int index = Random.Range(0, temp.Count);
            result.Add(temp[index]);
            temp.RemoveAt(index);
        }
        return result;
    }

    static List<Vector2> GetBattleRoads(int numBattleRoad)
    {
        List<Vector2> result = new List<Vector2>();
        List<Vector2> temp = new List<Vector2>();
        roads.ForEach(i => temp.Add(i));
        for (int i = 0; i < numBattleRoad; i++)
        {
            int index = Random.Range(0, temp.Count);
            result.Add(temp[index]);
            temp.RemoveAt(index);
        }
        return result;
    }

    static List<List<int>> GetJson(int numBattleRoom, int numBattleRoad)
    {
        List<List<int>> result = new List<List<int>>();
        for (int i = 0; i <= rowCount; i++)
        {
            List<int> line = new List<int>();
            for (int j = 0; j <= columnCount; j++)
            {
                line.Add(5);
            }
            result.Add(line);
        }
        for (int i = 0; i < rooms.Count; i++)
        {
            int x = (int)rooms[i].x;
            int y = (int)rooms[i].y;
            result[y][x] = 3;
        }
        for (int i = 0; i < roads.Count; i++)
        {
            int x = (int)roads[i].x;
            int y = (int)roads[i].y;
            result[y][x] = 1;
        }

        List<Vector2> battleRooms = GetBattleRooms(numBattleRoom);
        List<Vector2> battleRoads = GetBattleRoads(numBattleRoad);
        for (int i = 0; i < battleRooms.Count; i++)
        {
            int x = (int)battleRooms[i].x;
            int y = (int)battleRooms[i].y;
            result[y][x] = 4;
        }
        for (int i = 0; i < battleRoads.Count; i++)
        {
            int x = (int)battleRoads[i].x;
            int y = (int)battleRoads[i].y;
            result[y][x] = 2;
        }
        for (int i = 0; i < rooms.Count; i++)
        {
            if (!battleRooms.Contains(rooms[i]))
            {
                int x = (int)rooms[i].x;
                int y = (int)rooms[i].y;
                result[y][x] = 0;
                break;
            }
        }

        return result;
    }
    static void AddBlocks(List<Vector2> posList, int num)
    {

    }

    static Vector2 GetRandomDir()
    {
        int a = Random.Range(0, 4);
        switch (a)
        {
            case 0:
                return Vector2.left;
            case 1:
                return Vector2.right;
            case 2:
                return Vector2.up;
            case 3:
                return Vector2.down;
            default:
                return Vector3.left;
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    void Update()
    {
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");

        if (h != 0)
        {
            Vector3 dir = transform.position + Vector3.right * h;
            if (Mgr.instance.vector2Map.Contains(dir))
            {
                transform.position = dir;
            }
        }

        if (v != 0)
        {
            Vector3 dir = transform.position + Vector3.up * v;
            if (Mgr.instance.vector2Map.Contains(dir))
            {
                transform.position = dir;
            }
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using Newtonsoft.Json;
using UnityEditor;

public class Json
{
    [MenuItem("MyTools/SaveMap")]
    static void SaveMap()
    {
        SaveJson(Init());
    }

    private static string JsonPath()
    {
        return Application.streamingAssetsPath + "/Json.json";
    }

    private static MapData Init()
    {
        MapData mapData = new MapData();
        mapData.data = new List<List<int>>()
        {
            new List<int> {5,5,5,5,5,5,5,5,5,5,5,5,5,3,1,1,1,1,1,2,1,1,1,1,4},
            new List<int> {5,5,5,5,5,5,5,5,5,5,5,5,5,1,5,5,5,5,5,5,5,5,5,5,5},
            new List<int> {5,5,5,5,5,5,5,5,5,5,5,5,5,1,5,5,5,5,5,5,5,5,5,5,5},
            new List<int> {5,5,5,5,5,5,5,5,5,5,5,5,5,1,5,5,5,5,5,5,5,5,5,5,5},
            new List<int> {5,5,5,5,5,5,5,5,5,5,5,5,5,1,5,5,5,5,5,5,5,5,5,5,5},
            new List<int> {0,1,1,2,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,2,1,1,1,1,3},
            new List<int> {5,5,5,5,5,1,5,5,5,5,5,5,5,1,5,5,5,5,5,5,5,5,5,5,5},
            new List<int> {5,5,5,5,5,2,5,5,5,5,5,5,5,1,5,5,5,5,5,5,5,5,5,5,5},
            new List<int> {5,5,5,5,5,1,5,5,5,5,5,5,5,1,5,5,5,5,5,5,5,5,5,5,5},
            new List<int> {5,5,5,5,5,1,5,5,5,5,5,5,5,1,5,5,5,5,5,5,5,5,5,5,5},
            new List<int> {5,5,5,5,5,3,1,1,1,1,1,1,1,4,5,5,5,5,5,5,5,5,5,5,5},
        };
        return mapData;
    }

    public static void SaveJson(MapData mapData)
    {
        if (!File.Exists(JsonPath()))
        {
            File.Create(JsonPath());
        }

        string json = JsonConvert.SerializeObject(mapData);
        File.WriteAllText(JsonPath(), json);
        //Debug.Log("保存成功");
    }

    public static MapData ReadJson()
    {
        if (!File.Exists(JsonPath()))
        {
            Debug.LogError("文件不存在");
            return null;
        }

        string json = File.ReadAllText(JsonPath());
        MapData mapData = JsonConvert.DeserializeObject<MapData>(json);

        return mapData;
    }
}

public class MapData
{
    public MapData(List<List<int>> a)
    {
        data = a;
    }

    public MapData()
    {
    }

    public List<List<int>> data;
}
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值