【问题标题】:How to remove a child from a random array?如何从随机数组中删除一个孩子?
【发布时间】:2015-07-14 05:40:35
【问题描述】:

我有一个随机创建 10 个点的数组。但是,在某些区域我不希望创建它们。我怎样才能做到这一点?我的代码给了我错误 2025。

“提供的 DisplayObject 必须是调用者的子对象。”

它偶尔会按照指示输出 totalDots,(trace""+totalDots),但 90% 的时间它会给我错误。

public var numDots:Array = [];
public var totalDots:int = numDots.length;
public var box:Box = new Box();

public function addBox():void
{
     box.x = stageWidth/2;
     box.y = stageHeight/2;
     addChild(box);
}
private function addDot():void
{
    for(var i:int = 0; i < 10; i++)
    {
        var dot:Dot = new Dot();
        dot.x = Math.floor(Math.random() * stageWidth);
        dot.y = Math.floor(Math.random() * stageHeight);
        this.addChild(dot);
        totalDots++;
        trace(""+totalDots);

        for(var j:int = 0; j < totalDots; j++)
        {
            if(numDots[j].hitTestObject(box))
            {
                stage.removeChild(numDots[j]);
                numDots.splice(j, 1);
                totalDots--;
            }
        }
    }

}

【问题讨论】:

  • 这个盒子只是一个普通的矩形吗?
  • 现在,作为占位符。它稍后会变成稍微复杂的形状。

标签: arrays actionscript-3 flash random actionscript


【解决方案1】:

你的问题是你的嵌套循环。在每次迭代中,您添加一个新点,然后遍历所有现有的点,如果它与框碰撞,则将其删除。我不认为那是你打算做的。

看起来您只是想确保在某个区域内没有添加点。在这种情况下,使用 do while 循环保持简单:

for(var i:int = 0; i < 10; i++)
{
    var dot:Dot = new Dot();
    this.addChild(dot);
    do {
        dot.x = Math.floor(Math.random() * stageWidth);
        dot.y = Math.floor(Math.random() * stageHeight);
    } while(dot.hitTestObject(box))
    totalDots++;
    trace(""+totalDots);
}

【讨论】:

  • 感谢您的建议,但盒子上的点仍在创建中。我还应该注意,这些点将在随机方向移动。
  • @null 我错过了什么吗? while 循环应该强制点的位置在它与盒子碰撞时改变。
  • @Matt 我刚刚测试了我的代码,它对我有用...点和框永远不会冲突。
  • @Karma duuuh,对不起,我太快得出错误的结论。你是对的。
  • @karma 我将 addDot() 函数从主 Document Class 函数移动到 ENTER_FRAME 函数,它可以工作,尽管它不断重复,在屏幕上放置了无限数量的点。你能解释一下为什么它不能在主文档类函数中吗?
【解决方案2】:

您永远不会在数组中添加任何点。

您将点添加到显示列表中,如下所示:

this.addChild(dot);

然后您尝试像这样删除它:

stage.removeChild(numDots[j]);

尽管点从未添加到数组中,但即使添加了也无法正常工作。那是因为this 不是stage。它们是两种不同的东西。

您应该从不使用stage.addChild()(查看文档以获取更多信息)。只需一直调用addChild(),就相当于this.addChild()。这可确保您始终在同一个 DisplayObjectContainer 上操作

【讨论】:

    【解决方案3】:

    对于它的价值,您可以通过计算具有适当间隔(包含和排除区域之间的差异)的随机值并从中导出 xy 坐标来完全避免试验循环。

    以下代码(用我不知道的语言编写,如果语法错误,请致歉)有两种情况。 if 案例处理点将出现在排除框左侧或右侧的情况,x 值的范围仅限于该框的左侧或右侧。 else 的情况是点将出现在框的上方或下方,x 的值不受限制。

    var interval:int = stageWidth * stageHeight - box.w * box.h;
    var cut:int = interval - (stageWidth - box.w) * box.h;
    for (var i:int = 0; i < 10; i++) {
        var r:int = Math.floor(Math.random() * interval);
        var x:int;
        var y:int;
        if (r >= cut) {
            r -= cut;
            y = r / (stageWidth - box.w);
            x = r - y * (stageWidth - box.w);
            y += box.y;
            if (x >= box.x) x += box.w;
        } else {
            y = r / stageWidth;
            x = r - y * stageWidth;
            if (y >= box.y) y += box.h;
        }
        var dot:Dot = new Dot();
        dot.x = x;
        dot.y = y;
        this.addChild(dot);
        totalDots++;
        trace(""+totalDots);
    }
    

    这假定box 完全在stageWidth,stageHeight 内。

    另外值得注意的是它允许点重叠;与原始代码相同。

    对于更复杂的形状,您可以将box 设置为由该形状完全包围的最大矩形,以避免许多但不是所有重试情况。这对于大形状和许多点很有帮助。或者有一些变化可能会完美契合其他形状(例如椭圆)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-05
      • 2020-09-18
      • 2018-08-19
      • 1970-01-01
      • 2021-04-12
      • 2019-02-18
      • 2015-05-05
      • 1970-01-01
      相关资源
      最近更新 更多