我很困惑为什么我的代码说这个,
我的游戏会创建一个程序生成的地图,地图会分成几个部分。地图工作正常,我可以切换区域和东西没有问题但是当我删除树图块并重新添加草图块然后尝试切换它告诉我的区域"提供的DisplayObject必须是调用者的子代。 " Iv gottn并且修复和轻微了解这个问题,但我觉得它好像是一个calleer的孩子。 idk:c
我的代码是如何设置的,它在我的关卡类中创建了一个世界类,然后在那个世界中创建了一个worldTiles精灵来放置世界的瓦片。这是最初添加和删除切片的位置
这就是我非常确定我的问题所在,删除树砖并添加草砖的功能
protected function mouseOnTile()
{
for (var i:int; i < world.tilesInWorld.length; i++)
{
if (mouse.hitTestObject(world.tilesInWorld[i]))
{
trace(world.tilesInWorld[i].Name);
if (world.tilesInWorld[i].Name == "tree")
{
var tx:int = world.tilesInWorld[i].x;
var ty:int = world.tilesInWorld[i].y;
world.worldTiles.removeChild(world.tilesInWorld[i]);
world.treePool.returnSprite(world.tilesInWorld[i]);
world.tilesInWorld.pop();
world.tile = world.tilePool.getSprite();
world.tile.width = world.TILE_SIZE;
world.tile.height = world.TILE_SIZE;
world.tile.x = tx;
world.tile.y = ty;
world.tilesInWorld.push(world.tile);
world.worldTiles.addChild(world.tile);
}
}
}
}
我确定它与如何将草砖重新添加到worldTiles中有关,但我对如何做到这一点感到困惑?
这是在您走到其他屏幕区域时删除图块的功能
public function deleteTiles()
{
if (tilesInWorld.length > 0)
{
for (var i:int = tilesInWorld.length - 1; i >= 0; i--)
{
worldTiles.removeChild(tilesInWorld[i]);
switch (tilesInWorld[i].Name)
{
case "water" :
waterPool.returnSprite(tilesInWorld[i]);
break;
case "shallow" :
shallowPool.returnSprite(tilesInWorld[i]);
break;
case "shell" :
shellPool.returnSprite(tilesInWorld[i]);
break;
case "sand" :
sandPool.returnSprite(tilesInWorld[i]);
break;
case "tree" :
treePool.returnSprite(tilesInWorld[i]);
break;
case "grass" :
tilePool.returnSprite(tilesInWorld[i]);
break;
case "rock" :
rockPool.returnSprite(tilesInWorld[i]);
break;
case "stone" :
stonePool.returnSprite(tilesInWorld[i]);
break;
}
}
tilesInWorld.length = 0;//empty array
generateTile();
}
}
这是删除后在屏幕上生成图块的位置
public function generateTile()
{
var Xcalc:int = (X + (800 / TILE_SIZE) / GlobalCode.MAP_SCALE);
var Ycalc:int = (Y + (600 / TILE_SIZE) / GlobalCode.MAP_SCALE);
for (var i:int = X; i < Xcalc; i++)
{
for (var j:int = Y; j < Ycalc; j++)
{
hm = heightmap[i][j];
if ((hm >= 0.84))
{
tile = waterPool.getSprite();
}
else if (((hm >= 0.8) && hm < 0.84))
{
tile = shallowPool.getSprite();
}
else if (((hm >= 0.79) && hm < 0.799))
{
tile = shellPool.getSprite();
}
else if (((hm >= 0.7) && hm < 0.8))
{
tile = sandPool.getSprite();
}
else if (((hm >= 0.35) && hm < 0.4))
{
tile = treePool.getSprite();
}
else if (((hm >= 0.2) && hm < 0.7))
{
tile = tilePool.getSprite();
}
else if (((hm >= 0.09) && hm < 0.2))
{
tile = stonePool.getSprite();
}
else
{
tile = rockPool.getSprite();
}
tile.width = TILE_SIZE;
tile.height = TILE_SIZE;
worldTiles.x = 0;
worldTiles.y = 0;
tile.x = TILE_SIZE * (i % 800);
tile.y = TILE_SIZE * (j % 600);
tilesInWorld.push(tile);
worldTiles.addChild(tile);
}
}
}
答案 0 :(得分:5)
我相信你的问题在这里:
for (var i:int; i < world.tilesInWorld.length; i++)
{
...
world.worldTiles.removeChild(world.tilesInWorld[i]);
world.treePool.returnSprite(world.tilesInWorld[i]);
world.tilesInWorld.pop();
...
}
你正在通过数组前进,在数组中的元素上使用removeChild
,并使用“pop”删除数组的最后一项,而不是实际删除的项。您最终将击中已删除的项目。此外,每次i
时,pop
指针都会发生变化,这意味着循环永远不会触及每个项目,并且存在根本缺陷。
DisplayObject
中用作参数的dO.removeChild()
必须定义,非空,且dO
的子项(即添加dO.addChild()
如果它不符合这些要求的全部,则会出错。
要解决此问题,请使用splice()
代替pop()
(这将允许您删除数组中的特定元素)并向后遍历数组(将处理i
指针问题)
for (var i:int = world.tilesInWorld.length - 1; i >= 0; --i)
{
...
world.worldTiles.removeChild(world.tilesInWorld[i]);
world.treePool.returnSprite(world.tilesInWorld[i]);
world.tilesInWorld.splice(i, 1);
...
}
您也可以循环遍历数组,但需要修改指针。这比后退更慢,更容易出错,但也可以正常工作(当我说速度较慢时,除非你进行大量的计算,否则我们说的是微秒差异。)
for (var i:int; i < world.tilesInWorld.length; i++)
{
...
world.worldTiles.removeChild(world.tilesInWorld[i]);
world.treePool.returnSprite(world.tilesInWorld[i]);
world.tilesInWorld.splice(i, 1);
--i;
...
}
此外,这只是一种语法/可读性问题,您不应该依赖数据类型的默认值。 int
默认为0,但您仍应将其声明为var i:int = 0
,以便日后更改,标准化且易于阅读,以便您可以轻松将其更改为{{ 1}},其最大值比int高得多,但默认为Number
。
答案 1 :(得分:0)
这没有任何意义。由于您要从数组中删除所有元素,因此您可以忘记pop或slice并执行
world.tilesInWorld.length = 0;
循环后。
因为你要从world.worldTiles中删除所有对象,所以不要一个一个地删除它们并执行:
world.worldTiles.removeChildren()
循环后。
最后,你只剩下一个简单的循环:
world.treePool.returnSprite(world.tilesInWorld[i]);
这是一个案例(在你的情况下和给出的答案中)你们都非常努力地使一个简单的代码变得尽可能复杂。