ActionScript3 remove child error - actionscript-3

I recently have been converting an as2 fla to as3 (new to AS3) and have the entire thing working on export, but I am getting an error when I try to remove previously loaded swf's before a new swf is loaded
ArgumentError: Error #2025: The supplied DisplayObject
must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at MethodInfo-11()
I know the error relates to my removeChild code here:
`stage.addEventListener(MouseEvent.CLICK, removeSWF);
function removeSWF (e:MouseEvent):void
{
if(vBox.numChildren !=0){
// swfLoader.unloadAndStop();
vBox.removeChild(swfLoader);// empty the movieClip memory
}
}`
However, I cannot seem to find a suitable rewrite for this code that will work and not have an error. This code IS working, so I'm not sure if it would be worth my time to fix this error, or just leave it. I've already messed with it for a couple days, so at this point it's just frustrating me that I cannot fix it.
The stage mouse click listener is useful in this case because I have a back button not shown in this code that clears the loaded swf's before moving to another scene.
Does anyone see a simple solution for this, or do you think it is unnecessary to pursue since the code does what I require?
ENTIRE CODE:
function launchSWF(vBox, vFile):void {
var swfLoader:Loader = new Loader();
var swfURL:URLRequest = new URLRequest(vFile);
swfLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgressHandler);
swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadProdComplete);
swfLoader.load(swfURL);
function loadProdComplete(e:Event):void {
trace("swf file loaded");
vBox.removeChild(preLoader);
vBox.addChild(swfLoader);
currentSWF = MovieClip(swfLoader.content);
currentSWF.gotoAndPlay(1);
currentSWF.addEventListener(Event.ENTER_FRAME , checkLastFrame);
swfLoader.x = 165;
swfLoader.y = 15;
function checkLastFrame(e:Event):void {
if (currentSWF.currentFrame == currentSWF.totalFrames) {
currentSWF.stop();
// trace("DONE");
}
}
}
var preLoader:loader = new loader();
preLoader.x = 450;
preLoader.y = 280;
vBox.addChild(preLoader);
function onProgressHandler(event:ProgressEvent){
var dataAmountLoaded:Number=event.bytesLoaded/event.bytesTotal*100;
//preLoader.bar.scaleX = dataAmountLoaded/100;
preLoader.lpc.text= int(dataAmountLoaded)+"%";
//trace(preLoader.bar.scaleX );
}
//NEW ERRORS BUT WORKING
stage.addEventListener(MouseEvent.CLICK, removeSWF);
function removeSWF (e:MouseEvent):void
{
if(vBox.numChildren !=0){
// swfLoader.unloadAndStop();
vBox.removeChild(swfLoader);// empty the movieClip memory
}
}
}
var container:MovieClip = new MovieClip();
var currentSWF:MovieClip = new MovieClip();
fall_b.addEventListener(MouseEvent.CLICK, fall_bClick);
function fall_bClick(e:MouseEvent):void {
var swfFile:String = 'load/fall.swf';
launchSWF(container, swfFile);
addChild(container);
}
face_b.addEventListener(MouseEvent.CLICK, face_bClick);
function face_bClick(e:MouseEvent):void {
var swfFile:String = 'load/face.swf';
launchSWF(container, swfFile);
addChild(container);
}
rott_b.addEventListener(MouseEvent.CLICK, rott_bClick);
function rott_bClick(e:MouseEvent):void {
var swfFile:String = 'load/rottgut.swf';
launchSWF(container, swfFile);
addChild(container);
}
//MORE SWFS...
Any advice anyone has is appreciated

First of all function launchSWF(vBox, vFile):void { isn't closed. You've also got function inside functions which is easy enough for you to solve if you click the lines the curly brackets start and end on to track them.
I can't see anything wrong with the code you said has an error but I'm guessing this isn't all the code. If you using Flash Professisonal you can use permit debugging to show the line the error is on.
EDIT: Please note this hasn't been tested as I'm on my mobile writing out code. That being said this should now work:
var container:MovieClip;
var currentSWF:MovieClip;
var swfFile:String;
var swfLoader:Loader;
var preLoader:Loader;
var swfURL:URLRequest;
init();
function init():void {
preLoader = new Loader();
preLoader.x = 450;
preLoader.y = 280;
vBox.addChild(preLoader);
container = new MovieClip();
currentSWF = new MovieClip();
fall_b.addEventListener(MouseEvent.CLICK, fall_bClick);
face_b.addEventListener(MouseEvent.CLICK, face_bClick);
rott_b.addEventListener(MouseEvent.CLICK, rott_bClick);
stage.addEventListener(MouseEvent.CLICK, removeSWF);
}
function launchSWF(vBox, vFile):void {
swfLoader = new Loader();
swfURL = new URLRequest(vFile);
swfLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgressHandler);
swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadProdComplete);
swfLoader.load(swfURL);
}
function loadProdComplete(e:Event):void {
trace("swf file loaded");
vBox.removeChild(preLoader);
vBox.addChild(swfLoader);
currentSWF = MovieClip(swfLoader.content);
currentSWF.gotoAndPlay(1);
currentSWF.addEventListener(Event.ENTER_FRAME , checkLastFrame);
swfLoader.x = 165;
swfLoader.y = 15;
}
function checkLastFrame(e:Event):void {
if (currentSWF.currentFrame == currentSWF.totalFrames) {
currentSWF.stop();
// trace("DONE");
}
}
function onProgressHandler(event:ProgressEvent) {
var dataAmountLoaded:Number = (event.bytesLoaded / event.bytesTotal * 100);
//preLoader.bar.scaleX = dataAmountLoaded/100;
preLoader.lpc.text = int(dataAmountLoaded)+"%";
//trace(preLoader.bar.scaleX );
}
function removeSWF (e:MouseEvent):void {
if(vBox.numChildren !=0){
//swfLoader.unloadAndStop();
vBox.removeChild(swfLoader);// empty the movieClip memory
}
}
function fall_bClick(e:MouseEvent):void {
swfFile = 'load/fall.swf';
launchSWF(container, swfFile);
addChild(container);
}
function face_bClick(e:MouseEvent):void {
swfFile = 'load/face.swf';
launchSWF(container, swfFile);
addChild(container);
}
function rott_bClick(e:MouseEvent):void {
swfFile = 'load/rottgut.swf';
launchSWF(container, swfFile);
addChild(container);
}

I have this rewritten. I could not get the vBox errors cleared in the original code, and I was getting many other errors with what was posted. The vBox code was seen on a tutorial. I think it was supposed to reference the loader for the preloader and the swf, and vFile was for the actual .swf. The following code preloads multiple swfs and clears them with no errors. I appreciate your help AntBirch. I'm beginning to understand loaders in as3 a little more now.
//LOAD FIRST PIECE ON OPEN (required to removeChild later)
var swfLoader:Loader = new Loader();
var defaultSWF:URLRequest = new URLRequest("load/fall.swf");
swfLoader.load(defaultSWF);
swfLoader.x = 165;
swfLoader.y = 15;
addChild(swfLoader);
//PRELOADER
var preLoader:loader = new loader();
preLoader.x = 450;
preLoader.y = 280;
function loadProdComplete(e:Event):void {
trace("swf file loaded");
removeChild(preLoader);
addChild(swfLoader);
}
function onProgressHandler(event:ProgressEvent){
var dataAmountLoaded:Number=event.bytesLoaded/event.bytesTotal*100;
preLoader.lpc.text= int(dataAmountLoaded)+"%";
}
//BUTTONS
function btnClick(event:MouseEvent):void {
swfLoader.unloadAndStop();
removeChild(swfLoader);
swfLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgressHandler);
swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadProdComplete);
addChild(preLoader);
var newSWFRequest:URLRequest = new URLRequest("load/" + event.target.name + ".swf");
swfLoader.load(newSWFRequest);
swfLoader.x = 165;
swfLoader.y = 15;;
addChild(swfLoader);
}
// BUTTON LISTENERS
fall.addEventListener(MouseEvent.CLICK, btnClick);
face.addEventListener(MouseEvent.CLICK, btnClick);
rott.addEventListener(MouseEvent.CLICK, btnClick);
angel.addEventListener(MouseEvent.CLICK, btnClick);
ratts.addEventListener(MouseEvent.CLICK, btnClick);
metal.addEventListener(MouseEvent.CLICK, btnClick);
//etc...
//BACK BUTTON
BB3.addEventListener(MouseEvent.CLICK, BB3Click);
function BB3Click(e:MouseEvent):void {
swfLoader.unloadAndStop();
removeChild(swfLoader);
this.gotoAndPlay(1 ,"Scene 2")
}

Related

How to stop the timer and move to next scene when puzzle is solved

I created a jigsaw in action script and kept it a separate class. In the project i linked the code and i added a timer to the scene so that the player have to solve the puzzle within the time specified. Now what i want is that if the player solved the puzzle correctly the timer will stop and go to next scene.
this is the puzzle.as
var xpos:Array=new Array();
var ypos:Array=new Array();
var numDone,i:int;
var numPieces:int=3;
var dif:int=25; //how close do they have to drag the piece
var sound:Sound=new Sound();
function playSound(file:String): void {
//var sound:Sound=new Sound();
var req:URLRequest=new URLRequest(file);
sound.load(req);
sound.play();
} //playSound
function scramble(): void {
for(i=0;i<numPieces;i++){
this["piece"+i].x=Math.random()*300;
this["piece"+i].y=Math.random()*500;
this["piece"+i].alpha=.8;
} //for each piece
numDone=0;
txtMessage.text="Drag the pieces to solve the puzzle";
sound.close();
} //scramble
function init(): void {
for(i=0;i<numPieces;i++){
xpos[i]=this["piece"+i].x;
ypos[i]=this["piece"+i].y;
this["piece"+i].addEventListener(MouseEvent.MOUSE_DOWN, beginMove);
this["piece"+i].addEventListener(MouseEvent.MOUSE_UP, endMove);
} //for each piece
txtMessage.text="Drag the pieces to solve the puzzle";
} //init
function beginMove(e:MouseEvent): void {
if(e.target.alpha<1)
e.target.startDrag();
} //beginMove
function endMove(e:MouseEvent): void {
if(e.target.alpha<1) {
e.target.stopDrag();
//figure out which piece it is
var piece:int=0;
while(e.target!=this["piece"+piece]){
piece++;
} //
var curX:int=this["piece"+piece].x;
var curY:int=this["piece"+piece].y;
if(curX<=xpos[piece]+dif && curX>=xpos[piece]-dif &&
curY<=ypos[piece]+dif && curY>=ypos[piece]-dif) { //close enough
this["piece"+piece].x=xpos[piece];
this["piece"+piece].y=ypos[piece];
this["piece"+piece].alpha=1;
numDone++;
if(numDone>=numPieces) gameOver();
else playSound("http://www.zebra0.com/langResource/ok.mp3");
} //in position
} //not already done
}//endMove
function gameOver(): void {
txtMessage.text="You did it!";
playSound("http://www.zebra0.com/langResource/win.mp3");
gotoAndStop(1,"Scene 2");
} //gameOver
function scrambleHandler(e:MouseEvent): void {
scramble();
} //clickHandler
btnScramble.addEventListener(MouseEvent.CLICK,scrambleHandler);
function solve(e:MouseEvent): void {
for(i=0;i<numPieces;i++) {
this["piece"+i].x=xpos[i];
this["piece"+i].y=ypos[i];
this["piece"+i].alpha=1;
} //for each piece
} //solve
the code for linking the puzzle.as to the project. i kept in a layer called 'ActionScript'
include "Puzzle.as"
numPieces=20;
init();
scramble();
stop();
timer code i kept in a layer called 'action'
var nCount:Number = 90;
var myTimer:Timer = new Timer(1000, nCount);
timer_txt.text = nCount.toString();
myTimer.start();
myTimer.addEventListener(TimerEvent.TIMER, countdown);
myTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onComplete);
function countdown(e:TimerEvent):void
{
nCount--;
timer_txt.text = nCount.toString();
}
function onComplete(e: TimerEvent):void{
gotoAndStop(35);
}
if any one have an idea of how to achieve this.

AS3: Always reloading swf? Why?

I have a Homepage, which plays a mainSWF. In this mainSWF I have a loader, that loads external swfs from my server. With a button you can unload this external swfs an load a different one. Some of this swfs are 30mb big.
So, here is my problem:
The external SWFs are never saved temporary, or something like that. So you have to load all the 30mb everytime again. Is there a workaround or a configuration or something?
Thanks for answering!
var _swfLoader:Loader;
var _swfContent:MovieClip;
function loadSWF(path:String):void {
var _req:URLRequest = new URLRequest();
_req.url = path;
_swfLoader = new Loader();
setupListeners(_swfLoader.contentLoaderInfo);
_swfLoader.load(_req);
}
function setupListeners(dispatcher:IEventDispatcher):void {
dispatcher.addEventListener(Event.COMPLETE, addSWF);
dispatcher.addEventListener(ProgressEvent.PROGRESS, preloadSWF);
}
function preloadSWF(event:ProgressEvent):void {
var _perc:int = (event.bytesLoaded / event.bytesTotal) * 100;
// swfPreloader.percentTF.text = _perc + "%";
}
function addSWF(event:Event):void {
event.target.removeEventListener(Event.COMPLETE, addSWF);
event.target.removeEventListener(ProgressEvent.PROGRESS, preloadSWF);
_swfContent = event.target.content;
_swfContent.screen_demo_close_btn.addEventListener(MouseEvent.CLICK, unloadSWF);
addChild(_swfContent);
}
function unloadSWF(event:Event):void {
if (MovieClip(root).onDemo == 1) {
MovieClip(root).resetDevices();
_swfLoader.unloadAndStop();
removeChild(_swfContent);
_swfContent = null;
MovieClip(root).onDemo = 0;
}
}

action script 3.0 .I had tried a program that should move the dragger as well as the content movieclip,

In this code i need a progressbar to progress through while the imported .swf file is playing, meanwhile i should able to drag the dragger in the progress bar (i.e the rate of movement of dragger should sync with rate of .swf file playing). I got Argument error: #2109 Frame label 459.99 not found in scene1.
var loader:Loader = new Loader();
playBtn.visible = true;
pauseBtn.visible = false;
btn_00.addEventListener(MouseEvent.CLICK, fileLoaded);
btn_01.addEventListener(MouseEvent.CLICK, fileLoaded);
btn_02.addEventListener(MouseEvent.CLICK, fileLoaded);
function fileLoaded(evt:MouseEvent):void
{
var fileName:String = evt.currentTarget.name;
var fileNumber:String = fileName.split("_")[1];
var urlPath:String = "assets/file_" + fileNumber + ".swf";
loader.load(new URLRequest(urlPath));
addChild(loader);
}
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, swfLoaded);
function swfLoaded(event:Event):void
{
addEventListener(Event.ENTER_FRAME, trackPlayback);
}
function trackPlayback(event:Event):void
{
var perPlayed:Number = MovieClip(loader.content).currentFrame / MovieClip(loader.content).totalFrames;
progressbar.drag.x = (progressbar.bar.width - progressbar.drag.width) * perPlayed;
}
progressbar.drag.buttonMode = true;
var dragClicked:Boolean = false;
var xpos:Number = progressbar.bar.x * progressbar.drag.width;
progressbar.drag.addEventListener(MouseEvent.MOUSE_DOWN,dragMouseDown);
function dragMouseDown(evt:MouseEvent):void
{
trace(" inside mouse down ");
dragClicked = true;
progressbar.drag.startDrag(false,new Rectangle(xpos,0,progressbar.width-progressbar.drag.width,0));
}
progressbar.drag.addEventListener(MouseEvent.MOUSE_UP,dragMouseUp);
function dragMouseUp(evt:MouseEvent):void
{
dragClicked = false;
progressbar.drag.stopDrag();
var cnt:Number = (progressbar.drag.x/(progressbar.width-progressbar.drag.width))*MovieClip(loader.content).totalFrames;
MovieClip(loader.content).gotoAndPlay(cnt);
}
Pls solve my issue.
Thanks in advance.
To access a specific frame, you need to provide an integer value where at the moment you are using a floating-point value.
A simple fix would be to cast the Number to an int:
MovieClip(loader.content).gotoAndPlay(int(cnt));

eventlistener doesn't execute its function

I need to put some thumbnails on the stage. they have different width and I need to get the width after They are loaded.I used the listener to find the width but the function which listener should call doesnt run.
why my code doesn't enter to the function of loadThumbs?
function makeScroller():void
{
for (var item:uint = 0; item < 7; item++ )
{
var thisOne:MovieClip = new MovieClip();
var blackBox:Sprite = new Sprite();
var thisThumb:Sprite = new Sprite();
var imageLoader:Loader = new Loader();
imageLoader.load(new URLRequest(thumbList[item]));
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadThumbs);
function loadThumbs (e:Event):void
{
blackBox.graphics.beginFill(0xFFFFFF);
blackBox.graphics.drawRect(-1,-1,imageLoader.width,imageLoader.height);
thisOne.addChild(blackBox);
thisOne.blackBox = blackBox;
thisOne.x = tsX;
thisThumb.addChild(imageLoader);
thisOne.addChild(thisThumb);
tsX += imageLoader.width;
scroller.addChild(thisOne);
}
}
}
I have just tried a more simplified version of your code without any issues, maybe try this:
NOTE: Best practice is to add the COMPLETE listener BEFORE you call load also...
function makeScroller():void
{
var imageLoader:Loader = new Loader();
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadedHandler);
imageLoader.load(new URLRequest("http://images.imagecomics.com/c/2012/IMG120350.jpg"));
function loadedHandler(e:Event):void
{
trace("loaded");
}
}
makeScroller();

onPlayStatus as3

New to this one. Have this code for viewing multiple netstream events. Want to use the onPlayStatus to loop the "flv/intro.flv" and for the rest of the videos, I would like them to return to the intro.flv after they are done playing, but I can't find anything that helps enough. Can anyone offer a link or some help with the function? Here is my code so far :
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
var metaDataListener:Object = new Object();
metaDataListener.onMetaData = function(meta:Object){
}
ns.client = metaDataListener
var myVideo:Video = new Video(800, 600);
myVideo.x = 0;
myVideo.y = 0;
addChild(myVideo);
setChildIndex(myVideo, 0);
myVideo.attachNetStream(ns);
ns.play("flv/intro.flv");
duetBTN.addEventListener(MouseEvent.CLICK, playVideo1);
vantageBTN.addEventListener(MouseEvent.CLICK, playVideo2);
cabrioBTN.addEventListener(MouseEvent.CLICK, playVideo3);
classicBTN.addEventListener(MouseEvent.CLICK, playVideo4);
laundryBTN.addEventListener(MouseEvent.CLICK, playVideo5);
resourceBTN.addEventListener(MouseEvent.CLICK, playVideo6);
industryBTN.addEventListener(MouseEvent.CLICK, playVideo7);
homeBTN.addEventListener(MouseEvent.CLICK, playVideo8);
function playVideo1(e:MouseEvent):void {
ns.play ("flv/duet.flv");
}
function playVideo2(e:MouseEvent):void {
ns.play("flv/vantage.flv");
}
function playVideo3(e:MouseEvent):void {
ns.play("flv/cabrio.flv");
}
function playVideo4(e:MouseEvent):void {
ns.play("flv/classic.flv");
}
function playVideo5(e:MouseEvent):void {
ns.play("flv/laundry.flv");
}
function playVideo6(e:MouseEvent):void {
ns.play("flv/resource.flv");
}
function playVideo7(e:MouseEvent):void {
ns.play("flv/industry.flv");
}
function playVideo8(e:MouseEvent):void {
ns.play ("flv/intro.flv");
}
You can attach an event listener to the NetStream object that detects when a video has finished playing.
var introPlayer:NetStream = new NetStream(nc); // nc refers to shared net connection declared earlier
var introVid:Video = new Video(800, 600);
ns.addEventListener(NetStatusEvent.NET_STATUS, checkStreamStatus);
function checkStreamStatus(e:NetStatusEvent):void {
switch (e.info.code) {
case "NetStream.Play.Complete":
playIntro();
break;
}
};
function playIntro():void {
addChild(introVid);
introVid.attachNetStream(introPlayer);
introPlayer.play("flv/intro.flv");
}
Have changed the code completely to match the set-up you were using originally. This is how you're supposed to do it, apologies for previous answer. This is the correct way of doing it though.
If NetStream.Play.Complete is not dispatched, replace it with:
NetStream.Play.Stop or NetStream.Buffer.Flush