Flash AS3: position loaded images from loop based on image height - actionscript-3

I'm trying to dynamically stack images that are being pulled in via an xml file. Below is what I'm doing, and it almost works. The problem is that it only seems to fire off the event complete function on the very last one, instead of going for all of them. Is there a way to make it run the even.complete function for each image?
function aboutfileLoaded(event:Event):void {
aboutXML = new XML(aboutTextLoader.data);
for(var l:int = 0; l < aboutXML.aboutimages.image.length(); l++)
{
imageLoader = new Loader();
imageSource = aboutXML.aboutimages.image[l];
if (imageSource != "") {
this.imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, aboutimageLoaded);
this.imageLoader.load(new URLRequest(imageSource));
//aboutBox.aboutContent.addChild(imageLoader);
//imageLoader.y = imageYpos;
//imageYpos = imageYpos + 50;
}
}
}
function aboutimageLoaded(event:Event):void {
aboutBox.aboutContent.addChild(imageLoader);
this.imageLoader.y = imageYpos;
imageYpos = imageYpos + this.imageLoader.height;
}

I use a simple Image class I wrote for loading all images.
public function loadImages(xml:XML):void {
for each(var img:XML in xml.images) {
var i:Image = new Image(img.src, img.width, img.height);
i.loader.contentLoaderInfo.addEventListener(Event.COMPLETE, positionImage);
}
}
/**/
private function positionImage(e:Event):void {
var i:Image = e.target;
gallery.addChild(i);
// Do the positioning.
}
In your code above, you could always just change your aboutimageLoaded function:
// In aboutfileLoaded() change all "this.imageLoader" to just "imageLoader"
function aboutimageLoader(event:Event):void {
aboutBox.aboutContent.addChild(event.target);
event.target.y = imageYpos;
}

each Loader can only deal with one job at a time, so either you want to stack the jobs to load one after another:
//Global vars
loadIndex:int = 0;
imageLoader = new Loader();
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, aboutimageLoaded);
loadImage();
private function loadimage(){
if(aboutXML.aboutimages.image[loadIndex] != null){
imageSource = aboutXML.aboutimages.image[loadIndex];
if (imageSource != "") {
imageLoader.load(new URLRequest(imageSource));
}
}
}
function aboutimageLoaded(event:Event):void {
var holder = (ev.content as Bitmap).clone();
aboutBox.aboutContent.addChild(holder);
holder .y = imageYpos;
imageYpos = imageYpos + holder.height;
loadIndex ++;
loadimage();
}
or make multiple instances of Loaders, one for each:
for(var l:int = 0; l < aboutXML.aboutimages.image.length(); l++)
{
var imageLoaderTemp = new Loader();
imageSource = aboutXML.aboutimages.image[l];
if (imageSource != "") {
imageLoaderTemp.contentLoaderInfo.addEventListener(Event.COMPLETE, aboutimageLoaded);
imageLoaderTemp.load(new URLRequest(imageSource));
}
}
}
function aboutimageLoaded(event:Event):void {
aboutBox.aboutContent.addChild(event.target);
event.target.y = imageYpos;
imageYpos = imageYpos + event.target.height;
}

Related

Trouble with addChild/removeChild and display list order in ActionScript3

I am working on a project, which includes a Lake symbol that the player can throw stones into, which in turn causes octopi to rise out of the lake in the positions that each stone hits the lake.
There is also a symbol for the splash made by the stone which will appear after the stone hits and before the octopus appears.
It is likely that there will be many octopi on the screen at the same time and they need to be ordered in the display list so that the ones that should appear further back are behind the others.
Each instance of these symbols should only play once and then be removed.
My code for this makes use of the different add/remove child method alongside for loops, conditionals and arrays which I have put together with the help of various tutorials and forums.
The problem I have is that when you click on the lake two or more times in quick succession, the stone and the splash symbols aren't removed properly and often keep looping.
Here is the code I am using. Any ideas?
var stone:Stone;
var stoneSplash:StoneSplash;
var octopus1:Octopus1;
var octopus2:Octopus2;
var whichOctopus:Array = [addOctopus1, addOctopus2];
var octopusScale:Number;
var octopusContainer:MovieClip = new MovieClip;
lake.lakeHitArea.addEventListener(MouseEvent.CLICK, onClickLake);
//Add octopusContainer to the stage's display list just above the Lake
addChildAt(octopusContainer,getChildIndex(lake) + 1);
octopusContainer.x = 0;
octopusContainer.y = 0;
function onClickLake(e:MouseEvent):void
{
trace("CLICK");
throwStone(mouseX, mouseY);
}
function throwStone(stonePositionX:int, stonePositionY:int)
{
stone = new Stone();
stone.x = stonePositionX;
stone.y = stonePositionY;
addChild(stone);
addEventListener(Event.ENTER_FRAME, removeStone);
}
function removeStone(e:Event):void
{
var count:int = numChildren;
var children:Array = [count];
//load all the children of the component into an Array
for (var i:int=0; i<count/* -1*/; i++)
{
children[i] = getChildAt(i/* + 1*/);
}
for (i=0; i<count/* - 1*/; i++)
{
if (children[i] is Stone)
{
if (children[i].currentFrameLabel == "Splash")
{
stoneSplash = new StoneSplash();
octopusContainer.addChild(stoneSplash);
stoneSplash.x = children[i].x;
stoneSplash.y = children[i].y;
}
if (children[i].currentFrameLabel == "end")
{
octopusContainer.removeChild(stoneSplash);
var positionX:int = children[i].x;
var positionY:int = children[i].y;
addOctopus(positionX, positionY);
removeChild(children[i]);
}
}
}
}
function addOctopus(positionX, positionY)
{
var o:int = Math.round(randomNumber(0,1));
whichOctopus[o](positionX, positionY);
reorderDisplayList();
addEventListener(Event.ENTER_FRAME, removeOctopus);
}
function addOctopus1(positionX: int, positionY:int):void
{
// if (whichOctopus1 == true)
// {
// var octopus:* = octopus1_1;
// }
// else
// {
// octopus = octopus1_2;
// }
octopus1 = new Octopus1();
var octopus:DisplayObject = octopus1;
octopusContainer.addChild(octopus);
octopus.x = positionX;
octopus.y = positionY;
octopusScale = randomNumber(0.5,0.85);
octopus.scaleX = octopusScale;
octopus.scaleY = octopusScale;
trace("children = " + octopusContainer.numChildren);
testPosition(octopus);
}
function addOctopus2(positionX: int, positionY:int):void
{
// if (whichOctopus2 == true)
// {
// var octopus:* = octopus2_1;
// }
// else
// {
// octopus = octopus2_2;
// }
octopus2 = new Octopus2();
var octopus:DisplayObject = octopus2;
octopusContainer.addChild(octopus);
octopus.x = positionX;
octopus.y = positionY;
octopusScale = randomNumber(0.25,0.5);
octopus.scaleX = octopusScale;
octopus.scaleY = octopusScale;
trace("children = " + octopusContainer.numChildren);
testPosition(octopus);
}
function testPosition(octopus:Object):void
{
trace(octopus)
for (var i:int = 0; i < 200; i++)
{
if (lake.hitTestPoint(octopus.x + octopus.hitTestBox1.x * octopus.scaleX,octopus.y + octopus.hitTestBox1.y * octopus.scaleY,true))
{
break;
}
else
{
octopus.x++;
}
}
for (i = 0; i < 100; i++)
{
if (lake.hitTestPoint(octopus.x + octopus.hitTestBox2.x * octopus.scaleX,octopus.y + octopus.hitTestBox2.y * octopus.scaleY,true))
{
break;
}
else
{
octopus.y--;
}
}
for (i = 0; i < 200; i++)
{
if (lake.hitTestPoint(octopus.x + octopus.hitTestBox3.x * octopus.scaleX,octopus.y + octopus.hitTestBox3.y * octopus.scaleY,true))
{
break;
}
else
{
trace(i);
octopus.x--;
}
}
for (i = 0; i < 100; i++)
{
if (lake.hitTestPoint(octopus.x + octopus.hitTestBox1.x * octopus.scaleX,octopus.y + octopus.hitTestBox1.y * octopus.scaleY,true))
{
break;
}
else
{
octopus.y--;
trace(i);
}
}
}
function randomNumber(min:Number, max:Number):Number
{
return Math.random() * (max - min) + min;
}
function reorderDisplayList():void
{
//the number of children in our component
var count:int = octopusContainer.numChildren;
var children:Array = [count];
//load all the children of the component into an Array
for (var i:int=0; i<count; i++)
{
children[i] = octopusContainer.getChildAt(i);
}
//sort the Array children based on their 'y' property
children.sortOn("y", Array.NUMERIC);
//re-add the children to the component ;
//in the order of the sorted Array we just created.
//When we add the children using 'addChild' it will
//be added at the top of the component's displaylist
//and will automatically be removed from its original position.
for (i=0; i<count/* - 1*/; i++)
{
if (children[i] is Octopus1 || children[i] is Octopus2)
{
// trace("child = " + children[i] + " at i: " + i);
octopusContainer.removeChild(children[i]);
octopusContainer.addChild(children[i]);
}
}
}
function removeOctopus(e:Event):void
{
var count:int = octopusContainer.numChildren;
var children:Array = [count];
//load all the children of the component into an Array
for (var i:int=0; i<count/* -1*/; i++)
{
children[i] = octopusContainer.getChildAt(i/* + 1*/);
}
for (i=0; i<count/* - 1*/; i++)
{
if (children[i] is Octopus1 || children[i] is Octopus2)
{
trace(i);
trace("Is an octopus");
if (children[i].currentFrame >= 202)
{
octopusContainer.removeChild(children[i]);
}
}
}
}
I would greatly appreciate any advice to help me overcome this hurdle and continue with my project.
Thank you in advance.
Chris Collins.
Your issue (or at least one of them) is that your code will only remove the most recent StoneSplash. So if you click a bunch of times in between the splash and end animation , only the last clicked one will get removed.
This is because you are using a global var (stoneSplash) to reference the splash, and it gets overwritten to the new one. You need to either add a splash reference on the stone itself, or create a dictionary so you know which splash goes with which stone.
Here would be one way:
if (children[i].currentFrameLabel == "Splash")
{
stoneSplash = new StoneSplash();
MovieClop(children[i]).stoneSplash = stoneSplash; //add a reference the splash on the stone itself
Then later, instead of octopusContainer.removeChild(stoneSplash); do:
octopusContainer.removeChild(MovieClop(children[i]).stoneSplash);
This way your removing the correct splash that goes with this stone.
Here would be a much cleaner way to architect this instead of using an enter frame handler:
On your Stone class timeline, put the following code on your Splash and End frames respectively:
Splash frame: this.dispatchEvent(new Event("Splash"));
End frame: this.dispatchEvent(new Event("End"));
Listen for those events when you create a new stone instance:
stone = new Stone();
stone.x = stonePositionX;
stone.y = stonePositionY;
stone.addEventListener("Splash", splashHandler,false,0,true);
stone.addEventListener("End",removeStone,false,0,true);
addChild(stone);
Respond to those events appropriately:
function splashHandler(e:Event):void {
var stone:Stone = e.currentTarget as Stone;
stoneSplash = new StoneSplash();
//you need a reference to the splash from the stone class - it would be best to create a class file and add a public property called splashObj and then just use stone.splashObj = new StoneSplash();
MovieClip(stone).stoneSplash = stoneSplash; //so on the end event we can read this var to remove stoneSplash
octopusContainer.addChild(stoneSplash);
stoneSplash.x = stone.x;
stoneSplash.y = stone.y;
}
function removeStone(e:Event):void {
var stone:Stone = e.currentTarget as Stone;
octopusContainer.removeChild(MovieClip(stone).stoneSplash);
addOctopus(stone.x, stone.y);
removeChild(stone);
}

AS3 Loading Image URLrequest - getBounds returns no values

I need to get the width and height of a flag I am loading into another movie so I can place it in the right location. Why is my getBounds not picking up the dimensions of the flag?
function displayFlags(evt:Event = null)
{
if(!Lang) { return; }
for (var i:uint = 0; i < Lang.length; i++)
{
//Language = new MovieClip();
//Language.name = Lang[i];
LangButton = new button01();
LangButton.name = Lang[i];
LangButton.btext.text = Lang[i];
LangButton.y = LangButton.height * i;
addChild(LangButton);
var flag:Loader = new Loader();
flag.load(new URLRequest(LangPath[i]+"/flag.png"));
/// Loads Flag into Button
LangButton.addChild(flag);
var fh = flag.getBounds(flag);
trace("FLAG HEIGHT = " + fh.height); // ZERO ZERO ZERO ZERO
// I really need this info to place the flag in the right location.
flag.y = (LangButton.height/2) - (flag.height/2);
}
evt.target.visible = false;
}
UPDATE: MAY 19TH, 2013
I was able to figure out that I need to wait for the flag to be loaded. Now I can get the correct Bounds.. however, now I can not get the movieClip "flag" in the load complete to respond. I don' think it sees the value of flag.
Below is my UPDATED code:
function displayFlags(evt:Event = null)
{
if(!Lang) { return; }
for (var i:uint = 0; i < Lang.length; i++)
{
//Language = new MovieClip();
//Language.name = Lang[i];
LangButton = new button01();
LangButton.name = Lang[i];
LangButton.btext.text = Lang[i];
LangButton.y = LangButton.height * i;
addChild(LangButton);
flag = new Loader();
flag.load(new URLRequest(LangPath[i]+"/flag.png"));
flag.name = Lang[i];
flag.contentLoaderInfo.addEventListener(Event.COMPLETE, loadedFlag(flag));
function loadedFlag()
{
return function()
{
var fh = flag.getBounds(flag);
trace("FLAG HEIGHT = " + fh);
trace("flag Name: "+ flag.name);
flag.alpha = .3;
}
}
LangButton.addChild(flag);
}
evt.target.visible = false;
}
try this :
flag.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler);
then add function :
function completeHandler(e:Event):void
{
var myFlagInfo:LoaderInfo = e.currentTarget as LoaderInfo;
var myFlag:Loader = myFlagInfo.loader;
var fh = myFlag.getBounds(myFlag);
}

as3 removeChild - I cannot target specific children

I'm still trying to get my head around AS3 and can't figure out how to target some specific Children in my project and remove them... I'm sure there's a simple solution to this on page 1 of a "Basic AS3" book somewhere but I can't work it out!
I'm trying to remove the red lines created in the addNewPoint function (or just give them an alpha of 0) as part of the fillDriveway function.
I can give you a link to the source files if you need.
Thanks so so much in advance!
Here's my terrible code:
import flash.display.*
pic.addEventListener(MouseEvent.CLICK,addNewPoint);
var n:Number = 0;
function addNewPoint(e:MouseEvent):void {
n++;
pointNo.text = String(n);
var nextPoint:MovieClip = new newPoint();
addChild(nextPoint);
nextPoint.name = "mc"+pointNo.text;
nextPoint.x = e.target.mouseX;
nextPoint.y = e.target.mouseY;
var joinPoints:MovieClip = new MovieClip();
this.addChild(joinPoints);
joinPoints.graphics.lineStyle(0.5,0xFF0000);
joinPoints.graphics.moveTo(this.getChildByName("mc1").x, this.getChildByName("mc1").y);
for(var i:int=2; i<=n; ++i){
joinPoints.graphics.lineTo(this.getChildByName("mc"+i).x, this.getChildByName("mc"+i).y);
}
}
pic.addEventListener(MouseEvent.CLICK, addNewPoint);
function fillDriveway(eventObject:MouseEvent) {
var joinPoints:MovieClip = new MovieClip();
this.addChild(joinPoints);
joinPoints.graphics.beginFill(0xFFFFFF, 0.7);
joinPoints.graphics.moveTo(this.getChildByName("mc1").x, this.getChildByName("mc1").y);
for(var m:int=2; m<=n; ++m){
joinPoints.graphics.lineTo(this.getChildByName("mc"+m).x, this.getChildByName("mc"+m).y);
}
joinPoints.name = "driveshape";
filledDrive.text = "filled";
}
function undoit(eventObject:MouseEvent) {
if(n > 0) {
if(filledDrive.text.indexOf("filled") != -1) {
this.removeChild(this.getChildAt(this.numChildren -1));
filledDrive.text = "";
}else{
this.removeChild(this.getChildAt(this.numChildren -1));
this.removeChild(this.getChildAt(this.numChildren -1));
n--;
pointNo.text = String(n);
}
}
}
undo.addEventListener(MouseEvent.CLICK, undoit);
function maskDrive(eventObject:MouseEvent) {
if(filledDrive.text.indexOf("filled") != -1) {
var finishA:MovieClip = new finishMC();
this.addChild(finishA);
finishA.x = 310;
finishA.y = 100;
finishA.mask = getChildByName("driveshape");
finishA.gotoAndPlay(2);
}
}
//BTN Actions
function btn1over(myEvent:MouseEvent) {
btn1.gotoAndPlay(2);
}
function btn1out(myEvent:MouseEvent) {
btn1.gotoAndPlay(11);
}
function btn2over(myEvent:MouseEvent) {
btn2.gotoAndPlay(2);
}
function btn2out(myEvent:MouseEvent) {
btn2.gotoAndPlay(11);
}
function btn3over(myEvent:MouseEvent) {
btn3.gotoAndPlay(2);
}
function btn3out(myEvent:MouseEvent) {
btn3.gotoAndPlay(11);
}
//BTN Calls
btn1.addEventListener(MouseEvent.CLICK, fillDriveway);
btn1.addEventListener(MouseEvent.ROLL_OVER, btn1over);
btn1.addEventListener(MouseEvent.ROLL_OUT, btn1out);
btn1.buttonMode = true;
btn1.useHandCursor = true;
btn2.addEventListener(MouseEvent.CLICK, maskDrive);
btn2.addEventListener(MouseEvent.ROLL_OVER, btn2over);
btn2.addEventListener(MouseEvent.ROLL_OUT, btn2out);
btn2.buttonMode = true;
btn2.useHandCursor = true;
btn3.buttonMode = true;
btn3.useHandCursor = true;
btn3.addEventListener(MouseEvent.ROLL_OVER, btn3over);
btn3.addEventListener(MouseEvent.ROLL_OUT, btn3out);
I think your issue is that each time you create a new joinPoints you are overwriting the pointer to the previous joinPoints instance, therefore you cannot access it. (this will create a memory leak).
Each time you create a joinPoints object, add it to an array:
joinPointsArray.push(joinPoints);
Your fillDriveway function can then access all the joinPoints you have created:
for (var i:int = 0; i < joinPointsArray.length, i++) {
joinPointsArray[i].alpha = 0;
}

as3 child as movieclip - won't accept functions

this follows on from my last question which I thought was answered but for some reason when I treat a child of my stage (display object) as a movieclip I can't then apply the usual functions that I want to:
var mc1:MovieClip = this.getChildByName("mc1") as MovieClip;
if(mc1) {
mc1.useHandCursor = true;
mc1.buttonMode = true;
mc1.addEventListener(MouseEvent.CLICK, fillDriveway);
}
Any wisdom would greatly appreciated... and sorry for asking such a similar question as previous...
Thanks in advance.
EDIT: More code from the AS on this project for context:
import flash.display.*
ImageUploader.visible = false;
function showUploader(e:MouseEvent):void {
ImageUploader.visible = true;
ImageUploader.gotoAndPlay(2);
}
pic.addEventListener(MouseEvent.CLICK,addNewPoint);
var n:Number = 0;
var joinPointsArray:Array = new Array;
function addNewPoint(e:MouseEvent):void {
n++;
pointNo.text = String(n);
if(n==1){
var nextPoint:MovieClip = new mcstart();
addChild(nextPoint);
nextPoint.name = "mc"+pointNo.text;
nextPoint.x = e.target.mouseX;
nextPoint.y = e.target.mouseY;
}else{
var nextPoint2:MovieClip = new newPoint();
addChild(nextPoint2);
nextPoint2.name = "mc"+pointNo.text;
nextPoint2.x = e.target.mouseX;
nextPoint2.y = e.target.mouseY;
}
var joinPoints:MovieClip = new MovieClip();
this.addChild(joinPoints);
joinPointsArray.push(joinPoints);
joinPoints.graphics.lineStyle(0.5,0xFF0000);
joinPoints.graphics.moveTo(this.getChildByName("mc1").x, this.getChildByName("mc1").y);
for(var i:int=2; i<=n; ++i){
joinPoints.graphics.lineTo(this.getChildByName("mc"+i).x, this.getChildByName("mc"+i).y);
}
}
pic.addEventListener(MouseEvent.CLICK, addNewPoint);
function fillDriveway(eventObject:MouseEvent) {
var joinPoints:MovieClip = new MovieClip();
this.addChild(joinPoints);
for(var p:int=0; p<(joinPointsArray.length); ++p) {
joinPointsArray[p].alpha = 0;
}
this.getChildByName("mc1").alpha = 0;
joinPoints.graphics.beginFill(0xFFFFFF, 0.7);
joinPoints.graphics.moveTo(this.getChildByName("mc1").x, this.getChildByName("mc1").y);
for(var m:int=2; m<=n; ++m){
joinPoints.graphics.lineTo(this.getChildByName("mc"+m).x, this.getChildByName("mc"+m).y);
}
joinPoints.name = "driveshape";
filledDrive.text = "filled";
}
function undoit(eventObject:MouseEvent) {
if(n > 0) {
if(filledDrive.text.indexOf("filled") != -1) {
this.removeChild(this.getChildAt(this.numChildren -1));
filledDrive.text = "";
}else{
this.removeChild(this.getChildAt(this.numChildren -1));
this.removeChild(this.getChildAt(this.numChildren -1));
n--;
pointNo.text = String(n);
}
}
}
function maskDrive(eventObject:MouseEvent) {
if(filledDrive.text.indexOf("filled") != -1) {
var finishA:MovieClip = new finishMC();
this.addChild(finishA);
finishA.x = 310;
finishA.y = 100;
finishA.mask = getChildByName("driveshape");
finishA.gotoAndPlay(2);
}
}
//BTN RollOvers
function btn1over(myEvent:MouseEvent) {
btn1.gotoAndPlay(2);
}
function btn1out(myEvent:MouseEvent) {
btn1.gotoAndPlay(11);
}
function btn2over(myEvent:MouseEvent) {
btn2.gotoAndPlay(2);
}
function btn2out(myEvent:MouseEvent) {
btn2.gotoAndPlay(11);
}
function btn3over(myEvent:MouseEvent) {
btn3.gotoAndPlay(2);
}
function btn3out(myEvent:MouseEvent) {
btn3.gotoAndPlay(11);
}
function undoover(myEvent:MouseEvent) {
undo.gotoAndPlay(2);
}
function undoout(myEvent:MouseEvent) {
undo.gotoAndPlay(11);
}
//BTN Calls
btn1HIT.addEventListener(MouseEvent.CLICK, fillDriveway);
btn1HIT.addEventListener(MouseEvent.ROLL_OVER, btn1over);
btn1HIT.addEventListener(MouseEvent.ROLL_OUT, btn1out);
btn1HIT.buttonMode = true;
btn1HIT.useHandCursor = true;
btn2HIT.addEventListener(MouseEvent.CLICK, maskDrive);
btn2HIT.addEventListener(MouseEvent.ROLL_OVER, btn2over);
btn2HIT.addEventListener(MouseEvent.ROLL_OUT, btn2out);
btn2HIT.buttonMode = true;
btn2HIT.useHandCursor = true;
btn3HIT.buttonMode = true;
btn3HIT.useHandCursor = true;
btn3HIT.addEventListener(MouseEvent.ROLL_OVER, btn3over);
btn3HIT.addEventListener(MouseEvent.ROLL_OUT, btn3out);
btn3HIT.addEventListener(MouseEvent.CLICK, showUploader);
undoHIT.addEventListener(MouseEvent.CLICK, undoit);
undoHIT.addEventListener(MouseEvent.ROLL_OVER, undoover);
undoHIT.addEventListener(MouseEvent.ROLL_OUT, undoout);
undoHIT.buttonMode = true;
undoHIT.useHandCursor = true;
var mc1:MovieClip = this.getChildByName("mc1") as MovieClip;
if(mc1) {
mc1.useHandCursor = true;
mc1.buttonMode = true;
mc1.addEventListener(MouseEvent.CLICK, fillDriveway);
}
Are you sure the movieclip is placed on stage or actually converted to movieclip?
Try stage.getChildByName(). Where did you place this code? Inside a frame or inside a main document class? To be sure you can check the childs are added on stage and see what their names are.
You can use this code
for ( var i :int = 0; i < this.numChildren; i++ )
{
babe = this.getChildAt( i );
if ( babe is MovieClip) {
trace( babe.name);
}
}
I've also seen this, not sure if it works.
if (stage.contains(mc1)) {
}
Wahoo! Figured it out!
By popping
var mc1:MovieClip = this.getChildByName("mc1") as MovieClip;
at the end of my AS I was referring to the child "mc1" before it existed - it isn't created until the user clicks somewhere on the "pic" movieclip. So the solution was to bung my actions for "mc1" (including declaring it as a MovieClip) into a separate function:
function createstartEndMC():void {
var startEnd:MovieClip = (this.getChildByName("mc1")) as MovieClip;
startEnd.useHandCursor = true;
startEnd.buttonMode = true;
startEnd.addEventListener(MouseEvent.CLICK, fillDriveway);
}
and then to call this function AFTER "mc1" child is created:
function addNewPoint(e:MouseEvent):void {
n++;
pointNo.text = String(n);
if(n==1){
var nextPoint:MovieClip = new mcstart();
addChild(nextPoint);
nextPoint.name = "mc"+pointNo.text;
nextPoint.x = e.target.mouseX;
nextPoint.y = e.target.mouseY;
createstartEndMC();
}
Finally it works and "mc1" (or "startEnd" as I call it once it's created and made into an MC) finally behaves as a normal timeline MC should!
I'm so happy - thanks for all your guidance!
Cam

AS3 Showing image after load is finish

So i'm loading picture from xml, and adding them into a movieclip called cv which has a holder called cHolder. Right now the problem is that while the preloader shows it is loading, the cv(s) appeared already. Is there anyway to show all the cv only after the images have finish loading?
Thanks.
for each (var projectName:XML in projectAttributes)
{
//trace(projectName);
var projectDP:XMLList = projectInput.project.(#name == projectName).displayP;
//trace(projectDP);
var cv:MovieClip = new cView();
catNo += 1;
cv.name = "cv" + catNo;
cv.buttonMode = true;
if(catNo % 5 == 0)
{
catY += 137;
catX = -170;
cv.x = catX;
cv.y = catY;
}
else
{
cv.x = catX;
cv.y = catY;
catX += 112;
}
var imageLoader = new Loader();
imageLoader.load(new URLRequest(projectDP));
TweenLite.to(cv.cHolder, 1, {colorTransform:{tint:0x000000, tintAmount:0.8}});
cv.cHolder.addChild(imageLoader);
cv.ct.text = projectName;
projName.push(projectName);
this.addChild(cv);
imageLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, imageProg);
function imageProg(e:ProgressEvent):void
{
loader.visible = true;
var imageLoaded:Number = e.bytesLoaded/e.bytesTotal*100;
loader.scaleX = imageLoaded/100;
}
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoad);
function imageLoad(e:Event):void
{
loader.visible = false;
}
First, don't put a function inside another function, this won't help for anything and is a bad habit :)
Declare two private variables:
var nImages:uint;
var loadedImages:uint;
Before the loop:
nImages = projectAttributes.length();
loadedImages = 0;
cv.visible = false;
and in the Event.COMPLETE listener:
function imageLoad(e:Event):void
{
loader.visible = false;
loadedImages++;
if (loadedImages == nImages)
{
cv.visible = true;
}
}
var count:int = 0;
var totalClips:int = 0;
cv.visible = false;
for each (var projectName:XML in projectAttributes)
{
++totalClips;
//trace(projectName);
var projectDP:XMLList = projectInput.project.(#name == projectName).displayP;
//trace(projectDP);
var cv:MovieClip = new cView();
catNo += 1;
cv.name = "cv" + catNo;
cv.buttonMode = true;
if(catNo % 5 == 0)
{
catY += 137;
catX = -170;
cv.x = catX;
cv.y = catY;
}
else
{
cv.x = catX;
cv.y = catY;
catX += 112;
}
var imageLoader = new Loader();
imageLoader.load(new URLRequest(projectDP));
TweenLite.to(cv.cHolder, 1, {colorTransform:{tint:0x000000, tintAmount:0.8}});
cv.cHolder.addChild(imageLoader);
cv.ct.text = projectName;
projName.push(projectName);
this.addChild(cv);
imageLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, imageProg);
function imageProg(e:ProgressEvent):void
{
loader.visible = true;
var imageLoaded:Number = e.bytesLoaded/e.bytesTotal*100;
loader.scaleX = imageLoaded/100;
}
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoad);
function imageLoad(e:Event):void
{
++count;
if(count == totalClips){
cv.visible = true;
}
loader.visible = false;
}
}
So you might want to adapt things a little, in case I'm counting in the wrong spots etc for your implementation but as you can see the solution is simple, you count the total number of clips being processed for loading from the XML, then as the images are loaded and call the OnComplete callback, you increment another count until you've seen that you've loaded all processed images, and set the container to visible.