我正在尝试使用Midpoint Displacement Algorithm使用JavaScript和canvas
gamedev.stackexchange.com建议。
以下代码生成数组索引为x
位置且其值为y
位置的点。
var createTerrain = function(chops, range) {
chops = chops || 2;
range = parseInt(range || 100);
if (chops > 8) return;
var cycle = parseInt(width / chops);
for (var i = 0; i <= width; i += cycle) {
var y = (height / 2) + getRandomNumber(-range, range);
terrain[i] = y;
}
chops *= 2;
range *= 0.5;
createTerrain(chops, range);
}
getRandomNumber()
的参数是min
和max
。 width
和height
分别是canvas
。
这会产生类似......
看起来很不稳定,但这可能就是这样。
我有这个算法吗?如果没有,那有什么不对,你能指出我正确的方向吗?
答案 0 :(得分:11)
我认为它看起来不像中点位移,只是因为每个段都应该有一个规则的X轴长度(你有几乎垂直的段)。您是否尝试生成一个简单的4段数组?它看起来像什么?
这是我写的一个简短的教程,你可以看到它的实际应用:Mid-point algorithm in Javascript
源代码:
function Terrain(segmentCount) {
this.segmentCount = segmentCount;
this.points = [];
for (i=0; i<=segmentCount; ++i) {
this.points[i] = 0;
}
};
/**
* Generate the terrain using the mid-point displacement algorithm. This is in fact
* a shortcut to the recursive function with the appropriate value to start
* generating the terrain.
*
* @param maxElevation the maximal vertical displacement to apply at this iteration
* @param sharpness how much to attenuate maxElevation at each iteration (lower
* value means a smoother terrain). Keep between 0 and 1.
*/
Terrain.prototype.generateUsingMidPoint = function(maxElevation, sharpness) {
this.midPoint(0, this.segmentCount, maxElevation, sharpness);
}
/**
* This is the recursive function to actually generate the terrain. It computes a new height for the point
* between "start" and "end" (the mid-point): averages start and end heights and adds a random
* displacement.
*
* @param maxElevation the maximal vertical displacement to apply at this iteration
* @param sharpness how much to attenuate maxElevation at each iteration (lower
* value means a smoother terrain). Keep between 0 and 1.
*/
Terrain.prototype.midPoint = function(start, end, maxElevation, sharpness) {
var middle = Math.round((start + end) * 0.5);
if ((end-start<=1) || middle==start || middle==end) {
return;
}
var newAltitude = 0.5 * (this.points[end] + this.points[start]) + maxElevation*(1 - 2*Math.random());
this.points[middle] = newAltitude;
this.midPoint(start, middle, maxElevation*sharpness, sharpness);
this.midPoint(middle, end, maxElevation*sharpness, sharpness);
};
答案 1 :(得分:0)
从查看结果来看,您实施的算法显然是错误的。你出错的地方很难说,因为你发布的代码不是自包含的。您正在对父作用域中定义的几个变量进行操作,并且不会立即显示它们包含的内容或行为方式。
例如terrain
是什么?
首先要了解的是,如果起点和终点在y轴上不匹配,那么你做错了;)