背包系统详解

//装备药水:实现药水单向(若装备栏内没药水可直接装备)、双向置换(若装备栏内已经有药水,直接点击新药水会进行置换),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的后面加了一条判断父元素的条件,想通了一后,功能就恢复正常了,可喜可乐~
http://img2.58codes.com/2024/20139997XiqxLH74RM.jpg


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章