Clicking on a movieclip inside another movieclip on AS3 - actionscript-3

Alright, what i need it's simple but its driving me crazy, i want to know if AS3 detects my mouse inside a movieclip.
For example, i have a movieclip instanced "BEframes" which is inside movieclip "BE1" and i want to put him inside a new movieclip instanced "roll". So the order would be roll > BE1 > BEframes.
I want to know if flash will only detect "roll" or he will detect all movieclips, thank you,
for(i=1;i<=77;i++){
var str:String =("BE" + i);
this[str].BEframes.gotoAndStop(i);
this[str].addEventListener(MouseEvent.CLICK, clique);
this[str].addEventListener(MouseEvent.ROLL_OVER, over);
this[str].addEventListener(MouseEvent.ROLL_OUT, out);
}
function clique(evt:MouseEvent):void{
var botao:String = evt.currentTarget.name.toString();
var num:String = botao.replace("BE", "");
parede_esquerda.gotoAndStop(num);
}
function out(evt:MouseEvent):void {
evt.currentTarget.gotoAndPlay("out");
}`enter code here`
function over(evt:MouseEvent):void {
evt.currentTarget.gotoAndPlay("over");
}
*

Probably, you should use MOUSE_OVER and MOUSE_OUT instead of ROLL_OVER and ROLL_OUT.
this[str].addEventListener(MouseEvent.MOUSE_OVER, over);
this[str].addEventListener(MouseEvent.MOUSE_OUT, out);

To avoid receiving mouseEvent for movieClips set mouseEnabled to false, i.e if you don't want clip roll's mouse event setroll.mouseEnabled = false so that the object below will receive mouseEvent

Related

Spawn MC addChild to stage but how to tie in the draggable function? AS3

I'm running into some problems with making the movie clip so I can drag it about the stage. The scenario: the user clicks a button that spawns the movie clip to the stage, from there they can move the item around the stage - it's a draggable object. I can make it so the movieClip spawns, I can make it so it drags... but i can't make it do both, once I try to attach the drag function. Any pointers please? I'm new to as3! :-)
spawner_btn.addEventListener(MouseEvent.CLICK, spawnspinkjewel);
function spawnspinkjewel(event:MouseEvent):void
{
var myChild:pink_jewel= new pink_jewel();
stage.addChild(myChild)
myChild.x=300;
myChild.y=150;
}
pink_jewel.addEventListener(MouseEvent.MOUSE_DOWN, pickupblack_pink_jewel);
pink_jewel.addEventListener(MouseEvent.MOUSE_UP, dropblack_pink_jewel);
function pickupblack_pink_jewel(event:MouseEvent):void {
event.target.startDrag(true);
}
function dropblack_pink_jewel(event:MouseEvent):void {
event.target.stopDrag();
}
You added the listeners to the incorrect object.
Change this:
pink_jewel.addEventListener(MouseEvent.MOUSE_DOWN, pickupblack_pink_jewel);
pink_jewel.addEventListener(MouseEvent.MOUSE_UP, dropblack_pink_jewel);
To this:
myChild.addEventListener(MouseEvent.MOUSE_DOWN, pickupblack_pink_jewel);
myChild.addEventListener(MouseEvent.MOUSE_UP, dropblack_pink_jewel);

AS3 Getting to Control Stage

I am building a Flash Game, I am doing this:
MainStage, with 11 frames
Mainstage Loads > Lobby.swf (1 frame)
Lobby Loads > Arrows.swf (1 frame)
I just want to control the main Stage from Arrows.swf , get the current frame, right arrow mainStage.current frame + 1, left arrow mainStage.current frame -1
I have tried the parent/child method
this.parent.parent
parent.parent
this.root
parent.root
every combination, I am also tracing and when I finally hit the mainStage it is saying cannot convert Stage to Display Object which I understand.
but how can I just get current frame of the "mainstage" needle and control it with gotoAndPlay or other such methods ?
I have solved it.
I didn't control the main stage what I did was, I reduced the main stage layer in the lobby layer when I load the left and right arrow I attach an event listener for a custom event.
In the arrows movie I have written a function to dispatch the event here are the lines of code I used
in the "main" stage of the movie you want to control:
//ball loader prep and load
var ballLoader:Loader = new Loader();
var ballRequest:URLRequest = new URLRequest("lobbyBalls.swf");
ballLoader.load(ballRequest);
ballLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, ballsLoaded);
function ballsLoaded(event:Event):void{
trace("ball Loader complete");
ballLoader.x = 50;
ballLoader.y = 200;
stage.addChild(ballLoader);
ballLoader.content.addEventListener("Previous", ctrlPrevFrame);
ballLoader.content.addEventListener("Next", ctrlNextFrame);
}
In the movie from which you want to control
import flash.events.Event;
leftArrow.addEventListener(MouseEvent.CLICK, prevEvent);
rightArrow.addEventListener(MouseEvent.CLICK, nextEvent);
function prevEvent(event:Event):void{
trace("prev");
dispatchEvent(new Event("Previous", true));
}
function nextEvent(event:Event):void{
trace("next");
dispatchEvent(new Event("Next", true));
}
Thanks anyways....

Bubble click event in swf

I try to add a MovieClip to an existent SWF on the fly - inject an small code who do something like:
this.obj = new MovieClip(); // it is inside an object
obj.name = 'FLOOR';
obj.graphics.beginFill(0xFFFFFF, 0);
obj.graphics.drawRect(0,0,self.width, self.height);
obj.graphics.endFill();
obj.buttonMode = true;
self.addChildAt( floorLayerMC , 0); /* self is an reference for the this keyword, reference for the entire swf */
My question is: this SWF has many elements like images and textfields, and some of this elements has no event handler for click. I Need to find a way to "redirect" all of the events to my "FLOOR" element, using something like bubbling the event.
Of course, I can add the FLOOR in top of any elements BUT I have some elements with click handler. I can't ignore all of the elements. So my problem is:
if I click over an MovieClip with click handler, perform the original action.
if I click over an MovieClip without click handler, perform the FLOOR action.
I can't add a event handler in all of the elements.
Any Idea?
Listen for a click on the container movieclip's own stage (the movieclip that contains the FLOOR). In the handler method for the click event, do a hit test using hitTestPoint with the mouseX and MouseY of the container movieclip, and if the mouse is over any clickable objects, ignore the stage click. Store all the objects that are clickable in an array to do that test.
This code is untested but it would go something like this:
var exemptArray:Array = [ btn_mc1, btn_mc2, btn_mc3 ];
containerMC.stage.addEventListener(MouseEvent.CLICK, onClickMyMC);
function onClickMyMC( event:Event ):void
{
for(var i:int = 0; i < exemptArray.length; i++)
{
if( exemptArray[i].hitTestPoint(containerMC.mouseX, containerMC.mouseY) )
{
// do nothing, ignore the stage click ( and let the object with the click respond )
break;
}
else
{
// respond to the stage click
}
}
}
To build the exemptArray without knowing what objects are clickable ahead of time:
( untested but should be close enough to give you an idea ).
var exemptArray:Array = buildExemptArray();
function buildExemptArray():Array
{
var arr:Array = [];
for(var j:int = 0; j < containerMC.numChildren; j++)
{
if( containerMC.getChildAt(i).hasEventListener(MouseEvent.CLICK) )
{
arr.push( containerMC.getChildAt(i) );
}
}
return arr:
}
EDIT TO ANSWER QUESTION IN COMMENTS:
this.addEventListener(MouseEvent.CLICK, onClick) will add a click event to the whole object, children included.
this.stage.addEventListener(MouseEvent.CLICK, onClick) will add a click only to the movieclip's stage, not its children as well.
In as3 all movieclips have a stage property. If you wrote on the main timeline this.stage.addEventListener(MouseEvent.CLICK, onClick); that would be adding a stage click to the whole swf. But, if you wrote something like myMC.stage.addEventListener(MouseEvent.CLICK, onClick); it would only add a click to that movieclip's stage (myMC's stage). Since stage is below the display list, you can capture a click there in any movieclip. If you don't have access to all the objects that have mouse events ahead of time, you could loop through all the container's children and check if they have a mouseEvent with .hasEventListener(MouseEvent.CLICK);, create your exemptArray from that, then use the same logic above to ignore items in the exemptArray.

Why does this not work? Flash As3, if added child is at frame something?

This is my code help me please its really frustrating!
I have a movieclip in my library and added it with AS3 to the stage.
That part was easy. But now i want to control that movieclip.
If introScene "introClass" Reaches frame 120 then i want to remove that movieclip
and replace it with another one. The problem is the if statement doesn't work.
I also tried getChildByName but that didn't work either.
var introClass = new introScene;
addChild(introClass);
introClass.x = 640;
introClass.y = 387;
/*******INTRO-SCENE*******/
introClass.addEventListener(Event, introLoaded);
function introLoaded(event):void{
if(introClass == 120 ){
trace("Frame Reached")
}
}
i tried this and this also doesn't work :(
introClass.addEventListener(Event, introLoaded);
function introLoaded (e:Event):void{
if(MovieClip(introClass).currentFrame == 120){
trace("120 complete")
}
}
This is wrong statement:
introClass.addEventListener(Event, introLoaded);
You need to pass a string to addEventListener. Event type name is converted to a string at runtime which adds a event listener to "flash.events.Event" or something. And your object obviously doesn't have this event. You need to use Event.ENTER_FRAME for example.

Adding stop(); to a movieclip on the timeline is causing the tweens in said movieclip to not play, the movieclip just skips to the end

I've got a movieclip that is composed of 3 separate symbols. 2 of the symbols have their alpha tweened over 60 frames. 1 of the symbols is not tweened at all. All symbols are in separate layers, and there is a 4th, empty layer with a keyframe on frame 60 for actionscript.
The actionscript on frame 60 is simply "stop();" .
I am adding an instance of the movieclip to the stage dynamically from the document class. When I have "stop();" in there, the movieclip appears on the stage and skips straight to frame 60, where it succesfully stops.
Without "stop();" in there, the movieclip plays the alpha tweens perfectly, but obviously continuously loops.
Manually dispatching an Event.COMPLETE and listening for it does not work either and I would prefer not doing it that way anyway.
Here is the code that adds the movieclip to the stage:
//initialize the gameplay, remove title screen.
private function initialize_gameplay():void
{
//remove the title screen
initialize_title_screen(true);
this.screen_transition_obj = new tide_out_video();
this.addChild(this.screen_transition_obj);
this.game_board = new tidepool_gameboard();
this.screen_transition_obj.addEventListener(Event.COMPLETE,swap_transition_video_for_screen);
}
//replace the current transition video with the screen it was transitioning to
private function swap_transition_video_for_screen(e:Event){
this.addChild(this.game_board);
if(this.screen_transition_obj != null){
if(this.getChildByName(this.screen_transition_obj.name)){
this.removeChild(this.screen_transition_obj);
}
this.screen_transition_obj.removeEventListener(Event.COMPLETE, swap_transition_video_for_screen);
this.screen_transition_obj = null;
}
}
The movieclip's class is tidepool_gameboard and the property of the document class that stores the reference to it is game_board.
Any idea why putting stop(); on frame 60 of the movie clip is causing it to skip to the end without tweening?
UPDATE:
Adding the movieclip to the stage instantly instead of as the result of an event listener works properly, the problem only occurs when the movieclip is added in the event listner.
I can't believe I overlooked this, as it appears to be fairly obvious to me now.
In the code posted in the question, I've initialized a new instance of this.game_board, then added it to the stage after a delay based on an event listener for a video clip. The animation is playing, but it's playing before the clip ever is added to the stage.
Thanks go to alecmce who answered this question.
I did his Event.ADDED_TO_STAGE event listener, and it worked, which led me to realize that the MovieClip does not wait until it is added to the stage to start playing its own timeline, it simply starts the second you instantiate the object.
This is the new, fully functional code:
//initialize the gameplay, remove title screen.
private function initialize_gameplay():void
{
//remove the title screen
initialize_title_screen(true);
this.screen_transition_obj = new tide_out_video();
this.addChild(this.screen_transition_obj);
this.screen_transition_obj.addEventListener(Event.COMPLETE,swap_transition_video_for_screen);
}
//replace the current transition video with the screen it was transitioning to
private function swap_transition_video_for_screen(e:Event)
{
this.game_board = new tidepool_gameboard();
this.addChild(this.game_board);
if (this.screen_transition_obj != null)
{
if (this.getChildByName(this.screen_transition_obj.name))
{
this.removeChild(this.screen_transition_obj);
}
this.screen_transition_obj.removeEventListener(Event.COMPLETE, swap_transition_video_for_screen);
this.screen_transition_obj = null;
}
}