程序生成的顶视图2D RPG地图生成

程序生成是一个迷人的概念,并在游戏行业越来越受欢迎。 玩游戏的游戏每次玩的时候都有新的内容,对我来说是非常激动人心的。

我的问题是我将如何去使用适当的过渡区块生成顶视图2D地图?

我知道如何创建与独立的瓷砖顶视图地图。 例如,我可以用草和树生成程序图。 但是我不能生成不同大小和形状的森林。 我怎么知道把哪个森林精灵放在哪里? 我试图循环地图瓦片和访问周围的瓦片来select哪个瓦片是合适的。 但是,这种方法不会导致错误的森林瓷砖放在哪里? 计算机必须知道森林的大小以及森林的形状。

这个问题对我来说太复杂了。 任何想法如何打破这个问题将不胜感激,或者如果你只是想谈论程序生成我也是这样的游戏。

到目前为止,我已经生成了一个森林,但我有麻烦,使其看起来不错。 这是我到目前为止。 https://76295db93db3812642fa5ba984c042fa81ffc37c.googledrive.com/host/0B6H3TRExU5M9eEkyd2FreHhiNlU/

这个问题似乎是关于如何去产生一个地图select正确的瓷砖,所以这是我会回答。

你所说的是“自动裁剪”或“自动平铺”(取决于你问的对象)。

这是一个简单的方法来处理:

给定一个瓦片,我们可以find它的邻居。 然后每个瓦片具有边缘的4位状态和角部的4位状态,每个瓦片总共给出256个状态。 鉴于提供的图像,我们可以假设我们只需要关心每个瓦片的边缘邻居:

.#. #X# .#. 

出于理智的考虑,我们还会假设瓦片只有一种其他瓦片types(例如trees -> grass )过渡,或者瓦片包含透明度,并且分层在其他瓦片types之上。

那么每个瓦片需要16个不同的图像,每个邻居状态一个:

 eg 0: ... 1: .#. 2: ... 3: .#. etc. .X. .X. .X# .X# ... ... ... ... 

要确定需要哪个图像,只需在生成后迭代一次地图即可确定要渲染哪个图块。 这在运行时不应该太昂贵,或者如果需要,可以预先处理地图。

如果预处理地图,则应该制作一个单独的地图,用于存储实际可渲染的拼贴图,而不是就地编辑现有的地图。 这将使处理更简单,并且不会引入任何在处理时改变图块types的错误。

更新:简单的现场示例如下:

 var canvas = document.getElementById('canv'); var ctx = canvas.getContext('2d'); var map = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] var tiles = new Image(); tiles.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKoAAAAKCAYAAAAkasVsAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAADxSURBVFhH7ZfBCcJQEESNZQhe9CJiJSrYjUXYjaBWIuJFL4JtKF/54ikzg5/sByfXTGZn398kbLO/Dx894loMboTqLZlf1q3aw3hDezF+SaN41pwPZSvdaz4Ill9UvkYZVBQyN1tKlw8F+bG6yHzMm5nyleqVqadqIvP11bDWm0AEAQ9qBHXXlAl4UGVkfiCCgAc1grprygSkZUp27/gBtIhELlPsVt0xsk85xI5dWBWd0qs0qKPtstX7utq97pfSJa/kifyyDsGOHNTz8QTPRemVYQILfgkmsymUe+uHiCz4dwLSF7V2WDV/Uf3r/216nslTmhyOBL3DAAAAAElFTkSuQmCC'; var mTemp = []; for (var i = 0; i < map.length; i++) mTemp.push(0); for (var y = 0; y < 10; y++) { for (var x = 0; x < 10; x++) { if (map[y * 10 + x] == 1) { var val = 0; if (y > 0 && map[(y - 1) * 10 + x] == 1) val |= 1; if (x < 9 && map[y * 10 + x + 1] == 1) val |= 2; if (y < 9 && map[(y + 1) * 10 + x] == 1) val |= 4; if (x > 0 && map[y * 10 + x - 1] == 1) val |= 8; mTemp[y * 10 + x] = val + 1; } else mTemp[y * 10 + x] = map[y * 10 + x]; } } for (var y = 0; y < 10; y++) { for (var x = 0; x < 10; x++) { var tile = mTemp[y * 10 + x]; ctx.drawImage(tiles, tile * 10, 0, 10, 10, x * 10, y * 10, 10, 10); } } 
 <canvas id="canv" width="100" height="100"></canvas> 

对于随机瓦片生成,使用元胞自动机algorithm是一个好方法。

http://www.roguebasin.com/index.php?title=Cellular_Automata_Method_for_Generating_Random_Cave-Like_Levels

这是一个很好的基本思想教程。 基本上你有一些随机(或噪音)function,生成初始瓷砖。 然后,这个过程逐渐将类似的区域组合在一起,这可以给你漂亮的“随机”形状。

你可以做到这一点不仅仅是二进制值来实现更复杂的平铺世界。

一个常用的技术是从n * n个瓷砖的预制部分构建你的地图,这些瓷砖可以以不同的方式组合在一起(如果你想这样称呼它们,就是“超级瓷砖”)。 我最喜欢的例子是老式的X-COM:UFO Defense。 在总览图上,它们变得非常明显,特别是在“农田”生物群落中:

XCom:Ufo Defence概述图

当你想让你的地图很容易导航的时候(玩家可以从任何超级地图移动到任何相邻的超级地图),你需要确保每一个超级地图的南/北和东/西边界都有一个部分,被挡在任何超级球员上,所以玩家总是可以在他们之间移动。 X-com在农田生物群系上解决了这个问题,使每块瓷砖都向南和东方完全开放,从而可以根据需要将出口放到北方和西方。

当你想让你的地图更像迷宫(玩家只能在相邻的超级地图之间移动)时,需要为死角,直线,曲线,三角交叉点和交叉路段创建不同的超类。 至less你需要:

  • 4个死角(从南,西,北,东进入)
  • 2直(水平和垂直)
  • 4条曲线
  • 4个T型路口
  • 1道口

只要使用这15个基本超集中的一个,就可以使用标准的迷宫生成algorithm创建相当多的地图。 但是当你想要更多种类的时候,你可以为这15个基本图块创建多个替代版本。 只要他们都履行在同一地点开幕的合同,他们将是可以互换的。 以下是一些东北曲线的例子,它们都可以实现相同的function,并且应该可以互换,而不会影响地图的可播放性:

 ### ### ### ### ### ### ### ### ### ### # # ### ## ## ### ### # #### # # ####### ## # ####### ### # ####### ####### ####### ####### 

为了使这些更加有趣,超级瓷砖也可以随机化内部变化forms的特征,只有很less机会出现在每个超级特征上,只要这些特征不影响超级导航。 例如,在一个地下城中的一个房间可能有50%的几率在右上角有一个胸部,左上角的书架,右下角的武器架和左下角的桌子。 这已经给你一个价格的16个不同的超types。