Problems getting objects in Stage - actionscript-3

So, im using this code to remove a couple of movie clips from my stage:
for (var i:uint = 0; i < this.numChildren; i++)
{
if (this.getChildAt(i) is MovieClip
&& pecasInGame.indexOf(this.getChildAt(i)) >= 0)
{
removeChild(this.getChildAt(i));
}
}
But its not really working well... I have 5 movie clips to remove and they are all added dinamically, when these movieclips are added i insert then into this array "pecasInGame", and when there is five of then I try to remove using the aforementioned loop.
The problem is, it only removes 3 of then, the 0, 2 and 4 objects.. The 1 and 3 arent even listed in the loop. Any idea why would that happen??

You're removing the display objects, so the indexes are changing WHILE your loop goes on.
Change it this way:
for (var i:uint = this.numChildren-1; i >= 0 ; i--)
{
if (this.getChildAt(i) is MovieClip && pecasInGame.indexOf(this.getChildAt(i)) >= 0)
{
removeChild(this.getChildAt(i));
}
}
Other option: use your array to remove the objects, like this
for (var i:int=0; i<pecasInGames.length; i++) {
removeChild (pecasInGames[i]);
}

The problem is you are iterating over the children and removing at the same time, so the indices of the children are changing, which is causing the problem.
If you want to remove all the movie clips from the display list, do something like this :
for each(var mc:MovieClip in pecasInGame)
{
if(getChildIndex(mc) != -1)
removeChild(mc);
}

Related

Trying to remove object throws error 1009 cannot access a property or method of null object reference

Working on a flash game, in a previous game I had enemies come in by using an array and when they were killed or moved off the stage I would just remove them from the array. For some reason when I use exactly the same code in this game, it throws a 1009: error when I try to remove the array object, basically saying that there's nothing there. . . Which is strange.
Here's the code:
public function addZombie()
{
var zom:Zombie = new Zombie();
zom.y = 20;
zom.x = Math.floor(Math.random()*(1 + 500 - 30)) + 30;
addChild(zom);
zombies.push(zom);
numZombies++;
}
That's the function where it's added in, zombies is the array and it's pushed into the array in this function. Here's the code where I'm attempting to remove it:
for (var i:int = 0; i < zombies.length; i++)
{
if (zombies[i].y + zombies[i].height / 2 > 400) {
removeChild(zombies[i]);
zombies.splice(i,1);
numZombies--;
addZombie();
}
}
removeChild(zombies[i]); <-- This is the part that throws the error when it attempts to remove it. It removes some of them strangely enough, but not all of them.
I don't believe the loop is doing quite what you expect it to. When you remove an element from an array in this way, all the elements after the removed elements are moved down. So, if you have code like:
var testArr:Array = new Array();
testArr.push('First');
testArr.push('Second');
testArr.push('Third');
testArr.push('Fourth');
for (var i:int = 0; i < testArr.length; i++) {
testArr.splice(i,1);
}
The results of the loop will be:
i=0, testArr = ['Second', 'Third', 'Fourth']
i=1, testArr = ['Second', 'Fourth']
i=2 END OF LOOP
It would probably be better to use a while loop, incrementing the index only if the element is not removed (since removing the element moves a new element to that index position).
I don't see why you're getting the null object reference, but this would be causing other problems (why some are removed but not all).
The explanations of Bill Turner are the correct ones, but as it didn't seem to help you fix your issue, you might want to try this:
var zombieCount:int = zombies.length;
for (var i:int = 0; i < zombies.length; i++)
{
var zombie = zombies[i];
if (zombie.y + (zombie.height / 2) > 400) {
removeChild(zombie);
zombies.splice(i,1);
i--; // So that the loop will pass with the same value next time
numZombies--;
}
}
for (var j:int = zombies.length; j < zombieCount; j++)
{
addZombie();
}

Order of instances in 3D Flash

I'm making cube of 9 cubes in Flash As3. However i cant rotate it properly due to order of indexes whole adding then to stage.
First im creating cube of 6 squares, then wall of 9 cubes, and at the end cube of 3 walls.
It is all fine, however when i rotate it to the left, order of cubes is inverted and it ruins whole composition. I know i coul dinamicly change index based on rotation but it would be a loooooooot of work.
Any ideas how could i do it better way?
Here is actual model:
http://test.mrowa.topdivision.pl/kostka/3DTest.html
If you are using the Flash's display list you would have to sort the sprites based on their z.
Here is some code that would sort the children of a DisplayObjectContainer based on their z position, call this whenever some object changes its position.
public function sortChildren(container:DisplayObjectContainer):void
{
var objects:Vector.<DisplayObject> = new Vector.<DisplayObject>;
for (var i:int = 0; i < container.numChildren; i++)
{
objects.push(container.getChildAt(i));
}
objects.sort(sortCompare);
var index:int = 0;
for (var j:int = 0; j < objects.length; j++)
{
index = container.getChildIndex(objects[j]);
if (index != j)
container.setChildIndex(objects[j], j);
}
}
private function sortCompare(a:DisplayObject, b:DisplayObject):int
{
return (a.z - b.z);
}
You can move the objects member to be a class member and add/remove items to it whenever you add/remove items to/from the stage so that you don't have to fill the whole array every time this function is called.

AS3: How to remove a MovieClip created and placed on stage through an array?

I'm making a game in flash and am using arrays to dynamically create items and place them inventory. LongSword is a MovieClip. I place the movieclip in the array like so:
function buyitem1(e:Event):void
{
if(Store.itemslot.length < 6 && Store.currentMenu == 1 &&score >= 450)
{
Store.itemslot.push(new LongSword);
}
}
Now I'm trying to remove the movieclip from the stage when the LongSword is "sold". How can i remove this longsword? I've tried:
for(var i:int = 0; i < Store.itemslot.length; i++)
{
if(Store.itemslot[i] == LongSword)
{
stage.removeChild(Store.itemslot[0]);
}
}
Ive also tried:
for(var i:int = 0; i < Store.itemslot.length; i++)
{
if(Store.itemslot[i] == new LongSword)
{
stage.removeChild(Store.itemslot);
}
}
and several variations. any ideas?
Try something like:
for each(var i:MovieClip in Store.itemslot)
{
if(i is Longsword)
{
var n:int = Store.itemslot.indexOf(i);
Store.itemslot.splice(n, 1);
if(i.parent) i.parent.removeChild(i);
break; // Only remove one Longsword.
}
}
If there are multiple instances of Longsword in the array, you may want to keep a reference to each instance somewhere for better comparison.

removing multiple movieclips

I'm developing a game.I've attached random movieClips from library. I've movieClips named picLeft1, picLeft2, picLeft3 and so on in library. Its working fine but i'm having problem removing it. the code below is for the attachment of movieclip. Here ranque is an array which stores randomly generated numbers up to 5 and HolderL is the movieClip in which I want to attach the movieClip. And q is a sprite.
for (var i:int = 0; int<3; i++) {
que_mc.push("picLeft"+ranque[i]);
var que_mc_class:Class = getDefinitionByName(que_mc[i]) as Class;
q = new que_mc_class();
this["HolderL"+(i+1)].addChild(q);
}
my code for removing the movieclip is given below.I want to remove all the movieclip attached in HolderL. but this code is not working.
for(var j:int = 1; j<=3; j++) {
this["HolderL"+j].removeChild(q);
}
Flash Player 11 allows you to use this:
for (var j:int = 1; j<=3; j++) {
var container : DisplayObjectContainer = this["HolderL"+j];
container.removeChildren();
}
Earlier versions don't have the removeChildren() command; you have to have two loops: One to loop to iterate over the container movie clips, one to traverse the display list and remove all children.
Shortest way to remove all children of a container prior to FlashPlayer 11:
while (container.numChildren > 0) container.removeChildAt(0);
It's not clear from your code what q is, but basically if you want to remove all the children from one movie clip, the simplest is to loop through all the children and remove them one by one. For example:
for (var i:int = container.numChildren - 1; i >= 0; i--) {
container.removeChildAt(i);
}

problem with tweenlite

i have a bit of a problem.
i have the following function:
private function elementsLoadedHandler(e:Event):void
{
elementContainer=new Sprite();
var currentItem:uint;
for (var i:uint=0; i < numberItems; i++)
{
var element:Element=new Element(elementModel.elements[currentItem]);
element.x=xPos;
element.alpha=.5;
addChild(element);
xPos+=130;
currentItem++;
elementsArr.push(element);
if (currentItem >= elementModel.elements.length)
{
currentItem == 0;
}
}
movementTimer=new Timer(_movementSpeed, 0);
movementTimer.addEventListener(TimerEvent.TIMER, moveItems);
movementTimer.start();
layout();
}
What this basicly does is place elements from an array onto the stage next to eachother. Now i want them to move to the right together. i do this as following:
private function moveItems(e:TimerEvent):void
{
var alphaVal:Number=.5;
movementTimer.delay+=25;
for (var i:uint=0; i < elementsArr.length; i++)
{
xPos=elementsArr[i].x + 130;
TweenLite.to(elementsArr[i], .5, {x: "130"});
if (elementsArr[i].x > _width)
{
elementsArr[i].x=0;
}
}
}
So i'm moving the items to the right and then i check if the last item is outside of the stage, if so i reset its position to 0 so it goes back to the left and this way i have a continious loop of items moving to the right.
The problem is that the way i do it, i have 11 tweens being executed per second, wich makes it laggy. I was thinking about putting the items in an container and tweening the container but i dont seem to be getting a nice continious flow then. Does anyone know how to solve this?
Also, in the first function you can see that i'm doing a for loop. the numberItems variable represents 11, but the amount of items in elementModel.elements is only 6, so for the other 5 elements i just pick the first 5 items from the array again. The problem is that when i trace these items it gives me 0. How can i take items from an array multiple times without overwriting the previous version of it?
You don't need to use tween lite for this. All you need to do in the moveItems function is move each item a little (elemtsArr[i].x += 5, for example) and if elementsArr[i].x > _width, then replace it a 0.
Something like this should work:
function moveItems( e:TimerEvent ):void
{
for (var i:int = 0; i < elemntsArr.length; i++)
{
elementsArr[i].x += 5;
if (elementsArr[i].x > _width)
elementsArr[i].x = 0;
}
}