AS3 Change Frame/Instance within MovieClip - actionscript-3

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);
}

Related

Making a button that goes to a random frame (from an array) on the main timeline. How to do from a movie clip?

I saw plenty of questions that asked how to make a button in a movie clip that leads to a frame in the main timeline, and took a look at them. But is it different if you want to go to a random frame in a specific set of frames? I've never really used AS3 aside from simple things like stop(); or gotoAndPlay.
Here's what my main timeline looks like at the moment:
Here's the code I've got so far by using Google:
var frameB:Array=[1,28,45,56,71,91,106,126];
blue_circle1.addEventListener(MouseEvent.CLICK, choose);
function choose1(event:MouseEvent):void {
var randomFrame:Number = frameB[Math.floor(Math.random() * frameB.length)];
trace(randomFrame);
gotoAndPlay(randomFrame);
}
The code works fine when I use it on the rotation buttons in the main timeline. But it doesn't work when I put it in a button in a movie clip. I need to change it so it works. If there is a better way of doing this, I'm willing to try it.
Edit: I should clarify things more. I got rectangle on wheels that moves left to right. It does this in a movie clip. I want the button to move with it. But when I place the button into said movie clip, the code on the button stops working. I hope I didn't end up making things more confusing.
When you place the button and/or code inside the movieClip it changes the movieClip that gotoAndPlay() is referring to. You need to specify which movieClip you are calling gotoAndPlay() on. For the main timeline gotoAndPlay() works, but inside a movieClip you must use this:
parent.gotoAndPlay(randomFrame);
Or you may need to set parent's type to a MovieClip like this:
MovieClip(parent).gotoAndPlay(randomFrame);
However, it's best to use external .as files as it gives you the most control over your code.
Save the code below in a file called 'MyFlashAnimation.as'
Create a folder called 'mycodefolder' and put it in the same directory/folder as your .fla.
Use the 'MyFlashAnimation.as' as your document class. In the Flash/Animate IDE find the Properties panel, then the Publish section
In the Publish section where it says 'Class' enter: mycodefolder.MyFlashAnimation (do not add the .as)
CODE:
package mycodefolder {
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class MyFlashAnimation {
private var animationClip:MovieClip;
private var blueCircle1:Button;
private var frameB:Array = [1,28,45,56,71,91,106,126];
// constructor
public function MyFlashAnimation() {
// this your main robot/car animation
// this assumes animation_clip is on the main stage
animationClip = this.animation_clip;
// this is your button. this assumes blue_circle1 is a child of
// your animation_clip. update the path if necessary.
// for example, it might be: animationClip.robot_body.blue_circle1
blueCircle1 = animationClip.blue_circle1;
// add listener
blue_circle1.addEventListener(MouseEvent.CLICK, choose);
}
function choose1(event:MouseEvent):void {
var randomFrame:Number = frameB[Math.floor(Math.random() * frameB.length)];
trace(randomFrame);
// tell animation clip to gotoAndPlay
animationClip.gotoAndPlay(randomFrame);
}
}
}
That should work. If you have all your movieClip paths correct.
"The code works fine when I use it on the rotation buttons in the main timeline. But it doesn't work when I put it in a button in a
movie clip."
What is the instance name of the MClip you paste the button into? That MC name will "add" to the final path of your button.
Examples:
(1) If your blue_circle1 on stage (you already can do this) :
blue_circle1.addEventListener(MouseEvent.CLICK, choose);
versus...
2) If your blue_circle1 is inside another MClip (with example name as: thingMC) :
thingMC.blue_circle1.addEventListener(MouseEvent.CLICK, choose);

How do I change the size of a movieclip in flash by clicking on it? (Actionscript 3)

Everything I've found is for making a separate button, but I'm trying to make it so that clicking on the movieclip itself makes it change size. The reason is that it's being animated moving across the page, so clicking it is the challenge. Can anyone help? This is the code I tried:
info_btn_mc.buttonMode = true;
info_btn_mc.addEventListener(MouseEvent.CLICK, openInfo);
stop();
function openInfo(e:MouseEvent):void {
enemy_first.play("shrink");
}
You cannot use play("shrink"), the method
play() (Moves the playhead in the timeline of the movie clip) has no arguments. use gotoAndPlay/gotoAndStop instead that received an argument called frame:Object (frame number or label (String).
enemy_first.addEventListener(MouseEvent.CLICK, openInfo);
enemy_first.stop();
function openInfo(event:MouseEvent):void
{
trace('event.currentTarget:', event.currentTarget);
event.currentTarget.gotoAndPlay("shrink");
}

AS3 Multiple Rollover objects

example image
Very new to AS3. Sorry if this question is really basic, I tried looking around for the right answer but only found semi-related questions. Please help!!
Objective: I want multiple rollover MovieClips on the same stage that play out their animations independently.
So far, I have only 1 MovieClip object that behaves properly. If I add another, the first one behaves properly but the second doesn't appear at all. I understand that it's probably only calling the instance that I first dropped into the stage and that I need to change my code to have a "master" or parent MovieClip and that the instances should be the children, but I'm not sure how to write that in code. Eventually, the idea is that I add my children movieclips, and then slightly change the content in each clip.
My code so far:
import flash.events.MouseEvent;
clip_boxes.removeEventListener(MouseEvent.ROLL_OUT, clipOut);
clip_boxes.addEventListener(MouseEvent.ROLL_OVER, clipOver);
function clipOver(event:MouseEvent):void {
clip_boxes.addEventListener(MouseEvent.ROLL_OUT, clipOut);
clip_boxes.removeEventListener(MouseEvent.ROLL_OVER,clipOver);
clip_boxes.gotoAndPlay("Over");
};
function clipOut(event:MouseEvent):void {
clip_boxes.addEventListener(MouseEvent.ROLL_OVER, clipOver);
clip_boxes.removeEventListener(MouseEvent.ROLL_OUT, clipOut);
clip_boxes.gotoAndPlay("Out");
};
There are a few ways you can do this. I'll list in order of worst to best.
Manually add listeners to each instance.
When you drag a new MovieClip onto the timeline, you need to give it an instance name (found in the properties panel). I'm not sure if clip_boxes is a parent timeline that you intend to have all your movie clips on, or if it is one of your movie clips itself.
Assuming you have 3 clips with the instance names: MC1,MC2,MC3, you could do this (on the first frame of the timeline that contains them)
MC1.addEventListener(MouseEvent.ROLL_OVER, clipOver);
MC2.addEventListener(MouseEvent.ROLL_OVER, clipOver);
MC3.addEventListener(MouseEvent.ROLL_OVER, clipOver);
//If you had a whole bunch, you could also use a loop to add all the listeners
//you use event.currentTarget to get a referce to the object the listener was attached to - this way you only need this one handler function
function clipOver(event:MouseEvent):void {
MovieClip(event.currentTarget).addEventListener(MouseEvent.ROLL_OUT, clipOut);
MovieClip(event.currentTarget).gotoAndPlay("Over");
};
function clipOut(event:MouseEvent):void {
MovieClip(event.currentTarget).removeEventListener(MouseEvent.ROLL_OUT, clipOut);
MovieClip(event.currentTarget).gotoAndPlay("Out");
};
Use Inheritance
This would involve creating a base class file (.as file) that you can then attach to all your MovieClips so they inherit all the code within. Here is an example of a class file that would do this for you: (lets assume this is a file called SubClass.as in your root directory)
package {
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class SubClass extends MovieClip {
public function SubClass(){
this.addEventListener(MouseEvent.ROLL_OVER, rollOver,false,0,true);
}
public function rollOver(event:MouseEvent):void {
this.addEventListener(MouseEvent.ROLL_OUT,rollOut,false,0,true);
this.gotoAndPlay("Over");
}
public function rollOut(event:MouseEvent):void {
this.removeEventListener(MouseEvent.ROLL_OUT,rollOut,false);
this.gotoAndPlay("Out");
}
}
}
Now, when you create your movieClips (or right click in the library and select properties), you can set a baseClass for them. If you set the base class to the class above, they automatically use the code above and have the mouse over/out attached. (as long as they have the Out/Over frame labels it will just work).
Can you also post the code where you add clip boxes to the stage? Did you add them in the GUI by dragging and dropping or in code?
If so, you might need to make instances of each of the clip boxes inside the larger movieclip that contains all of them together. Then you'll need to refer to each one with clip_boxes.box1, etc.
EDIT:
Oh, I see you had an image there. My bad. Make sure you give each clip box its own unique instance name. You'll need to have clip_box_1, clip_box_2, etc. Then in code you use clip_box_1.addEventListen.....etc.

Applying action to a button in one frame makes it apply to whole movieclip in Flash CS6

I have a movieclip with several layers and frames. Some of those contain buttons. When I click button 1 I want it to go to the next frame. When I click button 2 I want it to go to frame 23. This is the code I'm using for button 1:
this.addEventListener(MouseEvent.CLICK, convnext);
function convnext(evt:MouseEvent):void
{
MovieClip(parent).gesprekkencivcen.nextFrame();
}
and this is the code for button 2:
this.addEventListener(MouseEvent.CLICK, convend1);
function convend1(evt:MouseEvent):void
{
MovieClip(parent).gesprekkencivcen.gotoAndStop(23);
}
What happens now is that when I click either of the buttons, or in fact anywhere inside the movieclip (even layers I haven't applied actions to) it executes both functions at the same time so I end up going to frame 24. Can somebody provide an answer to this problem?
Obviously this in both cases refers to the same object, and not to the buttons in particular. Record the names of those buttons as you've named their instances on the timeline, say button1 and button2 and write the code employing those names.
button1.addEventListener(MouseEvent.CLICK, convnext);
function convnext(evt:MouseEvent):void
{
parent.parent.gesprekkencivcen.nextFrame();
}
button2.addEventListener(MouseEvent.CLICK, convend1);
function convend1(evt:MouseEvent):void
{
parent.parent.gesprekkencivcen.gotoAndStop(23);
}
With this, however, you will need to update the link to gesprekkencivcen in both listeners, as those buttons will have this as parent, and their target apparently is not a child of this. I have tried to plainly set a call to parent.parent.gesprekkencivcen, which might not work.

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