我正在开发基于文本的(控制台)WW2策略游戏,设置在2d方格网格地图上。我想要一种方法来计算从地图上的一个图块到另一个图块的视线。我已经使用this Java示例来解决我的代码问题,这就是我所写的:
\"
注意:getEmptyMap只用0&#39填充多维数组。
Testresult使用(0,0,4,4,4)作为输入:
public function plotLine($x0, $y0, $x1, $y1, $size)
{
$arr = $this->getEmptyMap($size);
$xDist = abs($x1 - $x0);
$yDist = -abs($y1 - $y0);
if($x0 < $x1) {
$xStep = 1;
} else {
$xStep = -1;
}
if($y0 < $y1) {
$yStep = 1;
} else {
$yStep = -1;
}
$plotError = $xDist + $yDist;
$arr[$x0][$y0] = 1;
while($x0 != $x1 || $y0 != $y1) {
// if(2 * $plotError > $yDist) {
// // Horizontal step
// $plotError += $yDist;
// $x0 += $xStep;
// }
// if(2 * $plotError < $xDist) {
// // Vertical step
// $plotError += $xDist;
// $y0 += $yStep;
// }
if(2 * $plotError - $yDist > $xDist - 2 * $plotError) {
// Horizontal step
$plotError += $yDist;
$x0 += $xStep;
} else {
// Vertical step
$plotError += $xDist;
$y0 += $yStep;
}
$arr[$x0][$y0] = 1;
}
$this->line = $arr;
}
我尝试过绘制线的方法:一个是Franz D.使用的常规实现(目前在上面的示例中已经注释掉),另一个是Franz D.所展示的修改后的实现。也没有给我我想要的结果;一种&#34;抗锯齿&#34;。当焊料看起来从0,0,2,2和1,2和2,1处的建筑物时,2,2处的任何东西都应该被阻挡。注释掉的实施将完全忽略建筑物,修改确实会打击&#34; 2,1但不是1,2。如何将我的代码调整为&#34; hit&#34;在线下方和线上方?
答案 0 :(得分:1)
您遇到的'问题'是因为在查看精确对角线时出现特殊边缘情况。处理这个问题只有两个(简单)的可能性:
1)对角线同时增加水平和垂直平铺。在你的游戏中,这意味着即使主要方向被阻挡,单位也能够看到对角线。
2)选择优先考虑水平图块或垂直图块,只增加两者之一。这是Franz D.的算法,你最后写了并放在你的帖子里。这里,if
- 语句对于对角线是正确的,这意味着结果将是:
1100
0110
0011
0001
如果您希望竖线具有优先权,可以将其更改为:
...
if(2 * $plotError - $yDist < $xDist - 2 * $plotError) {
// Vertical step
$plotError += $xDist;
$y0 += $yStep;
} else {
// Horizontal step
$plotError += $yDist;
$x0 += $xStep;
}
...
请注意,if / else的两个主体都已交换,>
在条件中已更改为<
。
现在,结果将是:
1000
1100
0110
0011
如果你想让一个单位只能看到对角线,如果没有任何障碍阻挡相邻的红衣主教,那么最简单的解决办法就是使用上述两种算法,并将他们的结果合并为一个瓦片阵列。
最后一点说明:如果您只对坐标感兴趣而不是对它们的值感兴趣(就像您描述的用例的情况一样),使用简单的提取数组可能会更有效(内存) (x, y)
坐标代替完整地图的二维数组,然后将其循环以提取结果为(x, y)
的所有1
坐标。
祝你好运!