基于瓦片的Chebyshev距离效果异常问题排查与修复
问题原因分析
- Alpha值持续累积:代码中每次调用
tile.setAlpha(tile.alpha + ...)时,都是在瓦片当前透明度基础上叠加新值。随着游戏帧不断更新,透明度会持续增长超过1(完全不透明),最终导致所有瓦片异常明亮,无法呈现预期的区域效果。 - 双区域效果叠加错误:直接将两个区域的透明度贡献相加,会让重叠区域的透明度远超预期,破坏两个独立方形区域的视觉表现。
修复方案
需要重置每帧的透明度计算逻辑,避免累积,并合理合并两个区域的效果:
- 每帧重置透明度计算:不再基于瓦片当前透明度叠加,而是直接根据当前帧的距离计算新的透明度值。
- 合理合并双区域效果:对每个瓦片,分别计算两个原点带来的透明度,然后取两者的最大值(确保瓦片在任意一个区域内都能呈现对应透明度),或者将两者相加后限制在0-1范围内(让重叠区域更不透明)。
修正后的代码
function updateMap () { var origin = map.getTileAtWorldXY(player.x, player.y); var origin2 = map.getTileAtWorldXY(400, 400); // 提前判断原点是否有效,避免空引用错误 if (!origin || !origin2) return; map.forEachTile(function (tile) { // 计算玩家位置对应的瓦片透明度 var distPlayer = Phaser.Math.Distance.Chebyshev(origin.x, origin.y, tile.x, tile.y); var alphaPlayer = Math.max(0, 1 - 0.05 * distPlayer); // 确保透明度不低于0 // 计算固定位置(400,400)对应的瓦片透明度 var distFixed = Phaser.Math.Distance.Chebyshev(origin2.x, origin2.y, tile.x, tile.y); var alphaFixed = Math.max(0, 1 - 0.05 * distFixed); // 取两个透明度的最大值,呈现两个独立的方形区域 tile.setAlpha(Math.max(alphaPlayer, alphaFixed)); // 可选:如果希望重叠区域更不透明,可使用以下代码 // tile.setAlpha(Math.min(alphaPlayer + alphaFixed, 1)); }); }
补充说明
- 增加了原点有效性检查,防止玩家或固定位置超出地图范围时出现错误。
- 使用
Math.max(0, ...)确保透明度不会变成负数(当距离过远时,1 - 0.05*dist会小于0)。 - 两种合并方式可根据需求选择:取最大值保留两个独立区域的边界,相加则强化重叠区域的不透明度。
内容的提问来源于stack exchange,提问作者Vatsa Pandey
相关产品推荐
相关产品推荐

