Problems disabling movieclip button flash/as3 - actionscript-3

I've got a screen which involves a movie-clip where the object has a outline to symbolize that it can be clicked. Upon clicking the object, I'm requesting it to do numerous functions, disable itself and then go to another frame which removes the outline symbolizing it cannot be clicked anymore. But once you disable an object it goes to the original frame.
The object itself consists of these 3 frames.
Frame 1: Original State (Glow)
Frame 2: Hover over giving stats
Frame 3: No glow
To summerise i'd like to click the object and for it to go to the no glow frame and disable the movieclip.
The movieclip enabled = 1 is for when the user returns to the this frame, so the scene is aware of the button press.
Movieclip.addEventListener(MouseEvent.CLICK, Fun_Movieclip);
Movieclip.addEventListener(MouseEvent.MOUSE_OVER, Fun_MovieclipMouseOver);
Movieclip.addEventListener(MouseEvent.MOUSE_OUT, Fun_MovieclipMouseOut);
function Movieclip(event:MouseEvent):void
{
MovieclipEnabled = 1;
Movieclip.gotoAndStop(1);
Movieclip.mouseEnabled = false;
}
function Fun_MovieclipMouseOver(event:MouseEvent):void
{
Movieclip.gotoAndStop(2);
}
function Fun_MovieclipMouseOut(event:MouseEvent):void
{
Movieclip.gotoAndStop(3);
}
For some reason when ever the movieclip is disabled, it always reverts back to the glow state. Does anyone have a solution for this? Cheers
Edit: Inside the movieclip, the first frame has Stop();. Don't know if this would interfere with it.

mc.addEventListener(MouseEvent.CLICK, clickHandler);
mc.addEventListener(MouseEvent.MOUSE_OVER, mouseoverHandler);
mc.addEventListener(MouseEvent.MOUSE_OUT, mouseoutHandler);
function clickHandler(event:MouseEvent):void
{
mc.gotoAndStop(3);
mc.removeEventListener(MouseEvent.CLICK, clickHandler);
mc.removeEventListener(MouseEvent.MOUSE_OVER, mouseoverHandler);
mc.removeEventListener(MouseEvent.MOUSE_OUT, mouseoutHandler);
}
function mouseoverHandler(event:MouseEvent):void
{
mc.gotoAndStop(2);
}
function mouseoutHandler(event:MouseEvent):void
{
mc.gotoAndStop(1);
}
Not entirely sure what you meant by:
The movieclip enabled = 1 is for when the user returns to the this frame, so the scene is aware of the button press.
My suggestion for getting the scene to recognize the button click is to have the scene also listen to the mouse click handler

Related

out and over events dispatch together with down event after changing movie size

I have a MovieClip instance (movie) brought by code to the stage. I want to add some effects when mouse over or mouse down for this movie. So, first i added event listeners to this MovieClip:
movie.addEventListener(MouseEvent.MOUSE_DOWN, movieDownHandler);
movie.addEventListener(MouseEvent.MOUSE_UP, movieUpHandler);
movie.addEventListener(MouseEvent.MOUSE_OVER, movieOverHandler);
movie.addEventListener(MouseEvent.MOUSE_OUT, movieOutHandler);
Then i added event handlers:
private function movieDownHandler(e:MouseEvent):void {
trace("down");
}
private function movieUpHandler(e:MouseEvent):void {
trace("up");
}
private function movieOverHandler(e:MouseEvent):void {
trace("over");
}
private function movieOutHandler(e:MouseEvent):void {
trace("out");
}
And when i test it, everything goes ok: mouse over this movie, traces over, mouse down traces down, mouse up traces up and so on... But, when i add size change to the movie, for example, to mouse down handler like this:
private function movieDownHandler(e:MouseEvent):void {
trace("down");
movie.scaleX = 0.9;
movie.scaleY = 0.9;
}
and some filter effect to over handler, for example blurFilter:
private function movieOverHandler(e:MouseEvent):void {
trace("over");
e.currentTarget.filters = [new BlurFilter(1,1,1)];
}
then i receive unexpected behavior for event handlers: mouse over traces over (it is ok) and then i press (mouse down without releasing mouse button) at movie, then three events happen one after one: 'down', 'out', 'over' (mouse cursor don't leave MovieClip shape). What is the problem? Furthermore, setting scaleX and scaleY to 1.1 doesn't break handlers behavior
When you click a button,it go through three stage,first 'over',then 'down',then 'up',so it trace like that.
scareX has a range:0~1,the sacre is 0% ~ 100%

prevent next scene frame on movieclip mouseclick

I have a scene with a few objects as movieclips which can be clicked one at a time.
What happens is that I'm able to click every object and on click the scene switches to the next frame.
How do I change that?
Basically I have a key and a door, both movieclips.
You can collect the key, it disappears and after that you are able to click the door to open it.
What actually happens is you are both able to click the key and the door.
When you click the key, it's working as intended, but when you click the door, the key still disappears. This is much more annoying with more than 2 objects.
code for the key:
addEventListener(MouseEvent.CLICK, CollectKey);
function CollectKey(event: MouseEvent): void
{
this.visible = false;
// door
MovieClip(root).door.addEventListener(MouseEvent.CLICK, MovieClip(root).FinishGame);
}
code for the door:
stop();
function FinishGame(event: MouseEvent): void
{
if(MovieClip(root).currentFrame == 4)
{
nextFrame();
}
}
http://www.wuala.com/sollniss/stuff/Untitled-2.swf/
http://www.wuala.com/sollniss/stuff/Untitled-2.fla/
EDIT
After looking at your .fla, I can see your issue:
On your first frame, you have the following script:
stop();
addEventListener(MouseEvent.CLICK, StartGame);
function StartGame(event: MouseEvent): void
{
nextFrame();
}
You likely aren't aware that the mouse click listener you add there, doesn't go away until you tell it to (even if the frame changes). That's why every click calls next frame.
To remedy this, simply remove the listening before you move on to the next frame:
function StartGame(event: MouseEvent): void
{
removeEventListener(MouseEvent.CLICK, StartGame);
nextFrame();
}
And, may be that only visible false is not enough, you also need to set enabled = false and mouseEnabled = false for the key element, because without it, it will keep hearing the click event.

AS3 - Button inside MovieClip triggers MC's event

On stage, I have a MovieClip named "mc" with a simple rectangle drawn inside. mc also has a Button child named "btn" which is another simple rectangle ( smaller than mc's rectangle obviously). Then I have this code on stage.
function mcDown( _e:MouseEvent):void{
trace( "mc" );
}
function btnClick( _e:MouseEvent):void{
trace( "btn" );
}
mc.addEventListener( MouseEvent.MOUSE_DOWN, mcDown );
mc.btn.addEventListener( MouseEvent.CLICK, btnClick );
The problem I am having is when click the button, mcDown event is also triggered and traces both "mc" and "btn".
How can I make it so that when I click the button, it triggers only btnClick and not mcDown along? I tried MOUSE_UP instead of CLICK, same problem. And mcDown event has to remain MOUSE_DOWN.
There is no way to prevent bubbling except setting the bubbles parameter as false in the dispatchEvent.
dispatchEvent(EVENT_TYPE, BUBBLES,....);
However, you can avoid the bubbling by doing a check. Just have the below line as first line of your listener function it avoids the events dispatched from all objects other then targets.
if(e.eventPhase != EventPhase.AT_TARGET) return;
So, for your sample code, when you click on the button both the events dispatches but in the mcDown function it won't execute after the above said line.
If you add button in a MC, and you click on the button, you also click on the MC, because the part of the MC that is under the button is still there and it runes the function for the whole of the MC, you can't remove it.
So it's good idea to make a function that will check if the button is pressed, otherwise it will run the function for the whole of the MC.
This one should do it.
//add this in you constructor
mc.addEventListener(MouseEvent.MOUSE_DOWN, myReleaseFunc);
function myReleaseFunc(e:MouseEvent):void {
if(e.currentTarget.name == Btn1) //Btn1 is instance name for a button
{
Btn_func1();
}
else if(e.currentTarget.name == Btn2) //Btn2 is another button.
{
Btn_func2();
//For every button you'll need to add another function and if statement to check if that button was clicked.
}
else
{
Mc_func();
}
}
// this outside the main class
function Mc_func():void{
//you code here
}
function Btn_func1():void{
//you code here
}
function Btn_func2():void{
//you code here
}
I think that this way is much more effiecient and it will works better and faster and you'll have a lot smaller chance of overloading the system.

Timeline instances not on first frame

It's been a while since I've had to write Actionscript that really needs to integrate with the timeline (in this case, controlling a series of frames that must happen in a certain sequence) and I am trying to figure out what to do.
In the first few frames, I have a button "next_1".
At frame 10, I need to have another button "next_2". I really really need this button to not be on frame one (I could possibly just make it invisible, but that's going to create a clickable area that I don't want).
The problem is, anything I don't put on "frame_1" renders as null in my Document class.
Is there any solution to this? I would rather not have to write my script on the timeline if possible (it seems easier in the long run to keep it in a document class)...
Items on the timeline are created on the fly, so if the playhead has not reached frame 10, next_2 is not created.
Easiest Document-class solution:
Create an array of frame labels like ["label1", "label2"]
Create sectionIndex var and set it to 0
Create a next button on its own layer so it is always showing.
When the next button is clicked, increment sectionIndex, then gotoAndPlay(myLabels[sectionIndex])
Okay, directly lifted from "Real World Flash Game Development":
/**************************************************
* FRAME LABELS *
**************************************************/
private function enumerateFrameLabels():void {
for each (var label:FrameLabel in currentLabels) {
addFrameScript(label.frame-1, dispatchFrameEvent);
}
}
private function dispatchFrameEvent():void {
dispatchEvent(new Event(currentLabel, true));
}
This dispatches an event at each frame label on the timeline.
Then you can just add event listeners for each frame:
addEventListener("name_of_my_framelabel", frameHandler);
addEventListener("another_framelabel", frameHandler);
And write a switch statement to add event listeners for the buttons when they actually show up on the timeline.
private function frameHandler(e:Event):void {
switch(e.type) {
case 'screen_2':
stop();
next_2.addEventListener(MouseEvent.CLICK, click2, false, 0, true)
break;
}
}

Is it possible to remove an eventListener temporarily (i.e. until a function has been executed)

I am doing actionscript 3 at the moment and was wondering if it was possible to remove and eventListner temporarily. I know of removeEventListener, however, that removes the eventListener completely and i cannot click the button again.
If you want some more details, here the exact problem. I have function that when a button is pressed, an object appears. In the function which makes this object there is an eventListener which leads to a function which allows the user to press that object. When you press that object it disappear and the button will animate. However, since the original eventListener still exists, you can press the object while in motion and create a new object. So to the point: What i want to do is disable the eventListener while the button is moving, and reactivate it when it stops.
The best way is to simply use a flag which tells the function if the animation is complete or not. Here's an example of what I'm talking about using TweenLite as tween library:
public class CreateButton extends Sprite{
private var animating:Boolean = false;
public function CreateButton(){
this.addEventListener(MouseEvent.CLICK, onClick, false, 0, true);
}
private function onClick(event:MouseEvent):void{
if(this.animating == false){
// Trigger creation functionality
TweenLite.to(this, 0.5, {/* Parameters for the actual animation */ onComplete:animationComplete});
this.animating = true;
}
}
private function animationComplete():void{
this.animating = false;
}
}
It is best practice to remove the listener if it's functionality is to be disabled. You could however set the .mouseEnabled to false if you want to disable it's click functionality without removing the listener.