AS3 For statement access movieclip within movieclip - actionscript-3

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.

Related

AS2 carousel gallery to AS3

I'm making carousel gallery for my class, however we got a code written in AS2 and have to transform it into AS3. I have a problem with two fragments:
// create the objects for the circular motion
for (var i:Number = 0; i < numberOfObjects; i++)
{
this.createEmptyMovieClip('object'+i, i);
this['object'+i].loadMovie('p'+(i+1)+'.jpg');
}
Where I'm adding movie clips as objects, and then I want to use them as:
// create the motion along the circular path
this.addEventListener(Event.ENTER_FRAME, function()
{
// loop over all the objects
for (var i:Number = 0; i < numberOfObjects; i++)
{
thisObj = this['object'+i];
placeObj(thisObj,i);
displayObj(thisObj);
}
})
Of course I get an exception:
Scene 1, Layer 'actions', Frame 1, Line 85 1120: Access of undefined property thisObj.
I know that createEmptyMovieClip as well as loadMovie don't work in AS3, and I probably should make MovieClip as new MovieClip, however I still have troubles how to make this work. I'll be truly grateful for any advices.
You need to apply var keyword before you introduce a new variable.
Correct your as3 code this:
var thisObj:Sprite = this['object'+i];

Acessing "parent.child.MC"

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

Object removed from screen before the relevant command is called (Error #1009)

I'm sorry if it's asking for too much, but I'm too confused by now. I'm making this really simple shooter game for my nephew in AS3. It all seems to be working just fine, except for one really annoying error that keeps popping up every second or third time the game is launched.
IT is Error #1009: Cannot access a property or method of a null object reference. The problem is always with parent.removeChild(this) command in the relevant class (EnemyClass, BulletClass or MissileClass). This happens in two cases: either when checkFinishConditions method in Main is called and the EnemyClass instance needs to be deleted. So if I get the #1009 error does this mean the instance has already been deleted? The second situation is when inst.hitTestObject(enemyInstance) is checked in Main class. Does this mean the EnemyClass instance has already been deleted somehow? I'm totally lost here to be honest.
private function checkCollision():void
{
//loop through missiles
for (var i:int = 0; i < aMissileArray.length; i++) {
//get the current missile
var currentMissile:missileClass = aMissileArray[i];
//loop through enemies
for (var j:int = 0; j < aEnemyArray.length; j++) {
var thisEnemy:EnemyClass = aEnemyArray[j];
if (currentMissile.hitTestObject(thisEnemy)) {
var thisExplode:ExplosionClass = new ExplosionClass(thisEnemy.x,thisEnemy.y);
addChild(thisExplode);
currentMissile.destroyThis();
aMissileArray.splice(i,1);
thisEnemy.deleteEnemy();
aEnemyArray.splice(j, 1);
aDamageArray.splice(j, 1);
scoreValueText += 1;
j--;
i--;
}
//break;
}
}
//loop through bullets
for (var l:int = 0; l < aBulletArray.length; l++) {
//get the current missile
var currentBullet:BulletClass = aBulletArray[l];
//loop through enemies
for (var k:int = 0; k < aEnemyArray.length; k++) {
var currentEnemy:EnemyClass = aEnemyArray[k];
if (currentBullet.hitTestObject(currentEnemy)) {
currentBullet.destroyThis();
aBulletArray.splice(l, 1);
aDamageArray[k] -= 1;
l--;
if (aDamageArray[k] < 1) {
//create an explosion
var thisBulletExplode:ExplosionClass = new ExplosionClass(currentEnemy.x,currentEnemy.y);
addChild(thisBulletExplode);
currentEnemy.deleteEnemy();
aEnemyArray.splice(k, 1);
aDamageArray.splice(k, 1);
scoreValueText += 1;
k--;
}
break;
}
}
}
}
There is alot of code to look over, but one potential issue I see is here :
for each(var currentDieEnemy:EnemyClass in aEnemyArray) {
aEnemyArray.splice(0, 1);
currentDieEnemy.deleteEnemy();
}
The potential issue is that you are 'assuming' that the order of this loop is sequential based on the actual index order of the Array. You might want to stick a trace in there to verify that is actually what is happening, because I believe it's possible that they can be out of order.
See this question for details -- For-Each Loop AS3: Is the direction guaranteed?
So imagine the scenario where the 3rd item in the array is first and you splice the item at the 0 index. Now, you have an item in the array that is removed from the display list, but not from the array. So what happens when you get to that item ? Pretty much what you are describing will happen since the parent property is null, since you already removed it from the display list.
The way to fix that is to do something like this :
while (aEnemyArray.length > 0)
{
var currentDieEnemy:EnemyClass = aEnemyArray[0];
currentDieEnemy.deleteEnemy();
aEnemyArray.splice(0,1);
}
I found another issue in this block of code :
for (var j:int = 0; j < aEnemyArray.length; j++) {
var thisEnemy:EnemyClass = aEnemyArray[j];
if (currentMissile.hitTestObject(thisEnemy)) {
var thisExplode:ExplosionClass = new ExplosionClass(thisEnemy.x,thisEnemy.y);
addChild(thisExplode);
currentMissile.destroyThis();
aMissileArray.splice(i,1);
thisEnemy.deleteEnemy();
aEnemyArray.splice(j, 1); // now array composition is different.
aDamageArray.splice(j, 1);
scoreValueText += 1;
}
}
When you loop through an Array and splice an item at the loop index, you have to realize what happens to the composition of the array. Here's an example
Suppose enemy3 needs to be spliced because of a collision. Given your code, this is what happens :
Before (j == 2)
(0) enemy1
(1) enemy2
(2) enemy3
(3) enemy4
(4) enemy5
AFTER
(0) enemy1
(1) enemy2
(2) enemy4
(3) enemy5
So when the loop continues, j will now increment and equal 3.
The result is that enemy4 doesn't get evaluated as the composition of the array collapses to fill the hole created by the splice and you didn't adjust your loop index variable.
So, what you can do in that situation is simply decrement the loop index variable at the end of the block like so :
aEnemyArray.splice(j, 1); // now array composition is different.
aDamageArray.splice(j, 1);
scoreValueText += 1;
j--; // decrement loop index variable.
So while this is one solution, the main point to take away here is the change in the composition of your Array after a splice.
Yep, you are splicing your objects from arrays in a weird way. First, you are traversing the array forwards and splicing in the loop. This can lead to issues of several bullets not trigger collisions when they should, or say not move. See, if you are running your loop for bullets at index i, once you call bullets.splice(i,1); the bullet that was to be iterated next becomes at position i, then you increment i and that bullet remains unprocessed.
Next, you have nested loops, and in the inner loop you are removing an object from OUTER loop. This means once you did a removal of the outer loop's object, your inner loop is now invalidated, you have to preemptively terminate inner loop.
//loop through bullets
for (var l:int = aBulletArray.length-1; l>=0; l--) {
// first, traverse both arrays backwards
//get the current missile
var currentBullet:BulletClass = aBulletArray[l];
//loop through enemies
for (var k:int = aEnemyArray.length-1; k>=0; k--) {
var currentEnemy:EnemyClass = aEnemyArray[k];
if (currentBullet.hitTestObject(currentEnemy)) {
currentBullet.destroyThis();
aBulletArray.splice(l, 1);
aDamageArray[k] -= 1;
if (aDamageArray[k] < 1) {
//create an explosion
var thisExplode:ExplosionClass = new ExplosionClass(currentEnemy.x,currentEnemy.y);
addChild(thisExplode);
currentEnemy.deleteEnemy();
aEnemyArray.splice(k, 1);
aDamageArray.splice(k, 1);
scoreValueText += 1;
}
// and since we don't have "currentBullet" anymore, do this
break;
}
}
}
Fix all the other iterations through your arrays where you do splicing, like I did in this part of code, and you should avoid 1009 errors in these loops.
Also, you should not post your entire project code, but instead post only relevant parts, say an entire function that's reported as throwing an error, and explain which line is producing the error - it's written as number in the error's stack trace.

actionscript for loop iterator to change movie clip name

I have a bunch of movie clips I created in flash CS5 and are all placed within the stage. I control each one of them dynamically with code using ActionScript 3. However I want to control all of them at the same time using a for loop and just change the width of each element but its not working.
Here is my code:
for(var i:Number = 0; i < 100; i++)
{
leftBar+i.width = ( Math.round(channel.rightPeak * 1.1) ) + 60;
}
So I have 100 bars each called leftBar and their number. So the firstBar is leftBar1, then leftBar2 and so on. I cant get it to work however. I have tried "leftBar"+i and also leftBari but none of them seem to work.
The correct way to select each of those MovieClips in your loop is:
this["leftBar" + i]
New code:
// Note: We've changed the initial value of i to 1 because you mentioned that
// your first MovieClip was called 'leftBar1' rather than 'leftBar0'.
for(var i:int = 1; i <= 100; i++)
{
var current:MovieClip = this["leftBar" + i];
current.width = Math.round(channel.rightPeak * 1.1) + 60;
}
Basically you want to select the property leftBar0, leftBar1, etc from this using square brackets. It is the same as doing this:
this.leftBar0
And can also be used for any properties or methods of any other class:
// Example of Square Bracket notation.
var sprite:Sprite = new Sprite();
sprite["x"] = 10;
trace(sprite.x);
this["addChild"](sprite);

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