地图切片算法
地图
我正在用Javascript制作一个基于图块的RPG,使用perlin噪声高度图,然后根据噪声的高度分配一个图块类型。
地图最终看起来像这样(在小地图视图中)。
我有一个相当简单的算法,它从图像上的每个像素中提取颜色值,并根据其在(0-255)之间的位置将其转换为整数(0-5),这对应于瓷砖字典中的瓷砖。然后,将此 200x200 数组传递到客户端。
然后,引擎从数组中的值中确定切片,并将它们绘制到画布上。所以,我最终得到了有趣的世界,这些世界具有逼真的特征:山脉,海洋等。
现在我想做的下一件事是应用某种混合算法,如果邻居不是同一类型,这将使瓷砖无缝地融入邻居。上面的示例地图是玩家在其小地图中看到的内容。在屏幕上,他们看到由白色矩形标记的部分的渲染版本;其中,切片使用其图像呈现,而不是作为单色像素呈现。
这是用户在地图中看到的内容的示例,但它与上面的视口显示的位置不同!
正是在这种观点中,我希望过渡发生。
算法
我想出了一个简单的算法,可以在视口内遍历地图,并在每个图块的顶部渲染另一个图像,前提是它位于不同类型的图块旁边。(不改变地图!只是渲染一些额外的图像。该算法的想法是分析当前图块的邻居:
这是引擎可能必须呈现的内容的示例方案,当前磁贴是用 X 标记的磁贴。
将创建一个 3x3 数组,并读取其周围的值。因此,对于此示例,数组如下所示。
[
[1,2,2]
[1,2,2]
[1,1,2]
];
当时我的想法是为可能的瓷砖配置制定一系列案例。在一个非常简单的层面上:
if(profile[0][1] != profile[1][1]){
//draw a tile which is half sand and half transparent
//Over the current tile -> profile[1][1]
...
}
这给出了这样的结果:
它的工作原理是从 到 ,但不是从 到 的过渡,其中保留一个硬边。所以我想在这种情况下,必须使用角图块。我创建了两个 3x3 精灵表,我认为这两个表可以容纳所有可能需要的图块组合。然后,我为游戏中的所有图块复制了这一点(白色区域是透明的)。这最终是每种类型的磁贴有 16 个磁贴(不使用每个 spritesheet 上的中心磁贴。[0][1]
[1][1]
[1][1]
[2][1]
理想的结果
因此,使用这些新磁贴和正确的算法,示例部分将如下所示:
但是,我所做的每一次尝试都失败了,算法中总是存在一些缺陷,并且模式最终变得奇怪。我似乎无法正确处理所有案例,总的来说,这似乎是一种糟糕的方法。
解决方案?
因此,如果有人可以提供另一种解决方案,说明我如何创建这种效果,或者编写分析算法的方向,那么我将不胜感激!