2016-11-20 88 views
0

我正在研究基於文本的(控制檯)WW2策略遊戲,在2d方形網格地圖上設置。我想要一種方法來計算從地圖上的一個貼圖到另一個貼圖的視線。我用this Java示例立足我的代碼了,這是我寫的東西:Bresenham的線算法在PHP中

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; 
} 

注:getEmptyMap剛好充滿0的多維數組。

TestResult中使用(0,0,4,4,4)作爲輸入:

1100 
0110 
0011 
0001 

我試圖映射線的方式:一種是正常實現,弗朗茲D.使用(目前在我上面的示例中註釋掉了),另一個是Franz D.展示的修改後的實現。也沒有給我我想要的結果;一種「抗鋸齒」。當焊料從0.2,0.0,0,0,1和2,2的建築物看時,無論是在2,2處都應該被擋住。被註釋掉的實施將完全忽略建築物,修改「打」2,1但不是1,2。我將如何調整我的代碼,以在命令行和命令行之上「命中」?

+0

如果您認爲該算法最適合您的任務,那麼爲什麼不先嚐試一下,如果您還沒有使用過PHP,請先學習這個工具,然後將算法移植到PHP中 – Ghost

+0

我試過了並制定了一個實施,但我仍然遇到了一個問題(請參閱後編輯) – Somentus

回答

0

您正面臨的'問題'是由於特殊邊緣情況下看到的確切對角線。只有'兩種'(簡單)的可能性來處理這個問題:

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

祝你好運!

相關問題