noy 發表於 2025-7-13 13:46

弓箭遠戰會判定打不到怪

我是用 l1j 3.50 版本架設
可以改核心設定

最近從角色瞬移飛出場外
到怪物各種穿牆的問題都已經解決

但現在有個怪物跟角色在直線距離上確定無障礙物時會打不到的問題
具體來說是各類地城的牆壁邊緣或是轉角
甚至路邊的樹木倒木都可能發生
但在空曠處是不會有問題的
有時嚴重一點怪物旁邊有牆壁
即使我角色跟怪物貼在一起也會打不到怪
像是象牙塔這種直線牆壁走道的地圖就容易發生

站內有一篇是相同問題的文章
但是沒有解決方法
拿去問 chatgpt 得到的程式碼反而讓弓箭在空曠處完全打不中怪
初步感覺跟 L1Attack.java 的攻擊判定碼有關係
但實在不知怎麼下手

collared0wlet 發表於 2025-7-13 20:14

去看看L1AttackPc有沒有calcHit()//命中判定,然後配合以下程式碼檢查.

這段程式碼的目的是檢查從角色目前位置到指定目標座標之間的「直線路徑」是否通暢。如果路線中間有障礙物(例如牆壁或無法通過的地形),就會回傳 false,否則回傳 true。

/**
* 判斷從目前位置到指定座標的直線路徑上,是否**沒有障礙物**。
*
* @param tx 目標座標的 X 值
* @param ty 目標座標的 Y 值
* @return 如果路徑上沒有障礙物則回傳 true,否則回傳 false。
*/
public boolean glanceCheck(final int tx, final int ty) {
    final L1Map map = getMap(); // 取得角色所處地圖
    int chx = getX();         // 當前 X 座標
    int chy = getY();         // 當前 Y 座標

    for (int i = 0; i < 15; i++) {
      // 如果已到達目標點(或其周圍 8 格),則跳出迴圈
      if (((chx == tx) && (chy == ty)) || ((chx + 1 == tx) && (chy - 1 == ty)) || ((chx + 1 == tx) && (chy == ty))
                || ((chx + 1 == tx) && (chy + 1 == ty)) || ((chx == tx) && (chy + 1 == ty))
                || ((chx - 1 == tx) && (chy + 1 == ty)) || ((chx - 1 == tx) && (chy == ty))
                || ((chx - 1 == tx) && (chy - 1 == ty)) || ((chx == tx) && (chy - 1 == ty))) {
            break;

      } else {
            int th = targetDirection(tx, ty); // 取得目前朝向目標的方向
            // 如果此方向上無法通過(有障礙物),回傳 false
            if (!map.isArrowPassable(chx, chy, th)) {
                return false;
            }

            // 根據與目標點的相對位置,移動角色的座標
            if (chx < tx) {
                if (chy == ty) {
                  chx++;
                } else if (chy > ty) {
                  chx++;
                  chy--;
                } else if (chy < ty) {
                  chx++;
                  chy++;
                }
            } else if (chx == tx) {
                if (chy < ty) {
                  chy++;
                } else if (chy > ty) {
                  chy--;
                }
            } else if (chx > tx) {
                if (chy == ty) {
                  chx--;
                } else if (chy < ty) {
                  chx--;
                  chy++;
                } else if (chy > ty) {
                  chx--;
                  chy--;
                }
            }
      }
    }

    // 如果都沒遇到障礙物,回傳 true
    return true;
}

yasioukon 發表於 2025-7-13 14:29

遠攻障礙這種基本上無法一次性解決

畢竟他只能用地圖檔來判斷 無法像人類用眼睛看

所以可能必須手動將每個點分別下條件排除

但像面對面那種 可以直接下 距離1格無視障礙

noy 發表於 2025-7-13 16:43

yasioukon 發表於 2025-7-13 14:29
遠攻障礙這種基本上無法一次性解決

畢竟他只能用地圖檔來判斷 無法像人類用眼睛看


感謝

目前是針對 L1Attack.java 寫了個近距離不做障礙物判斷
運作起來是正常的
雖然這沒根本性解決問題

這個障礙物判定問題是每個版本都有嗎?

yasioukon 發表於 2025-7-13 19:05

用九宮格來說

789
456
123

面對面的情況 你人物是站在5往八個方向攻擊

但當你遠距離 例如你站在1往8射的時候

這時候是不是非直線了?

那到底要經4還經5穿過?

這時候 障礙物誤判 一般都是這種情況

攻城的時候 甚至有花園的地方最明顯

明明看到箭沒有射到障礙 卻無法命中

noy 發表於 2025-7-13 23:23

本帖最後由 noy 於 2025-7-13 23:25 編輯

collared0wlet 發表於 2025-7-13 20:14
去看看L1AttackPc有沒有calcHit()//命中判定,然後配合以下程式碼檢查.

這段程式碼的目的是檢查從角色目前 ...
非常感謝

這組程式碼體感上有改善目前的症狀
不過有時還是會在自己貼到牆邊但怪物旁邊沒牆壁時發生打不到的狀況
就是自身角色周圍 8 格中有貼到 1 格的牆壁或樹木
而怪物旁邊完全無障礙物且角色與怪物的射線上無障礙物
就會觸發打不到的狀況
頗像是攻擊判定會優先判斷角色周圍 8 格有沒有 1 格或以上的障礙物
一旦有障礙物就直接認定不會命中
而且這個問題不是每次都會發生
反倒讓問題更難捉摸

實務上變成我打帶跑的時候絕對不能讓角色貼到牆壁旁再反打
起碼要離牆壁 1 格的距離
這樣才比較不會觸發

collared0wlet 發表於 2025-7-14 13:17

建議你要把你那版本的客戶端地圖跟伺服器地圖比對,然後看是否對應會比較好

noy 發表於 2025-7-14 15:55

collared0wlet 發表於 2025-7-14 13:17
建議你要把你那版本的客戶端地圖跟伺服器地圖比對,然後看是否對應會比較好 ...


目前客戶端跟伺服器端都是 3.50
測試的地點是象牙塔 5 樓
之前因為該區用的是 3.52 的地圖造成怪物各種穿牆
已經把客戶端 3.50 的地圖匯出並貼上伺服器端了
所以現在兩端的象牙塔 5 樓地圖是一樣的

伺服器端原本抓下來就有 351 352 360 的壓縮檔
但是我不知道怎麼反過來把伺服器端的地圖匯入客戶端
不確定你說的比對是不是這樣子做?

頁: [1]
查看完整版本: 弓箭遠戰會判定打不到怪