Acessing "parent.child.MC" - actionscript-3

I have a structure that is something like this - holder.lineX.lineoverlay
I want to access the movieclip "lineoverlay" on all children created
If I do something like this:
MovieClip(this.parent).lineX.lineoverlay.visible = false;
It works but I don't always know how many "line" movieclips I have, because they are created in runtime.
I tried this:
for (var i:uint = 1; i < MovieClip(parent).numChildren; i++) {
MovieClip(this.parent).getChildAt(i).lineoverlay.visible = false;
}
But I keep getting an error because flash treats "lineoverlay" as an undefined property and not as movieclip.
Can someone help?

getChildAt returns a DisplayObject. DisplayObject is not a dynamic object (unlike Movieclip). So just cast it to movieclip in that case.
This should work:
for (var i:uint = 1; i < MovieClip(parent).numChildren; i++) {
MovieClip(MovieClip(this.parent).getChildAt(i)).lineoverlay.visible = false;
}

Related

Modifying Display Object Color

I'm attempting to change the color of several display objects using colorTransform but can't get it working -
private function getChildren(mc:DisplayObjectContainer):Array {
var children:Array = [];
for (var i:int = 0; i < mc.numChildren; i++) {
var child:DisplayObject = mc.getChildAt(i);
if(child.name == "color1"){
children.push(child);
} else if(child.name == "color2"){
children.push(child);
}
if (child is DisplayObjectContainer) {
var childChildren:Array = getChildren((child as DisplayObjectContainer));
children = children.concat(childChildren);
}
}
return children;
}
and in my enter stage event:
var mychildren:Array = getChildren(this.spartan);
for each(var child:DisplayObject in mychildren) {
if(child.name == "color1"){
child.transform.colorTransform = _colorTransform1;
}
trace(child.name);
I've declared the color as _colorTransform1.color = 0xCCFF00
My character subsists of several movieclips that are currently either instances of color1:red or color2:green. As a new programmer I'm wondering if I should have proceeded with another method?
trace(child.name)
if(child.name == "color1"){
trace("found color!")
}
Alright, I kind of feel a little stupid right now because the answer was so darn obvious...
While attempting to change the color of the movieclip I had forgotten that the movieclip itself had not loaded yet. To fix this issue all I had to do was call the movieclip frame BEFORE I changed the color.

Adding a child to a child

In AS3, I am trying to add a child to a specific child of a MovieClip.
To do this I have done the following:
for (var r:Number = 0; r < 2; r++) {
sand = new Sand();
sLayers.getChildAt(r).addChild(sand);
}
When sLayers is the MovieClip parent, r is the specific child of sLayers, and sand is the child I want to add.
It comes up with the following error:
1061: Call to a possibly undefined method addChild
through a reference with static type flash.display:DisplayObject.
Sorry I simplified the code, it would take up too much space.
Is there another way to do this? Or am I close but just missing something?
try this
for(var r:Number = 0; r < 2; r++)
{
var sand:Sand = new Sand;
(sLayers.getChildAt(r) as MovieClip).addChild(sand);
}

Arranging items in an inventory

I'm working on an inventory system I made following a short tutorial that leaves you stranded. I've managed to get the items removed and rearrange to the correct order somewhat. For some reason though, if I click on the last item in my inventory, then on the first item, the items do not rearrange correctly.
public class Inventory {
var itemsInInventory:Array;
var inventorySprite:Sprite;
var itemNum:int;
public function Inventory(parentMC:MovieClip) {
itemNum=0;
itemsInInventory = new Array();
inventorySprite = new Sprite();
inventorySprite.x = 50;
inventorySprite.y = 360;
parentMC.addChild(inventorySprite);
}
public function makeInventoryItems(arrayOfItems:Array){
for(var i:int = 0; i < arrayOfItems.length; i++){
arrayOfItems[i].addEventListener(MouseEvent.CLICK, getItem);
arrayOfItems[i].buttonMode = true;
}
}
public function getItem(e:MouseEvent){
var item:MovieClip = MovieClip(e.currentTarget);
itemsInInventory.push(item);
inventorySprite.addChild(item);
item.x = (itemsInInventory.length-1)*40;
item.y = 0;
item.removeEventListener(MouseEvent.CLICK, getItem);
item.addEventListener(MouseEvent.CLICK, useItem);
}
public function useItem(e:MouseEvent){
var item:MovieClip = MovieClip(e.currentTarget);
itemNum = item.x;
inventorySprite.removeChild(item);
itemsInInventory.splice(item, 1);
sortInventory();
}
public function sortInventory(){
for(var i:int = 0; i < itemsInInventory.length; i++){
if(itemsInInventory[i].x > itemNum){
itemsInInventory[i].x -= 40;
}
}
itemNum=0;
}
}
I belive thats all the coding info I need to provide for help solving this mystery.
Also, a link to the game for testing. If you would like a link for a download of the game, please ask.
LINK
Instead of substracting 40px, just set their position again:
for(var i:int = 0; i < itemsInInventory.length; i++){
itemsInInventory[i].x = i*40;
}
Also, I did not even know that it is possible to give an object reference to the splice function, I would rather use:
itemsInInventory.splice(itemsInInventory.indexOf(item), 1);
And remove the event listener from the item when you delete it from the inventory in the useItem function.
item.removeEventListener(MouseEvent.CLICK, useItem);
EDIT:
With Flash Player 10, Adobe introduced the Vector class which is kind of the same as the Array class, but it can only store one data type. In your case it would be MovieClip or Sprite. The Vector class is singificantly faster and more developer friendly because you can see the help from the IDE when you are typing myVector[i].. I recommend using that instead, although there is nothing wrong with Array. It is just outdated a bit, but is helpful when you want to store more data types.
myVector:Vector.<MovieClip> = new Vector.<MovieClip>();

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();
}

AS3 For statement access movieclip within movieclip

I have added:
sub1_btn
Within sub1_btn there is a movieclip called "arrow".
Using this code I am able to access it and tween it:
TweenMax.to(sub2_btn.arrow, 1, {rotation: -0});
However, using this code within a FOR statement (as there are 2), I am not
for (var i:int = 1; i<3; i++){
TweenMax.to(["sub"+i+"_btn"].arrow, 1, {rotation: -0});
}
What is wrong with the above code? The error is:
Error: Cannot tween a null object.
at com.greensock::TweenLite()
at com.greensock::TweenMax()
at com.greensock::TweenMax$/to()
at src::main/pullSub()
Try this instead:
for (var i:int = 1; i<3; i++){
TweenMax.to(this["sub"+i+"_btn"].arrow, 1, {rotation: -0});
}
The problem is that ["sub"+i+"_btn"] creates a new array, and that array doesn't contain an object arrow. But when you use this["sub"+i+"_btn"] you access the movie clip sub[i]_btn as you want.