iT邦幫忙

0

背包系統詳解

  • 分享至 

  • xImage
  •  
//裝備藥水:實現藥水單向(若裝備欄內沒藥水可直接裝備)、雙向置換(若裝備欄內已經有藥水,直接點擊新藥水會進行置換),

var x = document.getElementsByClassName('rpgui-icon empty-slot')
for(var j=0;j<=29;j++){
    var child = x[j].firstElementChild
    if(child!=null){
         child.addEventListener("click",function(){
            var Data = document.getElementById('potion_col')
            //裝備欄已有物品,做置換
            if(Data.firstElementChild!=null && this.parentNode!=Data){
                var x_copy = this
                x_copy.style['height']='100%';
                x_copy.style['width']='100%';
                var p = this.parentNode;
                this.remove();
                Data.firstElementChild.style['height']='13%';
                Data.firstElementChild.style['width']='13%';
                Data.append(x_copy);
                p.append(Data.firstElementChild)
            }
            //裝備欄沒有物品,直接裝備
            else{
                var x_copy = this
                this.remove();
                x_copy.style['height']='100%';
                x_copy.style['width']='100%';
                Data.append(x_copy);
            }
        })
    }
}


//解除藥水:可透過點擊下方藥水裝備欄返回藥水回倉庫,會自動找空格填入

var y = document.getElementById('potion_col')
y.addEventListener("click",function(){
    var y_copy=y.firstChild
    y_copy.style['height']='13%';
    y_copy.style['width']='13%';
    var Data = document.getElementsByClassName('rpgui-icon empty-slot')
     for(var i=0; i<=29;i++){
         if (Data[i].firstElementChild==null){
            Data[i].append(y_copy);
            break;
         }
     }
})

首先是要先分解背包系統他的運作邏輯會是長什麼樣:打開包包=>看見物品=>點選物品/直接裝備=>不喜歡並解除裝備

我首先設想了兩種狀況:裝備欄是空的,以及裝備欄不是空的

首先用document.getElementsByClassName選中30格欄位,並用FOR迴圈尋覽,然後想進行下一步時就出了第一個問題。

那就是直接在document.getElementsByClassName('rpgui-icon empty-slot')的後面接firstChild或著firstElementChild都會找不到人,看了網路上的說法,猜想是尋覽的當下並沒有將目標選中,因此他不知道firstChild是眾多欄位中的誰家孩子。

這裡的解法是另設變數child來先儲存所有欄位的firstChild,光是想出這一步我碰壁了幾個小時zzz(菜到不行)

接下來就簡單多了,用if判斷式確定選中的不是空欄位,並同樣用js選擇器找到裝備欄,然而接下來遇到隱形的怪物而不自知,你只要知道當時我的這行if(Data.firstElementChild!=null && this.parentNode!=Data)並沒有加上第二個條件就好了=>

病灶點:if(Data.firstElementChild!=null)

這裡的if...else當時想得很簡單,就是考量到裝備欄是否為空的,如果不是空的,那就做一個對調的動作,對調的具體流程是:
-先複製一個選中的裝備
-改變複製體的css屬性,讓他符合裝備欄的大小
-清除選中裝備
-改變裝備欄中既有裝備的css屬性,讓他符合背包的大小,同時完成複製
-用append將複製品對調

而空的就少了對調的過程,直接將修改css的複製體丟過去後自刪。

接著就是如果是直接點選裝備欄的物品,我設定是會返回背包,返回背包基本就是背包傳物品到空裝備欄的顛倒,只不過多了用for迴圈尋覽空的欄位。

一切都是那麼的自然,一切都是那麼的順利,我甚至在寫這個版本前還用寫死欄位參數的版本做了測試,側了N遍不會出問題的~

邪惡的BUG就在這時候打爆了我的狗腿TT

做測試的時候,背包與裝備欄的置換功能是OK的,但是如果是直接去點擊已有物品的裝備欄準備回收時,則裝備欄的物品會神奇的消失。

當時是認為一定是下面返回背包的程式碼有問體,不斷console.log找斷點,並重構了多次邏輯,但依然無法正常運作,y.fisrtChild傳回值一直是Null或Undefine。

中間一度想直接將返回背包功能包進裝備的迴圈內當上帝對象進行判斷,但是也出現了意料外的錯誤,後來也不知道是怎樣,靈光一閃的想到應該是**addEventListener()**的問題,因為既然能夠監聽並重複對調的行為,那移動到裝備欄內的物品應該也是有addEventListener()事件在作用的,所以才會按下去的瞬間被移除,因為監聽到了remove()事件。

這就是思考的盲點吧!即使盡量想用程式腦去想事情,當下一看到東西被轉移過去,且比較複雜的對調功能都運作正常,就下意識地認為裝備欄內的東西已經與背包的監聽事件脫鉤,因此我便在判斷Data.firstElementChild!=null的後面加了一條判斷父元素的條件,想通了一後,功能就恢復正常了,可喜可樂~
https://ithelp.ithome.com.tw/upload/images/20210730/20139997XiqxLH74RM.jpg


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言