You could take a cue from nature and modify your second idea. Once you generate your continents (which are all about the same size), get them to randomly move and rotate and collide and deform each other and drift apart from each other. (Note: this may not be the easiest thing ever to implement.)
Write an algorithm that can tell a good continental layout from a bad one.
Refine the algorithm so that you can quantify how good a good layout is.
Once you have that in place, you can start to implement an algorithm which should be shaped like this:
Generate crappy continents and then improve them.
For improvement you can try all sorts of standard optimization tricks, whether it's simulated annealing, genetic programming, or something completely ad hoc, like moving a randomly chosen edge square from whereever it is on the continent to the edge opposite the continent's center of mass. But the key is to be able to write a program that can tell good continents from bad ones. Start out with hand-drawn continents as well as your test continents, until you get something you like.
I wrote something similar to what you're after for an automated screensaver-style clone of Civilization 1. For the record I wrote this in VB.net but since you don't mention anything about language or platform in your question I'll keep it abstract.
The "map" specifies the number of continents, continent size variance (eg 1.0 would keep all continents with the same approximate land area, down to 0.1 would allow continents to exist with 1/10th the mass of the largest continent), maximum land area (as a percentage) to generate, and the central land bias. A "seed" is distributed randomly around the map for each continent, weighted towards the centre of the map as per the central bias (eg a low bias produces distributed continents more similar to Earth, where as a high central bias will resemble more of a Pangaea). Then for each iteration of growth, the "seeds" assign land tiles according to a distribution algorithm (more on that later) until a maximum land area has been reached.
The land distribution algorithm can be as precise as you want but I found more interesting results applying various genetic algorithms and rolling the dice. Conway's "Game of Life" is a really easy one to start out with. You'll need to add SOME globally aware logic to avoid things like continents growing into each other but for the most part things take care of themselves. The problem I found with more fractal-based approaches (which was my first inclination) was the results either looked too patterned, or lead to too many scenarios requiring hacky-feeling workaround rules to get a result which still didn't feel dynamic enough. Depending on the algorithm you use, you may want to apply a "blurring" pass over the result to eliminate things like abundant single-square ocean tiles and checkered coastlines. In the event something like a continent being spawned surrounded by several others and having nowhere left to grow, relocate the seed to a new point on the map and continue the growth passes. Yes, it can mean you sometimes end up with more continents than planned, but if it's really something you firmly don't want then another way to help avoid it is bias the growth algorithms so they favour growth in the direction with least proximity to other seeds. At worst (in my opinion anyway), you can flag a series as invalid when a seed has nowhere left to grow and generate a new map. Just make sure you set a maximum number of attempts so if anything unrealistic is specified (like fitting 50 even-weighted continents on a 10x10 board) it doesn't spend forever trying to find a valid solution.
I can't vouch for how Civ etc do it, and of course doesn't cover things like climate, land age etc but by playing around with the seed growth algorithm you can get pretty interesting results that resemble continents, archipelagos etc. You can use the same approach to produce 'organic' looking rivers, mountain ranges etc too.
<!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>
I've created something similar to your first image in JavaScript. It's not super sophisticated but it works :
<!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>
Pick some starting points, and assign each a randomly drawn (hoped for) size. You can can maintain a separate size draw for planned continents and planned islands if you want.
Loop over the land elements, and where they are not yet at the planned size add one square. But the fun part is weighing the chance that each neighboring element will be the one. Some suggested thing that might factor in:
Distance to the nearest "other" land. Further is better generates wide oceanic spaces. Nearer is better makes narrow channels. You have to decide if you're going to let bits merge as well.
Distance from the seed. Nearer is better means compact land masses, farther is better means long strung out bits
Number of existing land squares adjacent. Weighting in favor of many adjacent squares gives you smooth coast, preferring few gives you lots of inlets and peninsulas.
Presence of "resources" squares nearby? Depends on the game rules, when you generate resource square, and if you want to make it easy.
Will you allow bits to approach or join with the poles?
??? don't know what else
Continue until all land masses have reached the planned size or can't grow anymore for some reason.
Notice that diddling the parameter to these weighting factors allows you to tune the kind of world generated , which is a feature I liked about some of the Civs.
This way you'll need to do terrain generation on each bit separately.
You could try a diamond square algorithm or perlin noise to generate something like a height map. Then, assign ranges values to what shows up on the map. If your "height" goes from 0 to 100, then make 0 - 20 water, 20 - 30 beach, 30 - 80 grass, 80 - 100 mountains. I think notch did something similar to this in minicraft, but I'm not an expert, I'm just in a diamond square mindset after finally getting it working.
A1= [elliptical rectangular random ... ]// list of continents with area A1 approx.
A2= [elliptical rectangular random ... ]// list of continents with area A2 approx.
A3= [elliptical rectangular random ... ]// list of continents with area A3 approx.
...
An= [elliptical rectangular random ... ]// list of continents with area An approx.
// note that elliptical is approximately elliptical in shape and same for the other shapes.
Choose one/more randomly from each of the lists (An).
Now you have control over number and area of continents.
You can use genetic algorithm for positioning them
as you see "fit" ;)
I think you can use "dynamic programming" style approach here.
Solve small problems first and combine solutions smartly to solve bigger problem.
A1= [elliptical rectangular random ... ]// list of continents with area A1 approx.
A2= [elliptical rectangular random ... ]// list of continents with area A2 approx.
A3= [elliptical rectangular random ... ]// list of continents with area A3 approx.
...
An= [elliptical rectangular random ... ]// list of continents with area An approx.
// note that elliptical is approximately elliptical in shape and same for the other shapes.
Choose one/more randomly from each of the lists (An).
Now you have control over number and area of continents.
You can use genetic algorithm for positioning them
as you see "fit" ;)
It will be very good to take a look at some "Graph Layout Algorithms"
I had an idea for map creation similar to the tectonic plates answer. It went something like this:
sweep through the grid squares giving each square a "land" square if rnd <= 0.292 (the actual percentage of dry land on planet earth).
Migrate each land chunk one square toward its nearest larger neighbour. If neighbours are equidistant, go toward the larger chunk. If chunks are equal size, choose one randomly.
if two land squares touch, group them into a chunk, moving all squares as one from now on.
repeat from step 2. Stop when all chunks are connected.
This is similar to how gravity works in a 3D space. It's pretty complicated. A simpler algorithm for your needs would work as follows:
Drop in n starter land squares at random x,y positions and acceptable distances from each other. These are seeds for your continents. (Use the Pythagorean theorem to ensure the seeds have a minimum distance between themselves and all others.)
spawn a land square from an existing land square in a random direction, if that direction is an ocean square.
repeat step 2. Stop when land squares fill 30% of total map size.
if continents are close enough to each other, drop in land bridges as desired to simulate a Panama type effect.
Drop in smaller, random islands as desired for a more natural look.
for each extra "island" square you add, cut out inland seas and lake squares from the continents using the same algorithm in reverse. This will maintain the land percentage at the desired amount.
Let me know how this works out. I've never tried it myself.
PS. I see this is similar to what you tried. Except it sets up all the seeds at once, before beginning, so the continents will be far enough apart and will stop when the map is sufficiently filled.
I haven't actually tried this but it was inspired by David Johnstone's answer regarding tectonic plates. I tried implementing it myself in my old Civ project and when it came to handling collisions I had another idea. Instead of generating tiles directly, each continent consists of nodes. Distribute mass to each node then generate a series of "blob" continents using a 2D metaball approach. Tectonics and continental drift would be ridiculously easy to "fake" simply by moving the nodes around. Depending on how complex you want to go, you could even apply things like currents to handle the node movement and generate mountain ranges that correspond to plate boundaries overlapping. Probably wouldn't add that much to the gameplay side of things, but it could make for an interesting map generation from a purely academic perspective :)
A good explanation of metaballs if you haven't worked with them before:
Here's what I'm thinking, since I'm about to implement something like this that I have for a game in development. :
The world divided into regions. depending on the size of the world, it will determine how many regions. For this example, we'll assume a medium sized world, with 6 regions. Each grid zone breaks into 9 grid zones. those grid zones break into 9 grids each. (this is not for character movement, but merely for map creation) The Grids are for biomes, grid zones are for over arching land features, (continent vs ocean) and the regions are for overall climate. The grids break down into tiles.
Randomly generated, the regions get assigned logical climate sets. Grid zones get randomly assigned to, for instance; ocean or land. Grids get assigned biomes randomly with modifiers based on their grid zones and climate, these being forest, desert, plains, glacial, swamp or volcanic. Once all those basics are assigned, it's time to blend them together, using a random percentage based function that fills in tile sets. For example; if you have a forest biome, next to a desert biome, you have an algorithm that decreases the likely hood that a tile will be "foresty" and increases that it will be "deserty." So, about half way between them, you'll see a sort of blended affect combining the two biomes to off a somewhat smooth transition between them. Transition from one grid zone to the next would probably take a little more work to insure logic landmass formations.Like, for example, a biome from one grid zone that touches the biome from another, instead of having a simple switching percentage based on proximity. For example, there are 50 tiles from the center of the biome to the edge of the biome, meaning, there are 50 from the edge it touches to the center of the next biome. That would logically leave a 100% change from one biome to the next. So as the tiles get nearer to the border of the two biomes, the percentage narrows out to around 60% or so. It'd, I think, be unwise to give too much probability of crossing biomes far from the border, but you'll want the border to be somewhat blended. For the grid zones, the percentage change will be much more pronounced. Instead of the % going down to around 60%, it'd only drop down to around 80%. And a secondary check would then have to be performed to ensure that there's not a random water tile in the middle of a land biome next to the ocean without some logic to it. So, either, connect that water tile to the ocean mass to make a channel to explain the water tile, or remove it altogether. Land in a water based biome is easier to explain using rock outcrops and such.
I'd place fractal terrain according to some layout that you know "works" (e.g. 2x2 grid, diamond, etc, with some jitter) but with a Gaussian distribution damping peaks down towards the edges of the continent centers. Place the water level lower so that is mostly land until you get near the edges.
发布评论
评论(11)
您可以从自然中汲取灵感并修改您的第二个想法。一旦你生成了你的大陆(大小都差不多),让它们随机移动、旋转、碰撞、彼此变形并相互漂移。 (注意:这可能不是最容易实现的事情。)
编辑:这是另一种实现方式,完成实现 - 游戏的多边形地图生成。
You could take a cue from nature and modify your second idea. Once you generate your continents (which are all about the same size), get them to randomly move and rotate and collide and deform each other and drift apart from each other. (Note: this may not be the easiest thing ever to implement.)
Edit: Here's another way of doing it, complete with an implementation — Polygonal Map Generation for Games.
我建议你回过头来
一旦你做到了这一点,你就可以开始实现一个应该像这样的算法:
为了改进,你可以尝试各种标准的优化技巧,无论是模拟退火、遗传编程或完全临时的东西,例如将随机选择的边缘方块从大陆上的任何位置移动到与大陆质心相对的边缘。但关键是能够编写一个可以区分好大陆和坏大陆的程序。从手绘大陆和测试大陆开始,直到得到你喜欢的东西。
I'd suggest you back up and
Once you have that in place, you can start to implement an algorithm which should be shaped like this:
For improvement you can try all sorts of standard optimization tricks, whether it's simulated annealing, genetic programming, or something completely ad hoc, like moving a randomly chosen edge square from whereever it is on the continent to the edge opposite the continent's center of mass. But the key is to be able to write a program that can tell good continents from bad ones. Start out with hand-drawn continents as well as your test continents, until you get something you like.
我写了一些类似于你所追求的文明 1 自动屏幕保护式克隆的内容。为了记录,我在 VB.net 中写了这篇文章,但由于你在问题中没有提到任何有关语言或平台的内容,我将保留它抽象。
“地图”指定大陆数量、大陆大小方差(例如,1.0 将使所有大陆保持相同的近似陆地面积,小至 0.1 将允许大陆以最大大陆的 1/10 质量存在)、最大陆地面积(以百分比形式)生成,并且中央土地偏差。 “种子”随机分布在每个大陆的地图周围,根据中心偏差向地图中心加权(例如,低偏差会产生更类似于地球的分布式大陆,而高中心偏差将更像地球)盘古大陆)。然后,对于每次增长迭代,“种子”根据分配算法(稍后详细介绍)分配土地块,直到达到最大土地面积。
土地分配算法可以像你想要的那样精确,但我发现应用各种遗传算法和掷骰子会得到更有趣的结果。康威的《生命游戏》非常容易上手。您需要添加一些全球意识的逻辑,以避免大陆相互生长之类的事情,但在大多数情况下,事情会自行解决。我发现更多基于分形的方法(这是我的第一个倾向)的问题是结果要么看起来过于模式化,要么导致太多场景需要黑客感觉的解决方法规则来获得仍然不够动态的结果。根据您使用的算法,您可能希望对结果应用“模糊”传递,以消除大量单方形海洋瓷砖和方格海岸线等内容。如果某个大陆被其他几个大陆包围并且没有地方可以生长,请将种子重新定位到地图上的新点并继续生长过程。是的,这可能意味着你有时会得到比计划更多的大陆,但如果这确实是你坚决不想要的东西,那么另一种帮助避免这种情况的方法是对增长算法进行偏见,这样它们就会倾向于向最不接近其他方向的方向增长种子。在最坏的情况下(无论如何在我看来),当种子无处生长并生成新地图时,您可以将系列标记为无效。只需确保您设置了最大尝试次数,这样,如果指定了任何不切实际的内容(例如在 10x10 板上安装 50 个均匀加权的大陆),就不会永远花费时间来尝试找到有效的解决方案。
我不能保证《文明》等是如何做到这一点的,当然不包括气候、土地年龄等内容,但通过使用种子生长算法,你可以获得类似大陆、群岛等的非常有趣的结果。你可以也可以使用相同的方法来生成看起来“有机”的河流、山脉等。
I wrote something similar to what you're after for an automated screensaver-style clone of Civilization 1. For the record I wrote this in VB.net but since you don't mention anything about language or platform in your question I'll keep it abstract.
The "map" specifies the number of continents, continent size variance (eg 1.0 would keep all continents with the same approximate land area, down to 0.1 would allow continents to exist with 1/10th the mass of the largest continent), maximum land area (as a percentage) to generate, and the central land bias. A "seed" is distributed randomly around the map for each continent, weighted towards the centre of the map as per the central bias (eg a low bias produces distributed continents more similar to Earth, where as a high central bias will resemble more of a Pangaea). Then for each iteration of growth, the "seeds" assign land tiles according to a distribution algorithm (more on that later) until a maximum land area has been reached.
The land distribution algorithm can be as precise as you want but I found more interesting results applying various genetic algorithms and rolling the dice. Conway's "Game of Life" is a really easy one to start out with. You'll need to add SOME globally aware logic to avoid things like continents growing into each other but for the most part things take care of themselves. The problem I found with more fractal-based approaches (which was my first inclination) was the results either looked too patterned, or lead to too many scenarios requiring hacky-feeling workaround rules to get a result which still didn't feel dynamic enough. Depending on the algorithm you use, you may want to apply a "blurring" pass over the result to eliminate things like abundant single-square ocean tiles and checkered coastlines. In the event something like a continent being spawned surrounded by several others and having nowhere left to grow, relocate the seed to a new point on the map and continue the growth passes. Yes, it can mean you sometimes end up with more continents than planned, but if it's really something you firmly don't want then another way to help avoid it is bias the growth algorithms so they favour growth in the direction with least proximity to other seeds. At worst (in my opinion anyway), you can flag a series as invalid when a seed has nowhere left to grow and generate a new map. Just make sure you set a maximum number of attempts so if anything unrealistic is specified (like fitting 50 even-weighted continents on a 10x10 board) it doesn't spend forever trying to find a valid solution.
I can't vouch for how Civ etc do it, and of course doesn't cover things like climate, land age etc but by playing around with the seed growth algorithm you can get pretty interesting results that resemble continents, archipelagos etc. You can use the same approach to produce 'organic' looking rivers, mountain ranges etc too.
我用 JavaScript 创建了与您的第一张图像类似的东西。它不是超级复杂,但它可以工作:
http://jsfiddle.net/AyexeM/zMZ9y/
I've created something similar to your first image in JavaScript. It's not super sophisticated but it works :
http://jsfiddle.net/AyexeM/zMZ9y/
在这里即兴思考:
选择一些起点,并为每个点分配一个随机绘制的(希望的)大小。如果需要,您可以为规划的大陆和规划的岛屿维护单独的尺寸绘制。
遍历土地元素,在尚未达到计划大小的地方添加一个正方形。但有趣的部分是权衡每个相邻元素成为该元素的可能性。一些人建议可能考虑的因素:
继续,直到所有土地块都达到计划大小或由于某种原因无法再增长。
请注意,将参数调整为这些权重因子可以让您调整生成的世界类型,这是我喜欢某些《文明》的一个功能。
这样,您就需要分别对每个位进行地形生成。
Just thinking off the cuff here:
Pick some starting points, and assign each a randomly drawn (hoped for) size. You can can maintain a separate size draw for planned continents and planned islands if you want.
Loop over the land elements, and where they are not yet at the planned size add one square. But the fun part is weighing the chance that each neighboring element will be the one. Some suggested thing that might factor in:
Continue until all land masses have reached the planned size or can't grow anymore for some reason.
Notice that diddling the parameter to these weighting factors allows you to tune the kind of world generated , which is a feature I liked about some of the Civs.
This way you'll need to do terrain generation on each bit separately.
您可以尝试使用菱形方形算法或柏林噪声来生成诸如高度图之类的东西。然后,将范围值分配给地图上显示的内容。如果你的“高度”从 0 到 100,那么制作 0 - 20 水,20 - 30 海滩,30 - 80 草,80 - 100 山。我认为 notch 在微型工艺中做了类似的事情,但我不是专家,我只是在最终让它发挥作用后处于钻石方形心态。
You could try a diamond square algorithm or perlin noise to generate something like a height map. Then, assign ranges values to what shows up on the map. If your "height" goes from 0 to 100, then make 0 - 20 water, 20 - 30 beach, 30 - 80 grass, 80 - 100 mountains. I think notch did something similar to this in minicraft, but I'm not an expert, I'm just in a diamond square mindset after finally getting it working.
我认为你可以在这里使用“动态编程”风格的方法。
看看一些“图形布局算法”会非常好
您可以修改这些以满足您的目的。
I think you can use "dynamic programming" style approach here.
It will be very good to take a look at some "Graph Layout Algorithms"
You can modify these to suit your purpose.
我有一个类似于构造板块答案的地图创建想法。它是这样的:
这类似于重力在 3D 空间中的作用方式。这非常复杂。满足您需求的更简单的算法将按如下方式工作:
让我知道结果如何。我自己从来没有尝试过。
附言。我发现这与您尝试过的类似。除了它在开始之前立即设置所有种子之外,因此大陆之间的距离将足够远,并且当地图足够充满时就会停止。
I had an idea for map creation similar to the tectonic plates answer. It went something like this:
This is similar to how gravity works in a 3D space. It's pretty complicated. A simpler algorithm for your needs would work as follows:
Let me know how this works out. I've never tried it myself.
PS. I see this is similar to what you tried. Except it sets up all the seeds at once, before beginning, so the continents will be far enough apart and will stop when the map is sufficiently filled.
我实际上没有尝试过这个,但它的灵感来自大卫·约翰斯通关于构造板块的回答。我尝试在我的旧 Civ 项目中自己实现它,当涉及到处理碰撞时,我有另一个想法。每个大陆不是直接生成图块,而是由节点组成。将质量分配到每个节点,然后使用 2D 元球方法生成一系列“斑点”大陆。只需移动节点即可轻松“伪造”构造和大陆漂移。根据您想要的复杂程度,您甚至可以应用诸如电流之类的东西来处理节点运动并生成与板块边界重叠相对应的山脉。可能不会给游戏玩法增加太多,但从纯粹的学术角度来看,它可以生成有趣的地图:)
如果您之前没有使用过元球,那么它是对元球的一个很好的解释:
http://www.gamedev。净/页/资源/_//feature/fprogramming/exploring-metaballs-and-isosurfaces-in-2d-r2556
I haven't actually tried this but it was inspired by David Johnstone's answer regarding tectonic plates. I tried implementing it myself in my old Civ project and when it came to handling collisions I had another idea. Instead of generating tiles directly, each continent consists of nodes. Distribute mass to each node then generate a series of "blob" continents using a 2D metaball approach. Tectonics and continental drift would be ridiculously easy to "fake" simply by moving the nodes around. Depending on how complex you want to go, you could even apply things like currents to handle the node movement and generate mountain ranges that correspond to plate boundaries overlapping. Probably wouldn't add that much to the gameplay side of things, but it could make for an interesting map generation from a purely academic perspective :)
A good explanation of metaballs if you haven't worked with them before:
http://www.gamedev.net/page/resources/_//feature/fprogramming/exploring-metaballs-and-isosurfaces-in-2d-r2556
这就是我的想法,因为我即将为正在开发的游戏实现类似的东西。 :
世界分为多个区域。根据世界的大小,它将决定有多少个地区。对于这个例子,我们假设一个中等大小的世界,有 6 个区域。每个网格区域分为9个网格区域。这些网格区域各自分为 9 个网格。 (这不是为了角色移动,而只是为了创建地图)网格用于生物群落,网格区域用于拱形陆地特征(大陆与海洋),区域用于整体气候。网格分解成瓷砖。
这些区域是随机生成的,并被分配了逻辑气候集。例如,网格区域被随机分配;海洋或陆地。网格会根据其网格区域和气候随机分配生物群落和修饰符,这些是森林、沙漠、平原、冰川、沼泽或火山。一旦分配了所有这些基础知识,就可以使用填充图块集的基于随机百分比的函数将它们混合在一起。例如;如果你有一个森林生物群落,旁边有一个沙漠生物群落,你就有一个算法,可以减少一块瓷砖“森林”的可能性,并增加它“沙漠”的可能性。因此,大约在它们之间的中间,您会看到一种混合效果,将两个生物群系结合在一起,以在它们之间实现某种平滑的过渡。从一个网格区域到下一个网格区域的过渡可能需要更多的工作来确保逻辑陆地的形成。例如,一个网格区域的生物群落接触另一个网格区域的生物群落,而不是根据接近度进行简单的切换百分比。例如,从生物群落的中心到生物群落的边缘有 50 个图块,这意味着,从它接触的边缘到下一个生物群落的中心有 50 个图块。从逻辑上讲,这将使从一个生物群落到下一个生物群落发生 100% 的变化。因此,当图块越来越接近两个生物群落的边界时,百分比会缩小到 60% 左右。我认为,给远离边界的生物群落提供太多的可能性是不明智的,但你会希望边界有些混合。对于网格区域,百分比变化会更加明显。百分比不会下降到 60% 左右,而只会下降到 80% 左右。然后必须进行二次检查,以确保在海洋旁边的陆地生物群落中间不存在没有任何逻辑的随机水瓦片。因此,要么将该水瓦连接到海洋,以形成一条通道来解释水瓦,要么将其完全移除。使用岩石露头等更容易解释水基生物群落中的土地。
噢,有点笨,抱歉。
Here's what I'm thinking, since I'm about to implement something like this that I have for a game in development. :
The world divided into regions. depending on the size of the world, it will determine how many regions. For this example, we'll assume a medium sized world, with 6 regions. Each grid zone breaks into 9 grid zones. those grid zones break into 9 grids each. (this is not for character movement, but merely for map creation) The Grids are for biomes, grid zones are for over arching land features, (continent vs ocean) and the regions are for overall climate. The grids break down into tiles.
Randomly generated, the regions get assigned logical climate sets. Grid zones get randomly assigned to, for instance; ocean or land. Grids get assigned biomes randomly with modifiers based on their grid zones and climate, these being forest, desert, plains, glacial, swamp or volcanic. Once all those basics are assigned, it's time to blend them together, using a random percentage based function that fills in tile sets. For example; if you have a forest biome, next to a desert biome, you have an algorithm that decreases the likely hood that a tile will be "foresty" and increases that it will be "deserty." So, about half way between them, you'll see a sort of blended affect combining the two biomes to off a somewhat smooth transition between them. Transition from one grid zone to the next would probably take a little more work to insure logic landmass formations.Like, for example, a biome from one grid zone that touches the biome from another, instead of having a simple switching percentage based on proximity. For example, there are 50 tiles from the center of the biome to the edge of the biome, meaning, there are 50 from the edge it touches to the center of the next biome. That would logically leave a 100% change from one biome to the next. So as the tiles get nearer to the border of the two biomes, the percentage narrows out to around 60% or so. It'd, I think, be unwise to give too much probability of crossing biomes far from the border, but you'll want the border to be somewhat blended. For the grid zones, the percentage change will be much more pronounced. Instead of the % going down to around 60%, it'd only drop down to around 80%. And a secondary check would then have to be performed to ensure that there's not a random water tile in the middle of a land biome next to the ocean without some logic to it. So, either, connect that water tile to the ocean mass to make a channel to explain the water tile, or remove it altogether. Land in a water based biome is easier to explain using rock outcrops and such.
Oh, kinda dumb, sorry.
我会根据一些您知道“有效”的布局(例如 2x2 网格、菱形等,带有一些抖动)放置分形地形,但具有高斯分布,阻尼峰值向下朝向大陆中心的边缘。将水位降低,这样直到接近边缘之前大部分都是陆地。
I'd place fractal terrain according to some layout that you know "works" (e.g. 2x2 grid, diamond, etc, with some jitter) but with a Gaussian distribution damping peaks down towards the edges of the continent centers. Place the water level lower so that is mostly land until you get near the edges.