本文主要是为了实现各种随机大小不一样的方块基础房间,便于 Roguelike 游戏地图使用,希望对各位独立游戏的新手有所帮助,同时也希望各位大牛可以给出宝贵意见。

由于我的思路是地图=基础房间+特殊房间(宝箱房、挑战房、任务房、Boss房),本文暂不涉及特殊房间以及个性化的多边形房间。

房间要求

房间大小基本符合一定的长宽比;

单个房间不会有重叠;

房间间保留一定间隙,方便后续填充围墙与走廊;

整体房间分布不是线性的,方便后续连通的多样性;

核心思路

根据游戏的操作,定下一个房间的长宽比;(本文的房间长宽比为1.6-2.0)

根据长宽比,取得1号房间的长与宽X1,Y1;

取得1号房间的中心点O1;

对O1进行一个四向的随机偏移,得到O2;

取得2号房间的长于宽X2,Y2;

利用射线检测,若无重叠则可生成,若有,重复4、5、6步骤直到可以生成;

铺设地毯、围墙等基本装饰物,完成。

效果图

房间概览图

房间细节图

代码

C#代码如下,包含三个主体方法:取得房间半径、取得房间中心点和生成房间。

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class MapManager : MonoBehaviour

{

// Use this for initialization

private float roomRadii;//房间的长度半径

private float roomRatio;//由宽决定长的比值

public float roomX;//房间的长

public float roomY;//房间的宽

public float roomXi;//房间i的长

public float roomYi;//房间i的宽

public int roomXMin = 10;

public int roomXMax = 16;

public Vector2 posO;//房间中心点

int roomIndex = 0;

public List roomPos = new List();//创建储存房间有效位置的二维表

public List offset = new List();//创建储存房间中心点的二维表

public GameObject[] floorArray;

public Transform roomHolder;

void Start()

{

roomPos.Clear();//后续房间内的所有可用位置都会添加到这个二维表里

SetRoomXY();

posO = new Vector2(0, 0);

//生成12个房间进行检验

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

}

void SetRoomXY()//取得房间长宽半径

{

roomRadii = Random.Range(roomXMin, roomXMax);//标准值取随机值

roomRatio = Random.Range(16, 20);

roomRatio = roomRatio / 10;

roomX = 2 * roomRadii;//房间的长是标准值的两倍,因此就是偶数

roomY = roomX / roomRatio;//房间的宽由长来决定

roomY = Mathf.Round(roomY);//对Y取整数

if (roomY % 2 != 0)//对Y进行判断,取偶数 {

roomY += 1;

}

}

Vector2 CreateCenter(Vector2 pos)//对中心点进行偏移

{

int x = Random.Range(2 * roomXMin + 1, 2 * roomXMax + 1);

offset.Clear();

for (int i = 2 * roomXMin + 1; i <= 2 * roomXMax + 1; i++) {

for (int j = 30; j <= 50; j++) {

offset.Add(new Vector2(i, j));

}

}

//现在取出一个符合基本规则的中心点偏移量

int index = Random.Range(0, offset.Count);

float offsetX = offset[index].x;

float offsetY = offset[index].y;

Vector2 pos2 = new Vector2(0, 0);

int o = Random.Range(0, 4);

if (o == 0) {

pos2 = pos + new Vector2(offsetX, offsetY);

}

if (o == 1) {

pos2 = pos + new Vector2(offsetX, -offsetY);

}

if (o == 2) {

pos2 = pos + new Vector2(-offsetX, offsetY);

}

if (o == 3) {

pos2 = pos + new Vector2(-offsetX, -offsetY);

}

//现在取得了下一个房间中心

posO = pos2;

return posO;

}

void CreateRoom(Vector2 pos)//生成基础房间(铺设地板)

{

CreateCenter(pos);//对上一个房间的中心点进行偏移,取得本次房间的中心点

pos = posO;

SetRoomXY();//取得当前要生成房间的长宽半径

roomXi = roomX;

roomYi = roomY;

int isRoom = 0;

//对预生成的房间先进行是否有房间的检测(基于房间九点:左上,中上,右上,左中……)

Vector2 checkPos1 = new Vector2(pos.x - roomXi, pos.y - roomYi) + new Vector2(-4, -4);

Vector2 checkPos2 = new Vector2(pos.x - roomXi, pos.y + roomYi) + new Vector2(-4, 4);

Vector2 checkPos3 = new Vector2(pos.x + roomXi, pos.y - roomYi) + new Vector2(-4, 4);

Vector2 checkPos4 = new Vector2(pos.x + roomXi, pos.y + roomYi) + new Vector2(4, 4);

Vector2 checkPos6 = new Vector2(pos.x, pos.y - roomYi) + new Vector2(0, -4);

Vector2 checkPos7 = new Vector2(pos.x, pos.y + roomYi) + new Vector2(0, 4);

Vector2 checkPos8 = new Vector2(pos.x + roomXi, pos.y) + new Vector2(4, 0);

Vector2 checkPos9 = new Vector2(pos.x - roomXi, pos.y) + new Vector2(-4, 0);

RaycastHit2D hit1 = Physics2D.Linecast(checkPos1, checkPos1, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit2 = Physics2D.Linecast(checkPos2, checkPos2, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit3 = Physics2D.Linecast(checkPos3, checkPos3, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit4 = Physics2D.Linecast(checkPos4, checkPos4, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit5 = Physics2D.Linecast(pos, pos, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit6 = Physics2D.Linecast(checkPos6, checkPos6, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit7 = Physics2D.Linecast(checkPos7, checkPos7, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit8 = Physics2D.Linecast(checkPos8, checkPos8, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit9 = Physics2D.Linecast(checkPos9, checkPos9, 1 << LayerMask.NameToLayer("floor"));

if (hit1.collider == null && hit2.collider == null && hit3.collider == null && hit4.collider == null && hit5.collider == null && hit6.collider == null && hit7.collider == null && hit8.collider == null && hit9.collider == null)

{

isRoom += 1;

}

if (isRoom >= 0)

{

if (isRoom == 0) {

CreateRoom(pos);

} else {

roomIndex += 1;//可以生成房间的时候,给房间记上标记

roomHolder = new GameObject("Room" + roomIndex).transform;//给父类添加名字

//为地板进行二维数组赋值

for (float x = pos.x - roomXi; x <= pos.x + roomXi; x++) {

for (float y = pos.y - roomYi; y <= pos.y + roomYi; y++) {

Vector2 posFloor = new Vector2(x, y);

roomPos.Add(new Vector2(x, y));

int i = Random.Range(0, floorArray.Length);

GameObject go = Instantiate(floorArray[i], posFloor, Quaternion.identity);

go.transform.SetParent(roomHolder);

}

}

}

}

}

}

关于连通与特殊房,我的想法是因为生成的时候给房间以及进行序号标记了(1-12),先依次对中心点进行走廊生成,以及门生成,确保主干道连通,再取随机房间进行连通丰富路线(如2和4,6和8),在这个基础上加入预设的特殊房。(特殊房应该有足够的设计量,因此不适宜用随机。)

unity随机方向的代码_基于 Unity 的 Roguelike 随机房间生成的方法相关推荐

  1. 随机森林实例:利用基于CART算法的随机森林(Random Forest)树分类方法对于红酒质量进行预测

    随机森林实例:利用基于CART算法的随机森林(Random Forest)树分类方法对于红酒质量进行预测 1.引言 2.理论基础 2.1 什么是决策树 2.2 特征选择的算法 2.2.1 ID3:基于 ...

  2. unity 地图编辑器_基于Unity的场景基础测试

    场景作为游戏的一个基本构成元素,其功能.效果和性能的重要程度不言而喻.良好的场景表现是游戏留存率的重要因素,因此,QA对场景的测试需要格外注意. 场景的测试一般分为基础功能.效果.性能三方面.基础功能 ...

  3. 编写python手机充值代码_基于Python的天聚人合加油卡充值接口调用代码实例

    一.接口申请开通 本代码是基于天聚人合的话费充值API实现的话费充值功能,使用前需要: 通过https://www.tianjurenhe.com/docs/api/?id=1申请开通话费接口服务. ...

  4. 离散数学 逻辑判断系统 代码_基于线性时态逻辑的物联网操作系统安全性设计...

    随着物联网技术的发展,物联网设备安全性问题将是急需解决的核心问题之一.同时,在保障物联网设备安全的所有措施中操作系统层面的安全是重中之重,从本质上讲,可以说物联网操作系统的安全性直接决定了整个物联网设 ...

  5. python提取人物特征_基于图像人物面部表情识别的特征提取优化方法与流程

    本发明涉及一种基于图像人物面部表情识别的特征提取优化方法,主要利用基于统计特征提取的二维主成分分析法和改进的粒子群算法优化图像矩阵的解,属于图像处理.模式识别和计算机视觉交叉技术应用领域. 背景技术: ...

  6. 基于连通域字符分割的流程_基于改进连通域算法的车牌字符分割方法

    基于改进连通域算法的车牌字符分割方法 朱亚萍,邱锦山,杨成忠 [摘 要] 摘要:为了解决车牌字符分割中不连通汉字分割.粘连字符分割以及 竖直边框干扰等问题,提出了一种基于改进连通域算法的车牌字符分割方 ...

  7. python图书馆管理系统实验报告_基于Python的图书馆业务报表自动生成研究

    龙源期刊网 http://www.qikan.com.cn 基于 Python 的图书馆业务报表自动生成研 究 作者:辛海滨 来源:<电脑知识与技术> 2016 年第 27 期 摘要:针对 ...

  8. 网格合并之后物体的位置改变了_基于网格映射对自动驾驶环境信息表示方法

    作者 | Aimee知圈 | 进"汽车操作系统社群"请加微信13636581676,备注系统自动驾驶过程中往往需要对所驾驶的环境进行比较精确而完整的表示,通常会采用网格图的方式进行 ...

  9. em模型补缺失值_基于EM算法数据单变量缺失处理方法研究

    龙源期刊网 http://www.qikan.com.cn 基于 EM 算法数据单变量缺失处理方法研究 作者:黄铉 来源:<科技传播> 2015 年第 20 期 摘 要 数据分析方法大都针 ...

最新文章

  1. 普通人学python有用吗-普通人学Python有什么用?
  2. Apache solr(二).
  3. Linux下C程序插入执行shell脚本
  4. 参加了 Go 贡献者大会
  5. 论文学习10-Joint entity recognition and relation extraction as a multi-head selection problem(实体关系联合抽取模型
  6. 前端性能优化的重要方案:图片懒加载
  7. jquery remove()不兼容问题解决方案
  8. 数据流中的中位数 c语言,41 数据流中的中位数(时间效率)
  9. 服务器搭建网站完整教程(宝塔面板+wordpress) 快速搭建网站 一键部署
  10. Scikit-learn:聚类clustering
  11. ubuntu下配置开机启动服务
  12. Idea自定义Maven骨架(archetype)
  13. linux 6.5 dos2unix,dos2unix 安装
  14. Android Fingerprint完全解析(三) :Fingerprint Hal层分析
  15. ps中怎样测量标尺线之间的距离及怎样切换距离单位
  16. Android Kotlin之Flow数据流
  17. LoRa 数据速率,码片速率,符号速率
  18. Linux-根目录(/)的意义与内容
  19. 教你用 python 制作一张五彩斑斓的黑
  20. 我与数据仓库那些事-数据模型

热门文章

  1. 粒子群优化算法(PSO)简介及MATLAB实现
  2. 自考 02333 软件工程 思维导图 软件工程绪论与需求获取
  3. 服务器芯片维修,基于英特尔六核64位“服务器级”处理芯片
  4. Server 2008 将微软雅黑更改为宋体
  5. (一)算法基础——枚举
  6. Flipper TR膜张力传感器——简化了测定方法
  7. 文献阅读笔记——《Plug-and-Play Image Restoration with Deep Denoiser Prior》
  8. Flink解决广播配置流滞后数据流的问题
  9. php session 反序列化
  10. idea上如何跑java程序_java – 如何在Intellij IDEA中运行Applet?