Fal*_*nNL 97 algorithm map terrain
我正在研究类似文明的游戏,我正在寻找一种用于生成类似地球的世界地图的好算法.我已经尝试了一些替代方案,但尚未找到真正的赢家.
一种选择是使用Perlin噪声生成高度图,并在一定水平上添加水,以便世界上大约30%的土地是土地.虽然Perlin噪声(或类似的基于分形的技术)经常用于地形并且相当逼真,但它并没有提供太多控制结果的数量,大小和位置,我想从游戏角度来看.

第二种选择是从随机定位的单瓦种子开始(我正在处理瓷砖网格),确定大陆的所需大小,每个回合添加一个水平或垂直邻近现有大陆的图块,直到你达到了所需的大小.重复其他大陆.这种技术是文明4中使用的算法的一部分.问题在于,在放置前几个大陆之后,可以选择被其他大陆包围的起始位置,因此不适合新的大陆.此外,它有一种太靠近的地方产生大陆的趋势,导致看起来更像河流而不是大陆.

有没有人碰巧知道一个好的算法,用于在基于网格的地图上生成逼真的大陆,同时保持对其数量和相对大小的控制?
Dav*_*one 38
你可以从大自然中获取线索并修改你的第二个想法.一旦你生成了你的大陆(大小都相同),让他们随机移动和旋转,相互碰撞和变形,彼此分开.(注意:这可能不是最容易实现的东西.)
编辑:这是另一种方法,完成了一个实现 - 游戏的多边形地图生成.
Nor*_*sey 11
我建议你备份
一旦你有了这个,你就可以开始实现一个算法,其形状应该是这样的:
为了改进,你可以尝试各种标准的优化技巧,无论是模拟退火,遗传编程,还是完全临时的东西,比如将随机选择的边缘正方形从大陆移动到与大陆质量中心相对的边缘.但关键是能够编写一个程序,可以告诉好大陆不好的大陆.从手绘的大陆以及您的测试大陆开始,直到您得到您喜欢的东西.
nat*_*ere 10
我写了一些类似于你所追求的文明1的自动屏幕保护程序式克隆的东西.为了记录我在VB.net中写了这个但是因为你没有在你的问题中提到任何关于语言或平台的东西我会保留它抽象.
"地图"指定了大陆的数量,大陆的大小差异(例如,1.0将使所有大陆具有相同的近似土地面积,低至0.1将允许大陆以最大陆的质量的十分之一存在),最大陆地面积(以百分比表示)产生,以及中央土地偏见."种子"在每个大陆的地图周围随机分布,按照中心偏差向地图中心加权(例如,低偏差产生的分布大陆与地球更相似,其中高中心偏差将更像是盘古).然后,对于每次增长迭代,"种子"根据分布算法(稍后更多)分配地块,直到达到最大陆地面积.
土地分配算法可以尽可能精确,但我发现应用各种遗传算法和滚动骰子的更有趣的结果.康威的"生命游戏"是一个非常简单的开始.你需要添加一些全局意识的逻辑,以避免像大陆相互影响的事情,但大多数事情都要照顾好自己.我发现更多基于分形的方法(这是我的第一个倾向)的问题是结果看起来太过模式化,或导致太多场景需要hacky-feeling workaround规则来获得仍然感觉不够动态的结果.根据您使用的算法,您可能希望对结果应用"模糊"传递,以消除诸如丰富的单方形海洋瓷砖和方格海岸线之类的东西.如果像大陆一样被其他几个人包围并且无处可生的大陆,将种子重新定位到地图上的新点并继续增长.是的,它可能意味着你有时会比计划更多的大陆,但如果它真的是你坚定不想要的东西,那么另一种方法来帮助避免它是偏向增长算法,所以他们倾向于增长的方向与最接近其他种子.在最坏的情况下(我认为无论如何),当种子无处增长并生成新地图时,您可以将系列标记为无效.只要确保设置最大尝试次数,如果指定任何不切实际的东西(比如在10x10板上安装50个均匀加权的大陆),它就不会花费太多时间来寻找有效的解决方案.
我无法保证Civ等如何做到这一点,当然也没有涵盖气候,土地年龄等等,但通过种子生长算法,您可以得到非常有趣的结果,类似于大陆,群岛等.你可以使用相同的方法来生产"有机"的河流,山脉等.
Aye*_*xeM 10
我在JavaScript中创建了与您的第一个图像类似的东西.它不是超级复杂但它有效:
http://jsfiddle.net/AyexeM/zMZ9y/
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<style type="text/css">
#stage{
font-family: Courier New, monospace;
}
span{
display: none;
}
.tile{
float:left;
height:10px;
width:10px;
}
.water{
background-color: #55F;
}
.earth{
background-color: #273;
}
</style>
</head>
<body>
<div id="stage">
</div>
<script type="text/javascript">
var tileArray = new Array();
var probabilityModifier = 0;
var mapWidth=135;
var mapheight=65;
var tileSize=10;
var landMassAmount=2; // scale of 1 to 5
var landMassSize=3; // scale of 1 to 5
$('#stage').css('width',(mapWidth*tileSize)+'px');
for (var i = 0; i < mapWidth*mapheight; i++) {
var probability = 0;
var probabilityModifier = 0;
if (i<(mapWidth*2)||i%mapWidth<2||i%mapWidth>(mapWidth-3)||i>(mapWidth*mapheight)-((mapWidth*2)+1)){
// make the edges of the map water
probability=0;
}
else {
probability = 15 + landMassAmount;
if (i>(mapWidth*2)+2){
// Conform the tile upwards and to the left to its surroundings
var conformity =
(tileArray[i-mapWidth-1]==(tileArray[i-(mapWidth*2)-1]))+
(tileArray[i-mapWidth-1]==(tileArray[i-mapWidth]))+
(tileArray[i-mapWidth-1]==(tileArray[i-1]))+
(tileArray[i-mapWidth-1]==(tileArray[i-mapWidth-2]));
if (conformity<2)
{
tileArray[i-mapWidth-1]=!tileArray[i-mapWidth-1];
}
}
// get the probability of what type of tile this would be based on its surroundings
probabilityModifier = (tileArray[i-1]+tileArray[i-mapWidth]+tileArray[i-mapWidth+1])*(19+(landMassSize*1.4));
}
rndm=(Math.random()*101);
tileArray[i]=(rndm<(probability+probabilityModifier));
}
for (var i = 0; i < tileArray.length; i++) {
if (tileArray[i]){
$('#stage').append('<div class="tile earth '+i+'"> </div>');
}
else{
$('#stage').append('<div class="tile water '+i+'"> </div>');
}
}
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
在这里想一下袖口:
选择一些起点,并为每个起点分配一个随机抽取(希望)的大小.如果需要,您可以为计划的大陆和计划的岛屿维护单独的大小绘制.
环绕土地元素,并且它们尚未达到规划尺寸的地方增加一个方格.但有趣的部分是权衡每个相邻元素的概率.一些可能因素的建议:
继续,直到所有土地群已达到规划的大小或由于某种原因不能再增长.
请注意,将参数赋予这些加权因子可以调整生成的世界类型,这是我喜欢的一些Civs的功能.
这样你就需要分别对每个位进行地形生成.