remove a movieclip then reposition rest with flash as3
i would like to remove one or more object at runtime.
After each removed movieclip rest movieclips should be reposition as below. (Removed moviclip is 4 at representative figure)
Movieclips can be more.
Thank you for your help al开发者_JAVA百科ready now.
Try something like
var top:int = 0;
for (var i:int=0;i<numChildren;i++) {
var child:Sprite=getChildAt(i);
child.y = top;
top += child.height;
}
Edit for explanation
Let's say that you are removing the movice clip when it is clicked. In your main document Class, you might have something like this (assumes all instances are present in frame 1, and nothing else is there):
//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;
}
}
You could create a custom DisplayObjectContainer
class and override the addChild()
, addChildAt()
, removeChild()
, removeChildAt()
methods so that they not only add or remove a display object but also rearrange all the child display objects positions too. I made an example to demonstrate this:
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
[UPDATE]
Each line of the following code:
vGroup.removeChild(blocks[3]); // removes block 4
vGroup.removeChildAt(0); // removes block 1
vGroup.addChildAt(getBlock(6, 100, 100),1); // adds block 6
produces the following respective outputs(except the first which is the initial output):
If we can assume that these movieclips are added to their own container (as in, a container that contains only these moveclips), and that they are added sequentially, then this is quite easy.
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;
}
}
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();
Plenty of good examples already, I just wanted to add a short one. Enjoy.
You don't need to reposition everything. Start from previous index.
EDIT : I added the click handlers logic following Amy's post logic
//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;
}
}
}
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);
}
u needs to create container_mc and btn_mc in your stage.
精彩评论