C++实现中点位移算法生成类《焦土》坦克游戏高度图故障求助
问题修复方案
你的中点位移算法实现存在多个逻辑错误,按以下顺序修改即可得到预期效果:
核心错误修复点
- 递归区间逻辑错误
你当前递归调用时硬编码了左右边界为0和g_SCREEN_WIDTH-1,导致每次递归都在重复处理全屏幕范围,而非当前区间的子段。正确的递归调用应该处理当前传入的[left, right]区间的子段,同时删除代码中完全无用的left= mid / 2; right = mid + (mid / 2);两行,这两行会覆盖传入的区间参数,逻辑完全错误。
- 递归区间逻辑错误
- 随机偏移范围错误
你当前的随机偏移量只有正值(r取值范围为01),导致地形只会单向抬升/降低,没有自然起伏。需要修改随机值范围为-0.50.5,实现双向随机偏移。
- 随机偏移范围错误
- 粗糙度参数未生效
你整个算法中没有用到传入的roughness参数,中点位移的位移量衰减需要结合粗糙度控制,而非直接除以2。将位移衰减逻辑改为Displacement * roughness即可实现粗糙度控制:粗糙度越接近1,地形越崎岖;越接近0,地形越平滑。
- 粗糙度参数未生效
- 无用代码清理
你初始化代码末尾三行硬编码覆盖了之前随机生成的参数,如果需要随机地形效果,删除这三行即可:
- 无用代码清理
// 删除这三行 // Displacement = (g_SCREEN_HEIGHT/8); // roughness = 0.5; // itrations = 256;
- 坐标转换逻辑优化
你当前在计算y值的循环里就做了SDL坐标翻转,导致边界判断逻辑混乱,建议先计算出地形距离屏幕底部的高度,限制完合法范围后,最后统一翻转成SDL坐标。
- 坐标转换逻辑优化
- 递归终止条件优化
新增区间长度判断,当区间内没有中间点时直接终止递归,避免无效计算。
- 递归终止条件优化
完整修改后的函数参考
#include <algorithm> // 引入clamp需要的头文件 int func(double left, double right,std::vector<int> *points, double roughness, double segmnets, double Displacement, double itrations,int mountents,float range) { // 递归终止条件:区间无中间点、达到迭代次数上限 if (right - left <= 1 || segmnets > itrations - 1 || segmnets >= g_SCREEN_WIDTH) return 1; double mid = (left + right) / 2; if (mid <= 0 || mid >= g_SCREEN_WIDTH) return 1; // 计算中点高度 int y = ((points->at((int)left) + points->at((int)right)) / 2); float r = static_cast <float> (rand()) / static_cast <float> (RAND_MAX) - 0.5f; y += Displacement * r; // 限制高度范围,避免超出屏幕 y = std::clamp(y, 25, g_SCREEN_HEIGHT - 25); // 转换为SDL坐标系(y轴向下) int sdl_y = g_SCREEN_HEIGHT - y; points->at((int)mid) = sdl_y; // 递归处理左右子区间,位移量按粗糙度衰减 double new_displacement = Displacement * roughness; func(left, mid, points, roughness, segmnets * 2, new_displacement, itrations, mountents, range); func(mid, right, points, roughness, segmnets * 2, new_displacement, itrations, mountents, range); return 0; }
内容的提问来源于stack exchange,提问作者aharon80
相关产品推荐
相关产品推荐

