元气骑士 自建服务器,30分钟简易复刻《元气骑士》地图生成系统
对《元气骑士》这款游戏想必大家都不陌生。
元气骑士是由凉屋游戏工作室研发的一款角色扮演类游戏,于2017年2月17日发布。 游戏讲述了外星生物夺走维持世界的魔法石的故事,玩家将扮演骑士、刺客等角色参与游戏,夺回魔法石。
Unity Connect社区博主超级汽水借助Unity对游戏中的地图生成系统进行了复刻。与各位分享在此。
地图显示方式
随机大小的矩形房间。
随机的房间数量。
通过走廊连接每个房间。
每个图都有 俩个特殊房间:“出生房”、“传送房”。
地图生成思路梳理
因为在原版游戏中房间并不是完全的正方形,所以我们在设计时要考虑到边长的问题。
虽然游戏中的房间数量是随机的,但是也是有一个范围的。所以需要按照生成地图的最终面积来做一个约束。
走廊连接算是游戏中的一个难点,因为走廊的长度是不确定的要在生成房间后根据房间的位置和大小来确定走廊的生成位置以及长度。
在游戏中,每一个大关卡包含多个小关卡,每个小关卡中又包含了多张地图,每个地图中又有多个小房间。
这样说可能有点不太好理解我画了张图来帮忙理解:
1.png (20.01 KB, 下载次数: 3)
2020-3-10 11:08 上传
实现思路以及简化
在之前博主已经发过两篇文章介绍tilemap生成随机地图的方法,如果对tilemap不太了解可以点击【阅读原文】关注博主,获取往期教程。
整体的实现流程如下:
1、根据用户定义创建一张足够大的地图 (这里的地图指每个小关所有房间所在的大地图)。
2.png (2.08 KB, 下载次数: 3)
2020-3-10 11:08 上传
2 、假设大地图中所有位置布满大小相同的房间 (这里的房间边长一定要奇数,比较好操作),然后根据所需的房间总数来删掉多余的房间。
3.png (4.56 KB, 下载次数: 6)
2020-3-10 11:08 上传
4.png (4.86 KB, 下载次数: 5)
2020-3-10 11:08 上传
5.png (3.38 KB, 下载次数: 6)
2020-3-10 11:08 上传
3 .根据规定的长宽比,来随机修改每个房间的大小。
6.png (3.62 KB, 下载次数: 5)
2020-3-10 11:08 上传
4 .生成过道连通所有房间,(这里黄色的点是原先没有改变大小时的正方形的中心点)
7.png (6.46 KB, 下载次数: 6)
2020-3-10 11:08 上传
5 .确定特殊房间的位置。
8.png (6.58 KB, 下载次数: 6)
2020-3-10 11:08 上传
Tilemap中单独房间效果图:
9.png (27.74 KB, 下载次数: 7)
2020-3-10 11:08 上传
一个简单的房间以及半个过道
10.png (40.48 KB, 下载次数: 6)
2020-3-10 11:08 上传
长方形连接正方形房间,黄色方块为中心点
Unity中详细操作
1、创建一个普通的Tilemap。
2、创建一个空物体,用来挂载我们的地图生成脚本。
11.png (75.77 KB, 下载次数: 5)
2020-3-10 11:08 上传
3、 创建所需要的变量
public class MapManager : MonoBehaviour
{
[Header("地图种子")] public int seed = 123456;
[Header("每行房间数")] public int mapMaxW;
[Header("每列房间数")] public int mapMaxH;
[Header("总生成房间数")] public int mapCount;
[Header("最大房间宽")] public int roomMaxW;
[Header("最大房间高")] public int roomMaxH;
[Header("最小房间宽")] public int roomMinW;
[Header("最小房间高")] public int roomMinH;
[Header("房间的间隔距离")] public int distance;
[Header("地板")] public TileBase floor;
[Header("墙")] public TileBase wall;
[Header("地图")] public Tilemap tilemap;
private int[,] _roomMap;
private List _centerPoint;
private Dictionary _mapPoint;
}
复制代码
4、列出所需函数
//画出地图
private void DrawMap(){}
//画出房间
private void DrawRoom(int roomX,int roomY){}
//画出路
private void DrawRoad(){}
//画出地板和墙壁
private void DrawFloor(){}
//生成房间 (用二维 int 数组表示)
private int[,] RandomRoom(int maxW, int maxH, int minW, int minH, out int width, out int height){}
//生成一个地图 (用二维 int 数组表示)
private int[,] GetRoomMap(int mapW, int mapH, int roomCount)
//获取一个范围内的随机奇数
private int GetOddNumber(int min, int max){}
//获取下一个房间的位置
private Vector2Int GetNextPoint(Vector2Int nowPoint, int maxW, int maxH)
5 、实现各个函数
代码已经放在文末的附件,这里我讲一下我的大体思路以及各个函数的作用。
首先是使用,我在 Update 函数中检测按下 R 键重新生成地图,生成很简单只要调用 DrawMap 函数就可以。
private void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
DrawMap();
}
}
复制代码
在 DrawMap 中 会调用 DrawRoad 和 DrawFloor 俩个函数来分别画出道路和地板、墙壁。
部分函数解析:
//取一定范围内的一个奇数
private int GetOddNumber(int min, int max)
{
while (true)
{
var temp = Random.Range(min, max);
if ((temp & 1) != 1) continue;
return temp;
}
}
复制代码
这个函数主要用来在房间生成的时候取一个随机的奇数出来,因为我们的房间连接需要一个中心点所以奇数更方便使用。
//生成一个房间,用二维 int 数组表示
private int[,] RandomRoom(int maxW, int maxH, int minW, int minH, out int width, out int height)
{
width = GetOddNumber(minW, maxW);
height = GetOddNumber(minH, maxH);
var room = new int[width, height];
//方便以后扩展使用了二维数组,这里为了演示方便对房间内生成其他物体
for (var i = 0; i < width; i++)
{
for (var j = 0; j < height; j++)
{
room[i, j] = 1;
}
}
return room;
}
复制代码
这个函数主要用来生成一个房间,选用二维int数组主要是为了扩展、存储时方便。本案例中 普通地板为 1,墙壁为 0。同时为了后续步骤计算方便这里把生成的房间的长宽也返回了。
private int[,] GetRoomMap(int mapW, int mapH, int roomCount)
{
//第一个房间的坐标点
var nowPoint = Vector2Int.zero;
//当前生成的房间数
var mCount = 1;
//当前地图
var map = new int[mapW, mapH];
//第一个格子总有房间,作为出生房间
map[nowPoint.x, nowPoint.y] = 1;
while (mCount < roomCount)
{
nowPoint = GetNextPoint(nowPoint, mapW, mapH);
if (map[nowPoint.x, nowPoint.y] == 1) continue;
map[nowPoint.x, nowPoint.y] = 1;
mCount ++;
}
return map;
}
复制代码
这个函数用来生成总体的地图,也就是用来查看哪里需要生成房间。需要生成房间的地方为 1 ,空白的地方为 0。与GetNextPoint 连用获取下一个房间的坐标点。因为房间总是相连所以不存在间隔。
private Vector2Int GetNextPoint(Vector2Int nowPoint, int maxW, int maxH)
{
while (true)
{
var mNowPoint = nowPoint;
switch (Random.Range(0, 4))
{
case 0:
mNowPoint.x += 1;
break;
case 1:
mNowPoint.y += 1;
break;
case 2:
mNowPoint.x -= 1;
break;
default:
mNowPoint.y -= 1;
break;
}
if (mNowPoint.x >= 0 && mNowPoint.y >= 0 && mNowPoint.x < maxW && mNowPoint.y < maxH)
{
return mNowPoint;
}
}
}
复制代码
这个函数大体的思想还是参照我前俩篇文章中讲到的随机游走法的思路。
最终效果
1、生成房间
12.png (20.61 KB, 下载次数: 5)
2020-3-10 11:08 上传
2 、添加横向过道
13.png (21.52 KB, 下载次数: 6)
2020-3-10 11:08 上传
3 、添加纵向过道
14.png (22.85 KB, 下载次数: 6)
2020-3-10 11:08 上传
4 、添加墙壁
15.png (59.75 KB, 下载次数: 3)
2020-3-10 11:08 上传
作者:超级汽水
来源:Unity官方平台
原地址:https://mp.weixin.qq.com/s/OZggLLodTF9cownbt2FzGg
元气骑士 自建服务器,30分钟简易复刻《元气骑士》地图生成系统相关推荐
- 30分钟简易复刻元气骑士地图生成系统
本文转自Unity Connect博主 超级汽水 一个简易的房间类 Roguelike 游戏地图生成系统 如果你还不知道<元气骑士>是什么游戏,也许你可以去看看这个视频 https://s ...
- 元气骑士 自建服务器,元气骑士主机小工具ip地址怎么弄?ip设置方法教学[多图]...
元气骑士主机小工具ip地址怎么弄?最近有很多朋友在使用元气骑士主机小工具中遇到了问题,不知道到ip地址怎么输入,今天小编就为大家带来详细的介绍,帮助大家更好的联机体验游戏,有需要的朋友们一起来看看吧! ...
- 元气骑士 自建服务器,《元气骑士》新模式“电子空间”,自建地牢很轻松,这是创造玩法...
遇枪不捡,遇怪就跑,大家好,我是菜鸟熊猫~ 欢迎来到由熊猫君主讲的<元气骑士>大型栏目<元气搞笑日常>的第54期~ 在元气骑士这款游戏当中,因为玩法模式的固定导致了很多的玩家都 ...
- 元气骑士 自建服务器,七夕元气骑士联机盒子服务器官方版
七夕元气骑士联机盒子是一款可以带来热血地牢大冒险的动作游戏,拥有着超多特色的作战玩法可以在游戏里尽情的展开冒险,让你能够成为强大的地牢战神,不断在战斗讨伐之中成长自身,通过不断的杀戮来获得强力装备,不 ...
- 传送门骑士自建服务器,《传送门骑士》开放私人服务器!大神作品零距离
<传送门骑士>国服近日更新到1.34版本,增加了许多备受玩家好评的玩法内容,其中最具突破性的则是私人服务器的开放,这意味着玩家可以任意开放自己的沙盒世界.<传送门骑士>自面世以 ...
- AI帮60年代老技术解决面料数字化难题,王华民团队新方法只需3分钟数据采集复刻面料真实效果...
杨净 发自 凹非寺 量子位 | 公众号 QbitAI 当人人谈论元宇宙时,大家都在关心什么?空间是否热闹丰富,交互是否丝滑-- NoNoNo其实都不是,而是真实感与沉浸感. △饱受批评的小扎自拍 作为 ...
- 面试官问:生成订单30分钟未支付,则自动取消,该怎么实现?
欢迎关注方志朋的博客,回复"666"获面试宝典 来源 | https://blog.csdn.net/hjm4702192/article/details/80519010 在开发 ...
- 订单30分钟未支付自动取消怎么实现?
本文已经收录到Github仓库,该仓库包含计算机基础.Java核心知识点.多线程.JVM.常见框架.分布式.微服务.设计模式.架构等核心知识点,欢迎star~ 地址:https://github.co ...
- 面试官:生成订单30分钟未支付,则自动取消,该怎么实现?
Hollis的新书限时折扣中,一本深入讲解Java基础的干货笔记! 目录 了解需求 方案 1:数据库轮询 方案 2:JDK 的延迟队列 方案 3:时间轮算法 方案 4:redis 缓存 方案 5:使用 ...
最新文章
- java 运算符_java 运算符
- 还在封装各种 Util 工具类?这个神级框架帮你解决所有问题!
- tableview逆时针旋转90度。
- n皇后问题(回溯法-递归法和循环法,最小冲突法(较快解决10000级别问题))
- 第四范式先知平台成为首个通过金融信创适配验证的AI产品
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(三)
- 第三十五期:网络爬虫是啥玩意儿?有什么用呢?
- 利用栈和队列将队列中的元素逆置☆
- python selenium环境安装及配置_selenium环境配置
- go tcp客户端自动重连_在Go中构建并发TCP服务器样例
- 微软全面拥抱 AI!
- Java编程:将五子棋棋盘内容用稀疏矩阵存储至磁盘,并从中重新读取内容——稀疏数组和算法
- python json转对象
- 07-图4 哈利·波特的考试(25 分)
- 一文了解IMU原理、误差模型、标定、惯性传感器选型以及IMU产品调研(含IMU、AHRS、VRU和INS区别)
- mysql设置外部ip访问
- 基于jws发布webservice服务
- 1080驱动此图形驱动程序_如何更新图形驱动程序以获得最佳游戏性能
- python n维向量向任意方向旋转,求旋转矩阵
- 12、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用 == 还是equals()? 它们有何区别?