模拟<暗黑地牢>的随机地图
先上图, 绿色是起点, 蓝色是道路, 粉色是事件, 红色是战斗房间, 黄色是奖励房间
用的是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;
}