2010-08-31 95 views
7

所以我正在用HTML5和Javascript製作塔防遊戲。我唯一的問題是檢測鼠標何時與攻擊者的路徑接觸,這是阻止玩家在路徑上建造塔樓所必需的。攻擊者的路徑在MAP.js文件中(參見底部的鏈接)由一個二維數組(一個包含x和y對的數組)確定,所以我需要處理的是一系列點連接時組成一條路徑。我只是想禁止玩家將塔放置在路徑的50個像素內。說實話,我只是碰撞檢測很糟糕,所以一些幫助將不勝感激。HTML5畫布:鼠標和多邊形碰撞檢測

這裏是鏈接到所有代碼: http://shapeshifting.comuv.com/Tower_Defense/td/

正如你可能想象,只有.js文件都適用,但大多數相關的代碼是objects.js文件中。 (請原諒雜亂)

回答

2

我會逐步接近這一點。讓我們看看你的開始。你有一個由點定義的路徑 - 點對定義了一個線段。所以你真正擁有的是由線段組成的路徑。當用戶移動鼠標時,你會得到當前位置的x,y座標。你想要做的是找到鼠標點到所有線段的距離。如果它距任何線段小於50像素,那麼您不想讓它們在那裏建立。

要找到一個點和線段之間的距離,僞代碼如下所示。假設點A和點B代表線段的兩端,點C是鼠標點。

float distancePoint2LineSegment(Point a, Point b, Point c) { 
    Vector ab = b - a 
    Vector ac = c - a 
    Vector bc = c - b 

    float e = dotProduct(ac, ab) 
    if (e <= 0.0) 
    return sqrt(dotProduct(ac, ac)) 

    float f = dotProduct(ab, ab) 
    if (e >= f) 
    return sqrt(dotProduct(bc, bc)) 

    return sqrt(dotProduct(ac, ac) - e * e/f) 
} 

這會回答你的碰撞檢測問題,但我想你會想看看性能。您的路徑中將有多少線段,並且您想要在每次用戶移動鼠標時計算到每個線段的距離?您可以將線段放入四叉樹中,以便您只需對較少數量的線段測試鼠標點碰撞。

3

碰撞檢測是那些老的一個,隱藏編碼遊戲的問題通常人們會選擇darkpenguin以某種方式預先計算你的靜態地圖上的哪些位置是不可放置的。下一步是想出一種方法來指定最有效的碰撞圖。

你不希望你的遊戲做一噸的數學響應用戶移動他們的鼠標 - 它需要短而快 - 所以預先計算下來的東西快是至關重要的。

如果您的地圖是一個網格,那麼你有你的答案就在那裏 - 碰撞地圖是預先計算的二維數組 - 基本上與網格上的每一個地方一個像素很小的黑白圖像。白色像素(1)可放置,黑色像素(0)不可放置。您只需使用這個真/假的二維數組作爲查找。如果您想節省內存,您可以將網格上的每個32位空格分隔成單個位標誌。

如果你的地圖不是網格,那麼你仍然想要預先計算的東西,但是這個策略有點複雜。第一種可能性是像Hitesh那樣執行數學運算以生成稍微更高分辨率的碰撞圖,其餘部分與網格策略完全相同 - 例如,如果每個4x4像素塊都是一個碰撞入口,那麼塔是否可以是放置是一個測試,以確定它的座標是否在1以上 - 你可能需要100%的測試爲1,或者你可以讓它們達到一點,讓75%的測試爲1。

如果這還不夠詳細,您可以做這些更復雜的多邊形測試,但您希望它們儘可能簡單。當不使用預先計算好的網格時,最簡單的2D碰撞測試是2個圓圈 - 您只需計算它們中心之間的距離並檢查它們大於還是小於它們的半徑之和。如果您預先將您的怪物路徑預先計算爲一系列圓圈,那麼下一步就是將這些圓圈分成......猜猜看......網格。這可以防止每次檢查都必須測試地圖上的每個圓圈。這使得您可以在碰撞圖中包含大量的這些圓,因爲碰撞測試首先查找塔目前正在結束的網格輸入,然後檢查它是否與最接近的圓相碰撞,而不是整個地圖。請注意,此預先計算的圓形列表網格在多個相鄰網格條目中通常會具有相同的圓形,因爲包含給定圓形的任何部分的每個網格條目都必須在其碰撞檢查清單中包含該圓形。

關於前兩種網格方法的好處之一是它很容易進行QA測試 - 從字面上將碰撞圖存儲爲圖像並進行視覺檢查,以確保它看起來適合它所基於的地圖。如果您不想編寫代碼來生成它們,也可以手動繪製它。

圓形方法爲您提供了合法的曲線,並可以導致更細微的碰撞邊緣細節,但它顯然更難以測試並確保沒有地圖具有不良碰撞貼圖。編寫地圖生成工具也是更多的工作。

祝你好運!