MovieClip doesn't dispatch mouse event after nesting MovieClip loaded from external SWF - actionscript-3

Mostly, problem is described in the title... I tried to load an external SWF file that contains some named MovieClip instances (exporting and naming is done by Flash CS5 software) and to add some of externaly loaded (named) MovieClip-s in MovieClip object which is created in my code. Problem appears when i add MOUSE_CLICK listener to parent MovieClip. Simply, it does not dispatch event when i click on it at the stage...
private var loader:Loader;
public function Example(){
loader = new Loader();
var request:URLRequest = ... // URL to external SWF
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadingCompleted)
loader.load(request);
}
private function loadingCompleted(event:Event):void{
var mc:MovieClip = loader.content as MovieClip;
var myMovie:MovieClip = new MovieClip();
myMovie.addChild(mc.getChildByName("object_name"));
myMovie.addEventListener(MouseEvent.CLICK, myMovieClicked);
addChild(myMovie); // myMovie (with nested mc) appears on the stage
}
private function myMovieClicked(evt:Event):void{
//never reached
}
EDIT: I didn't mention that i'm working in Flex using FlashBuilder 4.5 where i created ActionScript project. Code above is body of Example class, which is main SWF class.
EDIT AFTER ANSWER: myMovie.mouseChildren = false solves the problem. Earlier i tried to set mouseEnabled = true, and it didn't fix the problem. But i'm confused about event flow now... Even if child is target node, why mouse listener on parent MovieClip doesn't recieve event (in capture phase) when parent is still on event flow? Moreover, when i create another movie clip in my code (whit some simple shape inside) and add it to myMovie, everything works fine. What is so special when i obtain movie clip from externaly loaded SWF?

Have you tried doing myMovie.mouseEnabled = true and myMovie.mouseChildren = false ?

Related

remove external swf file as3

I have loaded an external swf file which plays a flv file by default as swf is loaded. Now the problem is how do i remove the swf file from memory. my code :
var myLoader:Loader = new Loader();
var url:URLRequest = new URLRequest("ExternalSWF.swf");
myLoader.load(url);
detailMovieClip.movieHolder.addChild(myLoader);
I have tried many combinations of removeChild, unload and unloadAndStop but none works. I figure its all about not referencing correctly.
Update:
I went with the answer from Jegan, but it only work when i am testing in a dummy project which has only 1 numChildren, howver in real world code example numChildren reported 22 so i am not sure if that would be an issue. here is the real world code:
var myImageLoader:Loader;
var myImageRequest:URLRequest;
var theImagePath:String;
//part from xml processor function
theImagePath = "flash/"+myXML..item_video_link[n];
loadTheMovie(theImagePath);
function loadTheMovie(theImagePath):void{
myImageLoader = new Loader();
myImageRequest= new URLRequest(theImagePath);
myImageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,showMeTheVideo);
myImageLoader.load(myImageRequest);
}
function showMeTheVideo(evt:Event):void{
detailsMovieClip_mc.details_video_holder.dynamicVideoHolder.addChild(myImageLoader);
}
stopVideo(sectionname):viod{
if(detailsMovieClip_mc.details_video_holder.dynamicVideoHolder.numChildren !=0){
trace("what is the number of children: "+numChildren);
myImageLoader.unloadAndStop();
detailsMovieClip_mc.details_video_holder.
dynamicVideoHolder.removeChild(myImageLoader);
}
}
stage.addEventListener(MouseEvent.CLICK, removeSWF);
function removeSWF (e:MouseEvent):void
{
if(detailMovieClip.movieHolder.numChildren !=0){
myLoader.unloadAndStop();
detailMovieClip.movieHolder.removeChild(myLoader);// empty the movieClip memory
}
}
OR
Name your Loader instance and then search by using getChildByName
myLoader.name = "myloader";
function removeSWF (e:MouseEvent):void
{
if(detailMovieClip.movieHolder.numChildren !=0){
Loader(detailMovieClip.movieHolder.getChildByName("myloader")).unloadAndStop();
detailMovieClip.movieHolder.removeChild(detailMovieClip.movieHolder.getChildByName("myloader"));// empty the movieClip memory
}
}
I guess this is because you are adding the loader to the scene itsef.
Either you want to keep this behavior, in this case there is a quick fix, remove the loader from the MovieClip by using removeChild(), then set the reference to null, or use the delete keyword.
Either you want to do it properly, in this case, listen for the LOADED event, adds the MovieClip contained by the loader.content to the target MovieClip. Then, when you want to unload it, remove the clip from the container using removeChild(), then loader.unload().

Access children of embedded aswf

I am embedding an swf file that has some children on its timeline. Like this:
[Embed(source="assets/skyscraper200x600.swf")]
private var Skyscraper :Class;
All children in the swf have an instance name, I double checked that when creating the swf in Flash CS5.
I am trying to access those children by name like this:
_bg = MovieClip(new Skyscraper());
_pig = MovieClip(_bg.getChildByName("chara_pig"));
_arrow = MovieClip(_bg.getChildByName("arrow_banner"));
However, both _pig and _arrow end up being null.
What's even stranger is that when I look at the Skyscraper object in the debugger, it shows a rather strange class name and a Loader as its only child (which in turn has no children). What's up with this?
.
I can access them like above if I do not embed the swf, but load it with a Loader. But I cannot do it in this case. I need to embed the swf.
So, how can you access children of embedded swfs?
I am not talking about accessing classes in the library of the embedded swf, but the instances on the timeline.
Here is a solution. You can also see the steps who helped me find this solution (describeType is your friend) :
public class Demo extends Sprite {
[Embed(source="test.swf")]
private var Test:Class
public function Demo() {
//first guess is that embed SWF is a MovieClip
var embedSWF:MovieClip = new Test() as MovieClip;
addChild(embedSWF);
//well, emebed SWF is more than just a MovieClip...
trace(describeType(embedSWF));//mx.core::MovieClipLoaderAsset
trace(embedSWF.numChildren);//1
trace(describeType(embedSWF.getChildAt(0)));//flash.display::Loader
var loader:Loader = embedSWF.getChildAt(0) as Loader;
//the content is not already loaded...
trace(loader.content);//null
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(){
var swf:MovieClip = loader.content as MovieClip;
var child:MovieClip = swf.getChildByName("$blob") as MovieClip;
//do nasty stuff with your MovieClip !
});
}
}
At the end of this tutorial http://jadendreamer.wordpress.com/2010/12/20/flash-as3-embedding-symbols-from-external-swf-game-tutorial there is an example of how it can be done
One solution is to embed the swf as an octet stream and reconstitute its bytes. However, I seem to remember reading somewhere that if you just set the mimeType to "application/x-shockwave-flash", you get a MovieClip that works as normal.

Looking for AS3 event when MovieClip is initialised like AS2 onclipevent(load)

In AS2 there was an event onclipevent(load) that triggered when a movie clip was initialised on the stage. I have searched a lot but the only solution I can find for the same functionality in AS3 is to make a custom class for the movie clip. This is a bit overkill in my case as I only have one line of code to run and I'm trying to avoid lots of extra AS files in my project. I should note that my MovieClips are not dynamically added so events like Event.ADDED_TO_STAGE etc will not work.
Is there really no way to do onclipevent(load) in AS3?
There are no AS2 style clip events in AS3. If you want to avoid making a custom class for your clip, you could put the initialization code in a function and call it immediately when you create the clip, like this:
import flash.display.MovieClip;
function onClipLoad(clip : MovieClip) : void
{
// do onLoadStuff here
clip.x = 100;
clip.y = 10;
}
// call onClipLoad when the clip is created, either in code or via timeline
var myClip : MovieClip = new MyClip();
onClipLoad(myClip);
Even better, you could place this code on frame 1 of your MovieClip's timeline to automatically initialize instances of it:
var initialized : Boolean;
if(!initialized) {
initialized = true;
// do init code here
x = 100;
y = 10;
}

ActionScript: Adding multiple instances of the same swf file to the stage

I'm creating a game in ActionScript 3.0 using the FlashPunk game engine and the FlashDevelop SDK.
I've created my own MovieClip class that takes a preloaded movie clip file.
public function MyMovieClip(file:MovieClip, posX:int, posY:int, frameRate:int)
{
movieClip = file;
movieClip.x = posX;
movieClip.y = posY;
movieClip.stop();
FP.stage.addChild(movieClip);
timer = new Timer((1 / frameRate) * 1000);
timer.start();
timer.addEventListener(TimerEvent.TIMER, onTick);
}
The update for my movie clip is as follows:
private function onTick(e:TimerEvent):void
{
if (isRepeating)
{
if (movieClip.currentFrame == movieClip.totalFrames )
{
movieClip.gotoAndStop(0);
}
}
movieClip.nextFrame();
}
The problem that I'm having is that when I have multiple instances of the MyMovieClip class using the same swf file, only the last instance is rendered and is updated for each instance of the class that I have.(e.g 3 instances of MyMovieClip, the last instance is updates at 3 times the speed.)
If anymore info is needed I'll be happy to supply it.
You can create a new instance of the same loaded swf by doing this:
// re-use a loaded swf
var bytes:ByteArray = existingLoader.content.loaderInfo.bytes;
var loader:Loader = new Loader();
loader.loadBytes(bytes);
where existingLoader is the Loader that you used to load the swf in the first place.
The Loader used with loadBytes will dispatch another COMPLETE Event, so when you make a listener for that, you can use the 'cloned' version:
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onSWFClonedComplete);
You may have multiple instances of MyMovieClip, but what's with file:MovieClip which you are adding to the stage. If this is always the same instance of a MovieClip you will have this result, regardless how often you instantiate your MyMovieClip class, because you are adding the same instance multiple times to the stage.
You may have to load the "preloaded clip" multiple times or, if you are able to (you know the class name etc.), create a new instance of the desired class with getDefinitionByName() from your loaded clip and attach this new instance.

ActionScript 3 stage question HELP!

I have a 1.swf loads up a another 2.swf, while i doing things inside 2.swf like
1.swf is bigger
2.swf is smaller inside
stage.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
it keep refer to the parent's stage instead the 2.swf's stage.
Please help out. thanks
There is only one stage object, and it is always inherited from the root. Anytime you can access the property "stage" inside a DisplayObject (Sprite,MovieClip) it's actually just a reference to the root.stage that gets populated whenever that DisplayObject is added to the root stage, or a child of some object that eventually connects to the stage (the display list). The display list is just an object tree of various display objects that are connected to the root stage. Anyway so, about your question, if you just want to listen for events on your loaded swf do something like this:
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
loader.load(new URLRequest("swf2.swf"));
private function loadComplete(e:Event):void
{
var swf2Clip:MovieClip = loader.content as MovieClip;
swfClip.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
}
private function onMouseOut(e:MouseEvent):void
{
//Do something when swf2 is moused out.
}