“以撒的结合”地图是怎样生成的——RogueLike地图随机生成

RogueLike地图随机生成

挺喜欢玩《以撒的结合》的,觉得游戏里房间的随机生成挺有意思

刚好在写一个自己的RogueLike游戏,就想着来复刻一下

首先来看一下《以撒的结合》中地图的模样

以撒的结合地图
可以看到是由n个房间组合而成的

这里有几个注意点:

  1. 每个房间都必须连通,即玩家可以从任意一个房间走到另外一个任意房间。
  2. 拥有不同功能的房间,并且按照功能有特殊生成规则。比如说,BOSS房间不能太靠近初始房间。

初步想法就是,创建一个Generator,通过控制Generator上下左右随机行动,来逐步生成每个房间


具体实现

首先创建一个长方形的白色Sprite(名为Room)代替房间轮廓并标上序号

然后给房间加上一个Trigger(具体如图中绿框)

Trigger目的是表明房间实体是否生成

图1.1
编写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

图1.2
用枚举来表明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的配置信息

图1.3
然后运行调试

图1.4
可以看到,在房间数量为6的测试下,生成效果很理想

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值