背包系统详解

//装备药水:实现药水单向(若装备栏内没药水可直接装备)、双向置换(若装备栏内已经有药水,直接点击新药水会进行置换),

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


<<:  Seattle Web Design Agency

>>:  Best Web Hosting Affiliate Program

@Day23 | C# WixToolset + WPF 帅到不行的安装包 [87分帅的WPF外观]

要 厉害的WPF安装画面, 除了凭空想像外, 我们来看别人怎麽弄得 WixToolset 的 安装画...

Day-04 如何将APP安装到手机上

在昨天的内容我们认识了Android模拟器,模拟器固然方便,但是或许会碰上模拟器可执行、而装置却不支...

DAY9:元件与监听事件简介及实作

我们要来介绍到元件与监听事件,首先,先从取得画面元件说起,简单来说,Android主程序码跟画面的x...

Day32 ( 电子元件 ) 全彩 LED 光线变化 ( 共阳极 )

全彩 LED 光线变化 ( 共阳极 ) 教学原文参考:全彩 LED 光线变化 ( 共阳极 ) 全彩 ...

IT 铁人赛 k8s 入门30天 -- day22 k8s 资源管理工具 kustomize

前言 文件参考来源: https://kubernetes.io/docs/tasks/manage...