使用Flash AS3删除一个电影剪辑并重新定位其余电影剪辑。

3
我想在运行时删除一个或多个对象。
每次删除影片剪辑后,其他影片剪辑应该按以下方式重新定位(代表性图像中删除的影片剪辑为4)。
影片剪辑可以更多。
谢谢你现在的帮助。
6个回答

6
尝试类似以下的内容:
var top:int = 0;
for (var i:int=0;i<numChildren;i++) {
    var child:Sprite=getChildAt(i);
    child.y = top;
    top += child.height;
}

为解释做出修改

假设你想在点击影片剪辑时将其删除。在你的主文档类中,你可能会有这样的代码(假设所有实例都存在于第一帧,并且没有其他内容):

//constructor
public function MainDocumentClass() {
   for (var i:int; i<numChildren; i++) {
     var child:Sprite = getChildAt(i) as Sprite;
     child.addEventListener(MouseEvent.Click, deleteMe);
   }
}

protected function deleteMe(e:MouseEvent):void {
    var child:Sprite = e.currentTarget as Sprite;
    child.removeEventListener(MouseEvent.Click, deleteMe);
    rearrange();
}

protected function rearrange():void {
   var top:int = 0; 
   for (var i:int=0;i<numChildren;i++) {     
       var child:Sprite=getChildAt(i);     
       child.y = top;     
       top += child.height; 
    }   
}

非常感谢,但我需要更多的解释。因为我对AS3不是很熟悉。 - Kerberos

3
你可以创建一个自定义的DisplayObjectContainer类,并覆盖addChild()addChildAt()removeChild()removeChildAt()方法,以便它们不仅添加或删除显示对象,还重新排列所有子显示对象的位置。我做了一个示例来演示这个过程:
package 
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.text.TextField;

    public class Main extends Sprite 
    {
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);

        }// end function

        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);

            var vGroup:VGroup = new VGroup();
            var blocks:Vector.<Sprite> = new Vector.<Sprite>();

            for (var i:uint = 0; i < 5; i++)
            {
                blocks.push(getBlock(i + 1, 100, 100));
                vGroup.addChild(blocks[i]);

            }// end for

            addChild(vGroup);

            vGroup.removeChild(blocks[3]);
            vGroup.removeChildAt(0);
            vGroup.addChildAt(getBlock(6, 100, 100),1);

        }// end function

        private function getBlock(id:int, width:Number, height:Number):Sprite
        {
            var sprite:Sprite = new Sprite();
            sprite.graphics.lineStyle(1, 0x000000);
            sprite.graphics.beginFill(0xFFFF00);
            sprite.graphics.drawRect(0, 0, width, height);
            sprite.graphics.endFill();

            var textField:TextField = new TextField();
            textField.text = id.toString();
            sprite.addChild(textField);
            return sprite;

        }// end function

    }// end class

}// end package

import flash.display.DisplayObject;
import flash.display.Sprite;

internal class VGroup extends Sprite
{
    override public function addChild(child:DisplayObject):DisplayObject
    {
        var displayobject:DisplayObject = super.addChild(child);

        arrange();

        return displayobject;

    }// end function

    override public function addChildAt(child:DisplayObject, 
                                        index:int):DisplayObject
    {
        var displayobject:DisplayObject = super.addChildAt(child, index);

        arrange();

        return displayobject;

    }// end function

    override public function removeChild(child:DisplayObject):DisplayObject
    {
        var displayobject:DisplayObject = super.removeChild(child);

        arrange();

        return displayobject;

    }// end function

    override public function removeChildAt(index:int):DisplayObject
    {
        var displayobject:DisplayObject = super.removeChildAt(index);

        arrange();

        return displayobject;

    }// end function

    private function arrange():void
    {
        if (numChildren > 0)
        {
            for (var i:uint = 0; i < numChildren; i++)
            {
                getChildAt(i).y = (i > 0) ? getChildAt(i - 1).y + getChildAt(i - 1).height : 0;

            }// end for

        }// end if

    }// end function

}// end class

[更新]

下面代码的每一行:

vGroup.removeChild(blocks[3]); // removes block 4
vGroup.removeChildAt(0); // removes block 1
vGroup.addChildAt(getBlock(6, 100, 100),1); // adds block 6

生成以下相应的输出(除了初始输出之外):

enter image description here


2

如果我们假设这些电影剪辑被添加到它们自己的容器中(就是一个只包含这些电影剪辑的容器),并且它们是顺序添加的,那么这就很容易了。

container.removeChild(someMC);
for(var i:int = 0; i < container.numChildren; i++) {
    if(i == 0) {
        //this is the first, so position at 0
        container.getChildAt(i).y = 0;
    } else {
        //position based on previous child
        var prev:DisplayObject = container.getChildAt(i-1);
        container.getChildAt(i).y = prev.y + prev.height;
    }
}

这里的解释也适用于艾米的解决方案,她的更整洁些。 - shanethehat

2
var stack:Array = [];

function render():void {
  while(this.numChildren) this.removeChildAt(0); // removes all existing children
  for(var i = 0; i < stack.length; ++i) {
    var c = stack[i];
    c.y = this.height;
    this.addChild(c);
  }
}

stack.push(num1);
stack.push(num2);
stack.push(num3);
render();

stack.splice(1,1); // removes the second item from [stack]
render();

已经有很多好的例子了,我只想再添加一个简短的。享受吧。


1

你不需要重新定位所有东西。从上一个索引开始。

编辑:我根据艾米的帖子逻辑添加了点击处理程序逻辑。

//constructor
public function MainDocumentClass() 
{
    for (var i:int; i<numChildren; i++) 
    {
        var child:DisplayObject = getChildAt(i) as DisplayObject ;
        child.addEventListener(MouseEvent.Click, deleteMe);
   }
}

//click handler
protected function deleteMe(e:MouseEvent):void 
{
    //generic line to remove a listener
    IEventDispatcher(event.target).removeEventListener(event.type, arguments.callee);

    var pos:int = container.getChildIndex(e.target as DisplayObject);

    if(pos<0)
        return;

    container.removeChildAt(pos);
    rearrange(pos);
}

protected function rearrange(pos:int = 0):void
{
    for(; pos< container.numChildren; pos++) 
    {
        if(pos == 0) 
        {
            //this is the first, so position at 0
            container.getChildAt(pos).y = 0;
        } 
        else 
        {
            //position based on previous child
            var prev:DisplayObject = container.getChildAt(pos-1);
            container.getChildAt(pos).y = prev.y + prev.height;
        }
    }
}

非常感谢。还有一个问题,我如何使用您建议的帖子一次添加每个MC的点击事件? - Kerberos

0
var count:Number = 0;
var mc:Sprite;
var i:uint;
var pattern:RegExp = /\d+/;
btn_mc.addEventListener(MouseEvent.CLICK, action);
container_mc.addEventListener(MouseEvent.CLICK, action);
function action(e:MouseEvent):void 
{
    var str:String = e.target.name;
    if(str == "btn_mc")
    {
        mc = new Sprite();
        mc.graphics.beginFill(Math.random() * 0xffff00,1);
        mc.graphics.drawRect(0,0,20,20);
        mc.graphics.endFill();
        mc.buttonMode = true;
        container_mc.addChild(mc);
            mc.y = mc.width * count * 1.1;
        mc.name = "item" + count;
        count++;
        mc.addEventListener(MouseEvent.CLICK, action0);
    }
}
function action0 (e:MouseEvent):void 
{
    container_mc.removeChild(container_mc.getChildByName(e.target.name));
    var no:Number = e.target.name.match(pattern);
    var diff:Number = count - no;
    for( i = no+1; i< no+diff; i++)
    {
        container_mc.getChildByName("item"+i).y -= mc.width * 1.1;
    }
    count --;
    for(i = 0; i< container_mc.numChildren - 1; i++)
    {
        mc.name = "";
        container_mc.getChildAt(i+1).name = "item"+i;
    }
    trace(container_mc.numChildren);
}

您需要在舞台上创建 container_mc 和 btn_mc。


请不要将问题标记为[flash-cs5],除非从问题中清楚地表明正在使用CS5 IDE。 - shanethehat
@shanethehat:AS3不支持Flash CS5吗? - Benny
自CS3以来,ActionScript 3已经被用于每个Flash IDE中,并且在Flex和AIR应用程序中,这些应用程序不一定需要使用IDE。我认为,除非清楚知道OP正在使用哪个版本,否则仅使用[flash]标签就足够了。 - shanethehat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接