1

我正在用 JavaScript 制作一个 2D、自上而下的塞尔达风格网络 rpg 单人游戏。

当玩家(紫色衬衫)走近一只猫时,它会“拯救”它......这基本上从舞台上删除animalContainerContainerOfAnimals(从而从舞台上删除了animalContainer的BMP),然后将那个animalContainer的id添加到rescuedTotal_Array......

奇怪的是,在下面的图片中,我能够救援animalContainer2然后救援......但如果我从to ,它抛出一个animalContainer1animalContainer1animalContainer2

Uncaught TypeError: Cannot read property 'id' of undefined` error. 

... 基本上:

工作方式:获取 ID 22,然后到 ID 21 ->>> 我注意到的一件事是 ID 的元素名称不会改变......不知道为什么......所以对于破碎的方式...... . 它甚至可能无法将元素名称animalContainer2与 ID 相关联?但我不知道 ID 和名称是如何像这样解除关联的..

ID in rescued array...: 22, element name: animalContainer1, rescued array length: 2, elem index pos: 0, index: 0

ID in rescued array...: 21, element name: animalContainer1, rescued array length: 2, elem index pos: 1, index: 0 

Broken way - 抛出错误:获取 ID 21,然后下降到 ID 22

ID in rescued array...: 21, element name: animalContainer1, rescued array length: 1, elem index pos: 0, index: 0 

1. Uncaught TypeError: Cannot read property 'id' of undefined 

在此处输入图像描述

代码片段:

        function grabIt(NPC_id, index) {
            //check if NPCid already exists in array before adding...
            if ($.inArray(ContainerOfAnimals.children[index].id, rescuedTotal_Array) == -1) {
                rescuedTotal_Array.push(ContainerOfAnimals.children[index].id);
            }
            if (rescuedTotal_Array.length == 2) {
                for (var z = 0; z < rescuedTotal_Array.length; z++) {
                    console.log("ID in rescued array...: " + rescuedTotal_Array[z] + ", \n element name: " + ContainerOfAnimals.children[index].name + ", rescued array length: " + rescuedTotal_Array.length + ",\n elem index pos: " + z + ",\n index: " + index);
                }
            }
            //when I remove the first added element to rescuedTotalArray... the 2nd element's index assumes first added element's index... (goes from 1 to 0)
            console.log(index);
            console.log("element removed: " + ContainerOfAnimals.children[index]);
            stage.update();
            ContainerOfAnimals.removeChild(ContainerOfAnimals.children[index]);
            updateHUD();
        }

我不知道为什么我在数组中存储元素/从舞台上删除它们的顺序很重要......


编辑:我觉得我可以通过按元素 ID 而不是按索引从 ContainerOfAnimals 中删除元素来解决这个问题……容器对象不提供任何getChildID()功能……

所以我尝试了:

    var childToRemove = document.getElementById(ContainerOfAnimals.children[index]);
    console.log(childToRemove);
    ContainerOfAnimals.removeChild(childToRemove);

console.log(childToRemove) 给我null的孩子

但是这样做:console.log(ContainerOfAnimals.children[index].id);给我 id 21,这是正确的 id ...

4

4 回答 4

1

您可能rescuedTotal_Array是一个关联数组(或已变形为一个),并且可能包含以下内容:

rescuedTotal_Array = [1:object,2:object,object:object]

上面的数组长度为 3。但是您不能通过索引 2 访问第三个元素,因为它的索引是某种对象。

rescuedTotal_Array在访问之前尝试转储您的内容(这样您就可以查看是否一切正常)。这不是一个解决方案,但它可以帮助您,以便您自己找到错误。使用类似的东西

for (index in rescuedTotal_Array) {
    if (rescuedTotal_Array.hasOwnProperty(index)) {
        console.log(rescuedTotal_Array[index]);
    }
    else {
        console.log("no entry found for index: "+index);
    }
}
于 2013-08-15T14:56:12.843 回答
1

如果是这种情况,我不完全确定(如果不查看您的整个程序,我就无法知道),但可能是这样的:

我假设您的“ContainerOfAnimals”是一个 HTML 元素,并且您正在使用它的 .children -property 检索它的子节点。问题是 .children -property 返回一个“实时列表”

让我演示一下:

var children = ContainerOfAnimals.children;
console.log(children.length) // 2;

ContainerOfAnimals.removeChild(children[0]);
console.log(children.length) // 1;

假设您删除了 ContainerOfAnimals 的第一个孩子。发生什么了?子列表现在已经改变,第二个元素变成了第一个元素,第三个元素变成了第二个元素等等......

您可以通过使用包含所有子项的静态数组来解决此问题,如下所示:

var children = [].slice.call(ContainerOfAnimals.children);
console.log(children.length) // 2;

ContainerOfAnimals.removeChild(children[0]);
console.log(children.length) // 2;

现在从 DOM 树中删除元素不会从子数组中删除元素(这是静态的)。请记住,[].slice.call 在 IE8 或更低版本中不起作用。

让我知道这是否是问题所在。我没有足够的评论点,所以我不得不发表一个完整的帖子:)

于 2013-08-15T15:28:19.837 回答
1

请注意 EaselJS 元素不是 DOM 元素。

假设你想通过它的 id 删除一个元素,我建议这样做:

function removeElementById(container, id) {
   for (var i=container.getNumChildren(); i-->0;) {
       if (container.getChildAt(i).id===id) {
            container.removeChildAt(i);
            return true;
       }
   }
   return false;
}

但是使用 id 可能不是最好的架构解决方案。在我的 EaselJS 程序中,我保留了对对象本身的引用,这样我就不必搜索它们了。

于 2013-08-15T17:03:53.690 回答
-1

嗨,

尝试这样的声明:

for(var z = rescuedTotal_Array.length; z >= 0; z-- )

如果你注意到我只是把它转过来。它从 the 开始,然后倒退。这很愚蠢,但是,也许这个错误就是这样:)

让我知道事情的后续!

问候

于 2013-08-15T14:33:15.207 回答