Flash Actionscript 3.0 Mouse Cursor Duplicates - actionscript-3

I wrote a simple game and I want to add custom mouse cursor. I created MovieClip called Pointer, exported it to AS3 and wrote this code:
/* Custom Mouse Cursor
Replaces the default mouse cursor with the specified symbol instance.
*/
stage.addChild(movieClip_2);
movieClip_2.mouseEnabled = false;
movieClip_2.addEventListener(Event.ENTER_FRAME, fl_CustomMouseCursor_3);
function fl_CustomMouseCursor_3(event:Event)
{
movieClip_2.x = stage.mouseX;
movieClip_2.y = stage.mouseY;
}
Mouse.hide();
//To restore the default mouse pointer, uncomment the following lines:
//movieClip_2.removeEventListener(Event.ENTER_FRAME, fl_CustomMouseCursor_3);
//stage.removeChild(movieClip_2);
//Mouse.show();
Here is a screenshot:
Whenever I play the game (ctrl enter) it stops the play and duplicates the custom cursor. Is there anyway I can make it not duplicate this is very annoying and I have no idea on how to fix it.
~ EDIT 2 ~
Okay I changed the code to but the problem is now it's showing me the regular cursor and the custom one at the same time.
movieClip_1.mouseEnabled = false; movieClip_1.addEventListener(Event.ENTER_FRAME, fl_CustomMouseCursor); function fl_CustomMouseCursor(event:Event) { movieClip_1.x = stage.mouseX; movieClip_1.y = stage.mouseY; } stage.removeChild(movieClip_1) Mouse.hide()
~ EDIT 3 ~
Thank you #LDMS for helping me. I had to remove the first line stage.addChild(movieClip_1); and it worked. :)

Most likely, your problem stems from this line:
stage.addChild(movieClip_2);
When you add a movie clip that was created on the timeline to another display object (like the stage), it will not get removed from that new display object except through code.
If your timeline loops, then every loop it will create a new movie clip and add it to the stage (but not remove the old one).
To fix it, do one of the following:
don't loop your timeline (so the code only happens once), eg put a stop() on your timeline
manually remove the movie clip from the stage before the timeline loops (eg stage.removeChild(movieclip_2) at the end of your timeline
Don't add it to the stage to begin with. (just take out the stage.addChild(movieClip_2); line)

Related

AS3 Change Frame/Instance within MovieClip

I am not a programmer, so please forgive me if my question is too noobish.
I created a MovieClip in my library called "skill". Then I added three instances of that MovieClip into my stage called "skill_01", "skill_02", and "skill_03" respectively. I selected all three instances and created another MovieClip called "diagram" to nest them inside it. I will later add more skill instances inside this MovieClip called "diagram" but for now, I need the basics to work with three instances.
The main timeline or stage only has 1 frame, and so does the "diagram" MovieClip instance. However, the skill instances all have two frames: in frame 1 I have an PNG image showing them as being locked/offline, and in frame 2 I have another PNG showing them as unlocked/online. I need to be able to toggle them by clicking and right clicking on them, just like in the example below (see link)
I am trying to make it so that when you left click the skill instances they toggle to Online/Unlocked by switching to the PNG image in frame 2, and when you right click them, it goes back to frame 1 (Offline/Locked). I've tried several different lines of code, including the ones recommended by Adobe itself, and others, and I can't figure out what I'm doing wrong. It will go to frame 2 and refuse to go back to frame 1 when right clicked.
This is the code I have in the MovieClip:
stop();
skill_01.addEventListener(MouseEvent.CLICK, fl_ClickToGoToNextFrame);
function fl_ClickToGoToNextFrame(event:MouseEvent):void
{
gotoAndStop(2);
}
This part of the code doesn't work:
skill_01a.addEventListener(MouseEvent.RIGHT_CLICK, fl_ClickToGoToPreviousFrame);
function fl_ClickToGoToPreviousFrame(event:MouseEvent):void
{
prevFrame();
}
Screenshot 1:
gyazo (dot) com/e622baee46c3fabbd8c9a8d2df8396fe
Screenshot 2:
gyazo (dot) com/1b360716a5d243aa74e2be4127fe9a5b
(Sorry for typing the links like that, it won't let me add more than 1 link because I just signed up to this Forum)
For more context, I am trying to make a Skill Tree, that works similar to this one: http://www.dungeonsanddevelopers.com/#__6_Your
I will appreciate any help figuring this out!
if you have named your movieclip, skill_01, so what is the skill_01a ?
also add your event listener and its callback function in to the movieclip's parent and inside the callback function, for accessing the event owner, use
// stop(); not necessary to call stop if you have only 1 frame
with (this.diagram) {
skill_01.addEventListener(MouseEvent.CLICK, fl_ClickToGoToNextFrame);
skill_02.addEventListener(MouseEvent.CLICK, fl_ClickToGoToNextFrame);
skill_03.addEventListener(MouseEvent.CLICK, fl_ClickToGoToNextFrame);
skill_04.addEventListener(MouseEvent.CLICK, fl_ClickToGoToNextFrame);
skill_01.gotoAndStop(1);
skill_02.gotoAndStop(1);
skill_03.gotoAndStop(1);
skill_04.gotoAndStop(1);
}
function fl_ClickToGoToNextFrame(event:MouseEvent):void
{
if (MovieClip(event.target.parent).currentFrame == 1)
MovieClip(event.target.parent).gotoAndStop(2);
else
MovieClip(event.target.parent).gotoAndStop(1);
}
Edit: when an event is dispatched from clicked movieclip, only the last movieclip inside hierarchy tree will be passed as event.target in your exaple, that can be skill_01 (if currentframe is 1) or skill_1a (if currentframe is 2) athwart the question body, you have not only a png image inside skill's frame 1 and 2, they are movieclip's and will be returned as event.target. but if you only put your bitmaps (locked.png & unlocked.png) instead of skill_01 and skill_01a, the previous code works fine. bitmaps does not capture event so its parent is who accepted click event and its all a little confusing, i'm not good at explain
if its hard to comprehend
we shall use some thing like it, easier but larger code
with (this.diagram) {
skill_01.addEventListener(MouseEvent.CLICK, fl_ClickToGoToNextFrame_s1);
skill_02.addEventListener(MouseEvent.CLICK, fl_ClickToGoToNextFrame_s2);
skill_03.addEventListener(MouseEvent.CLICK, fl_ClickToGoToNextFrame_s3);
skill_04.addEventListener(MouseEvent.CLICK, fl_ClickToGoToNextFrame_s4);
skill_01.gotoAndStop(1);
skill_02.gotoAndStop(1);
skill_03.gotoAndStop(1);
skill_04.gotoAndStop(1);
}
function fl_ClickToGoToNextFrame_s1(event:MouseEvent):void {
toggle_buttons(skill_01);
}
function fl_ClickToGoToNextFrame_s2(event:MouseEvent):void {
toggle_buttons(skill_02);
}
function fl_ClickToGoToNextFrame_s3(event:MouseEvent):void {
toggle_buttons(skill_03);
}
function fl_ClickToGoToNextFrame_s4(event:MouseEvent):void {
toggle_buttons(skill_04);
}
function toggle_buttons(button:MovieClip):void
{
if (button.currentFrame == 1)
button.gotoAndStop(2);
else
button.gotoAndStop(1);
}

add even-listener to a button on timeline that is a grand child of a movie clip

I got a simple flash scene that contain movie clip that contain sliding button that changing every few seconds:
every layer contain a button and another movie clip.
If I want to add event-listener to a simple button on stage, i just write:
f4.addEventListener(MouseEvent.CLICK, f4Click);
function f4Click(event:MouseEvent):void
{
flash.external.ExternalInterface.call("dlHTCMD", "switchtogame?code=fnf50");
}
but when I'm trying to access the button inside the two movie clips, like
optContainer.optBeach.btnBeach.addEventListener(MouseEvent.CLICK, btnBeachClick);
and I'm adding a trace function to see if the event are triggered but nothing is happening.
looks like a simple problem but i didn't find a solution.
I thought about extending the button class and add a bind function with the value as the name of the button and set the Event Listener but I'm not an AS3 expert :(
Thanks.
Try this:
// Pass mouse events to children
optContainer.mouseChildren = true;
optContainer.optBeach.mouseChildren = true;
// Reset hit area
optContainer.hitArea = null;
optContainer.optBeach.hitArea = null;
// Reset masks
optContainer.mask= null;
optContainer.optBeach.mask= null;
Also check whether on each key frame button have name.

Set a button to invisible once clicked

I'm trying to set a button to invisible in AS3 however when the I leave the frame and come back to it the button is visible again. This is for a jeopardy game I make making for comm tech class.
Here is what I currently have:
a1.addEventListener(MouseEvent.CLICK, a1mouseClick);
function a1mouseClick(mouse:MouseEvent) {
a1.visible = false;
gotoAndStop("A1");
trace("Going to A1");
}
however when it comes back to the frame with the a1 button it is visible again.
Here is my current animation: https://dl.dropbox.com/u/23938245/jeporady.fla
While moving through the timeline flash player can recreates sprites, movie clips and text fields, so your buttons appears visible again. To prevent recreation move all controls to separate level without key frames. If key frames are required try to set the same instance name for this button in all keyframes.
#fsbmain and #prototypical they are right.
While moving through the timeline flash player can recreates sprites, movie clips and text fields, so your buttons appears visible again. To prevent recreation move all controls to separate level without key frames. If key frames are required try to set the same instance name for this button in all keyframes.
I was looking at your project, and offer a quick fix, you need to do the following:
Create a new layer on top to manage a few of actions availables for all frames with the following actions:
import flash.display.DisplayObject;
// Manages the buttons visible state
var buttonsStates:Object = {
"a1":true, "b1":true, "c1":true, "d1":true, "e1":true,
"a2":true, "b2":true, "c2":true, "d2":true, "e2":true,
"a3":true, "b3":true, "c3":true, "d3":true, "e3":true,
"a4":true, "b4":true, "c4":true, "d4":true, "e4":true,
"a5":true, "b5":true, "c5":true, "d5":true, "e5":true
};
// Checks the buttons visibility
function checkVisibility () {
for (var buttonName:String in buttonsStates)
{
var child:DisplayObject = this.getChildByName(buttonName);
child.visible = buttonsStates[buttonName];
}
}
// Saves the visible satatus to false
function setVisibilityToFalse(target:*) {
buttonsStates[target.name] = false;
target.visible = false;
}
Every time you want to check the visibility of the buttons you must call the checkVisibility() function. For example, every time you return to the button list.
Finally the event handler for each button must be like this:
function a1mouseClick(mouse:MouseEvent) {
setVisibilityToFalse(mouse.currentTarget); // Saves the visible state to false
gotoAndStop("A1");
trace("Going to A1");
}
You can download the edited file here http://cl.ly/Lt6X
You are missing a fundamental aspect of how the flash timeline and keyframes function. Once you move away from that frame, the stage instance of the content of that frame and it's properties/states are gone. When you return to that frame, the instance is created again based on the keyframe contents.
I think the best solution given your current approach is to put the main board persistent throughout all the frames. You can do that by creating a layer for it, and have it's keyframe extend from frame 2 to frame 27. However, your next issue will be adjusting visibility of all the elements on that screen when you don't want them visible.
My suggestion would be to put all the elements of that screen into a movieclip symbol of it's own and add that movieclip, and all code for it's listeners, to this new layer you created. For example you might name that instance - main_board and therefore you could modify it's visibility with main_board.visible property. If you did choose that solution, you would need to modify all the code on that frame to use that instance name as well ie :
main_board.a1.visible = false;
Also, you'd need to modify all you addEventListener lines as well :
main_board.a1.addEventListener(MouseEvent.CLICK, a1mouseClick);
Your approach for this game could be greatly simplified, but even further beyond the scope of this question than I have already gone!

AS3 - Unable to capture button click when using Mouse Move listener

In my first AS3 project (not used Flash since AS1) I need to use a custom movie clip as a cursor and detect clicking on a button. Using the code below, the custom cursor works as expected, but I am unable to capture clicking on the button.
If I comment out the first line, the trace for clicking works as expected. I have tried changing the order of the event listeners, applying the follow to the button rather than the stage, but cannot get both to work together.
Any advice as to where I'm going wrong ould be appreciated.
stage.addEventListener(MouseEvent.MOUSE_MOVE,follow);
start_button.addEventListener(MouseEvent.MOUSE_UP, playPhrase);
function playPhrase(event:MouseEvent) {
trace("Click received");
};
function follow(event:MouseEvent) {
cursor.x = mouseX;
cursor.y = mouseY;
};
Looks like that's because you always click on the cursor object as it always positioned right under mouse cursor. Make it "transparent" for mouse clicks:
cursor.mouseEnabled = false;
And if it's a DisplayObjectContainer then also:
cursor.mouseChildren = false;

currentFrame identifiers [AS3]

I'm completely new to Flash and AS3, and I'd have thought this would be a simple question, but I've been unable to find an answer online or in the documentation. I'm trying to use addEventListener (Event.ENTER_FRAME) and (.currentFrame) to disable a button for part of an animation sequence. While the animation sequence fades in, the Button Hand cursor is visible and people can select it before the sequence is completed. I want this button disabled for the first 213frames of the main timeline, which is when the button becomes visible.
Earlier, I was successfully able to disable a Rewind button for parts of a different movie scene using the code below with a few insignificant things changed.
Skip_btn.addEventListener(MouseEvent.CLICK, SkipToGoToScene);
function SkipToGoToScene(event:MouseEvent):void
{
MovieClip(this.root).gotoAndPlay(1, "Opening");
}
//Skip_btn functions
Skip_btn.addEventListener(Event.ENTER_FRAME, skipDisable);
function skipDisable(event:Event) {
if (this.currentFrame < 213)
{ Skip_btn.mouseEnabled = false;
} else {
Skip_btn.mouseEnabled = true;
}
if (this.currentFrame > 213) {
Skip_btn.removeEventListener(Event.ENTER_FRAME, skipDisable);
}
}
The problem is that before I could just use "this.currentFrame" as the button was on the same timeline that it controlled, whereas now it's embedded in a MovieClip that is on the main timeline. What can I swap "this" for so I can reference this main timeline? Also, could someone fill me in on what the other "identifiers" are for ".currentFrame", as I'm not too sure how it works. The documentation examples ask for Movieclips such as "MyMovie_mc.currentFrame", but what if you just want to reference a main timeline?
If the button is on main timeline you could just use
this.root.getChildByName("Skip_btn").mouseEnabled = true;
And if you start playing animation on main timeline use
MovieClip(this.root).currentFrame