RogueLike地图随机生成
挺喜欢玩《以撒的结合》的,觉得游戏里房间的随机生成挺有意思
刚好在写一个自己的RogueLike游戏,就想着来复刻一下
首先来看一下《以撒的结合》中地图的模样
可以看到是由n个房间组合而成的
这里有几个注意点:
- 每个房间都必须连通,即玩家可以从任意一个房间走到另外一个任意房间。
- 拥有不同功能的房间,并且按照功能有特殊生成规则。比如说,BOSS房间不能太靠近初始房间。
初步想法就是,创建一个Generator,通过控制Generator上下左右随机行动,来逐步生成每个房间
具体实现
首先创建一个长方形的白色Sprite(名为Room)代替房间轮廓并标上序号
然后给房间加上一个Trigger(具体如图中绿框)
Trigger目的是表明房间实体是否生成
编写Room.cs并添加到Room中
using UnityEngine;
using UnityEngine.UI;
public class Room : MonoBehaviour
{
public Text text;
public int stepToStart;
// Start is called before the first frame update
void Start(){}
// Update is called once per frame
void Update(){}
public void UpdateRoom(int order)
{
text.text = order.ToString(); //房间序号
}
}
创建RoomGenerator,并创建生成点Point
用枚举来表明Point移动的四个方向
当移动完毕之后,判断该点是否有房间存在
若有则继续移动,若无则结束移动
public enum Direction { up, down, left, right }
public Direction direction;
do
{
direction = (Direction)Random.Range(0, 4);
switch (direction)
{
case Direction.up:
generatorPoint.position += new Vector3(0, yOffset, 0);
break;
case Direction.down:
generatorPoint.position += new Vector3(0, -yOffset, 0);
break;
case Direction.left:
generatorPoint.position += new Vector3(-xOffset, 0, 0);
break;
case Direction.right:
generatorPoint.position += new Vector3(xOffset, 0, 0);
break;
}
}while (Physics2D.OverlapCircle(generatorPoint.position, 0.2f, roomLayer));
当Point移动完毕后,将房间生成
生成完毕的房间存储在List当中,方便调用
为了看的更清楚,可以将头尾房间用不同的颜色标记出
编写RoomGenerator.cs并添加到RoomGenerator中
using UnityEngine;
using UnityEngine.SceneManagement;
public class RoomGenerator : MonoBehaviour
{
public enum Direction { up, down, left, right }
public Direction direction;
[Header("房间信息")]
public GameObject roomPrefab;
public int roomQuantity;
public Color startColor, endColor;
[Header("位置控制")]
public Transform generatorPoint;
public float xOffset;
public float yOffset;
public LayerMask roomLayer;
public List<Room> rooms = new List<Room>();
// Start is called before the first frame update
void Start()
{
for (int i = 0; i < roomQuantity; i++)
{
rooms.Add(Instantiate(roomPrefab, generatorPoint.position, Quaternion.identity).GetComponent<Room>());
ChangePointPos();
}
rooms[0].GetComponent<SpriteRenderer>().color = startColor; //设定起始房间颜色
rooms[roomQuantity-1].GetComponent<SpriteRenderer>().color = endColor; //设定末尾房间颜色
foreach (var room in rooms)
{
room.UpdateRoom(rooms.IndexOf(room)+1); //更新房间距离
}
}
// Update is called once per frame
void Update()
{
if (Input.anyKeyDown) //此处为了方便调试,通过按键重新生成
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
public void ChangePointPos()
{
do
{
direction = (Direction)Random.Range(0, 4);
switch (direction)
{
case Direction.up:
generatorPoint.position += new Vector3(0, yOffset, 0);
break;
case Direction.down:
generatorPoint.position += new Vector3(0, -yOffset, 0);
break;
case Direction.left:
generatorPoint.position += new Vector3(-xOffset, 0, 0);
break;
case Direction.right:
generatorPoint.position += new Vector3(xOffset, 0, 0);
break;
}
} while (Physics2D.OverlapCircle(generatorPoint.position, 0.2f, roomLayer));
}
}
RoomGenerator.cs的配置信息
然后运行调试
可以看到,在房间数量为6的测试下,生成效果很理想