Adobe Animate (HTML5 Canvas) check timeline position of two movie clips and then display another movieclip if both movieclips are on frame 2 - html

In Adobe Animate (HTML5 Canvas) I need to check if two buttons have been clicked on and advanced to the second frame and if both have then display a movieclip.
I am new to programming and not sure how to even begin. I thought of using eventListner or an if/else statement. Not getting either to work. Any help would be greatly appreciated.

I'll try and answer the question to my knowledge, hopefully, it is simple enough to follow, but I'm sure there are probably better ways to write these functions.
buttonClick(evt) allows the buttons to be toggled on and off, assuming that frame 0 of the movieclips handles the off state of the buttons and frame 1 handles the on state. A function is then called on every click to check the states of the buttons.
checkButtonStates() is a conditional statement that just checks the current frame of the buttons, and if both are at 1 the movieclip is displayed and played.
const button1 = stage.children[0].button1_mc;
const button2 = stage.children[0].button2_mc;
const movieclip3 = stage.children[0].movieclip3_mc;
button1.addEventListener("click", buttonClick);
button2.addeventListener("click", buttonClick);
function buttonClick(evt) {
button = evt.currentTarget;
// check current frame of button and changes frame
if (button.currentFrame == 0){
button.gotoAndStop(1);
} else {
button.gotoAndStop(0);
}
checkButtonStates();
}
function checkButtonStates(){
// if both buttons have been clicked hide buttons and play movie
if (button1.currentFrame == 1 && button2.currentFrame == 1){
showButtons(false);
showAndPlayMovie(true);
}
}
// buttons visible property set by passed parameter
function showButtons(bool){
button1.visible = bool;
button2.visible = bool;
}
// changes visible property of movie by passed parameter. If movie is visible the movie is played.
function showAndPlayMovie(bool){
movieclip3.visible = bool;
if (movieclip3.visible == true){
movieclip3.play();
}
}

Related

ActionSript 3 - show controls on mouseover

I currently have a graphic animation with a simple play/pause button beneath, which stops and starts the entire animation:
Frame 1:
stop();
btn_2.addEventListener (MouseEvent.CLICK, stopplaying);
function stopplaying(e:MouseEvent):void {
MovieClip(root).stop();
stop();
gotoAndStop(2);
}
Frame 2:
stop();
btn_1.addEventListener (MouseEvent.CLICK, startplaying);
function startplaying(e:MouseEvent):void {
MovieClip(root).play();
play();
gotoAndStop(1);
}
This works simply and perfectly. However, I'd like the control button to show up on mouseover, and once again become transparent when the mouse leaves the area of the animation. Simply mapping alpha states to the mouse events works, but also seems to break the functionality of the button. Any help would be hugely appreciated!
Update: #BadFeelingAboutThis has good logic, but I'm not having much success with it. To be clear, frame 1 of my scene's actions is now:
var btn_1, btn_2;
this.addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
this.addEventListener(MouseEvent.MOUSE_OUT, mouseOut);
function mouseOver(e:Event):void {
if(btn_1) btn_1.visible = true;
if(btn_2) btn_2.visible = true;
}
function mouseOut(e:Event):void {
if(btn_1) btn_1.visible = false;
if(btn_2) btn_2.visible = false;
}
The button is hidden, but is not reappearing on mouseover. The only fail-point I can see is the keyword 'this', that is, that I'm using it incorrectly. Let me know if there's any other info I can provide!
Update 2: Some more information (and I apologize for my dimness here): here is the animation: [link snipped, updated link below]. The play/pause button is a movie clip named "pp" that contains two frames, each with a button, one named btn_1, the other btn_2.
Update 3: I added a transparent background square (named "backpp") as a mouseevent area (instead of using the broader "this"):
backpp.addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
backpp.addEventListener(MouseEvent.MOUSE_OUT, mouseOut);
This works great! When I mouseover the square, the controls show up. When I mouseout, they go away. However, the play/pause functionality is now not functioning. Any ideas?
Update 4: Most recent code/context below. The play/pause button is now sort-of functioning, and is hiding as intended, but is exhibiting a visual "flashing" behavior, as seen here: http://allaboarddesign.com/rodney/rodney-test.swf
Here is a screenshot of my FlashPro context:
You can do the following:
//create placeholder vars for your btns (they will be populated by the instances on the timeline)
//do this so the compiler knows they exist
var btn1, btn2;
//hide the buttons, do this on frame 2 as well but with btn2
btn1.visible = false;
//listen for mouse over/out on `this` (the timeline whose code this on, presumably your animation)
this.addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
this.addEventListener(MouseEvent.MOUSE_OUT,mouseOut);
function mouseOver(e:Event):void {
//show the buttons if they exist
if(btn1) btn1.visible = true;
if(btn2) btn2.visible = true;
}
function mouseOut(e:Event):void {
//hide the buttons if they exist
if(btn1) btn1.visible = false;
if(btn2) btn2.visible = false;
}
EDIT
Based off your screenshot, it looks your hierarchy is this:
Maintimeline -> pp -> btn1
Where pp is the controls for your main timeline animation.
In that case, the code should be on the Main Timeline and look like this:
pp.visible = false;
//listen for mouse over/out on `this` (the timeline whose code this on, presumably your animation)
this.addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
this.addEventListener(MouseEvent.MOUSE_OUT,mouseOut);
function mouseOver(e:Event):void {
//show the buttons if they exist
pp.visible = true;
}
function mouseOut(e:Event):void {
//hide the buttons if they exist
pp.visible = false;
}
For the mouse over to work, your animation will need something in the background to mouse over, even a transparent shape or movieClip will do.

AS3 - how to best use variables to effect functionality on different frames

I'm currently building a 50 button interactive display, it needs on a specific frame to log 3 button clicks then save a variable or something that 2 slides later will relay whether the user has chosen the correct 3 buttons. This warning is a simple movie clip. Below I listed the 2 frames that need to relate to each other. Please keep in mind I am fairly new to programming Flash and still struggle correct syntax and utilization.
I appreciate any or all input on how I can better accomplish this using Actionscript 3
The below is hiding 3 boxes that will surround the correct answer once clicked. The fl_check36 needs to somehow in the else section send a variable or something i can reference that would let me show the error box movie clip to the user. (I already have a reset button working for that page)
[Frame 36]
MDI_07_box_mc.visible = false;
MDI_08_box_mc.visible = false;
MDI_14_box_mc.visible = false;
// Boxes to be clicked
MDI_07_btn.addEventListener(MouseEvent.CLICK, fl_ClickToShow_14a);
function fl_ClickToShow_14a(event:MouseEvent):void
{
MDI_07_box_mc.visible = true;
}
MDI_08_btn.addEventListener(MouseEvent.CLICK, fl_ClickToShow_14b);
function fl_ClickToShow_14b(event:MouseEvent):void
{
MDI_08_box_mc.visible = true;
}
MDI_14_btn.addEventListener(MouseEvent.CLICK, fl_ClickToShow_14c);
function fl_ClickToShow_14c(event:MouseEvent):void
{
MDI_14_box_mc.visible = true;
}
// Check for boxes correct and go to next frame
MDI_18_btn.addEventListener(MouseEvent.CLICK, fl_check36);
function fl_check36(event:MouseEvent):void
{
if (MDI_14_box_mc.visible && MDI_08_box_mc.visible && MDI_07_box_mc.visible)
gotoAndStop(37);
else
Feedback_07_Wrong_mc.visible = false;
}
This frame just needs to check if the user got the information correct on frame 36 and show or hide the Feedback based on that.
[Frame 38]
stop();
addEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler_2);
function fl_EnterFrameHandler_2(event:Event):void
{
if (globalVar = 1)
Feedback_07_Wrong_mc.visible = true;
Feedback_07_Wrong_mc.gotoAndPlay(2);
}
Reset_Btn.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndPlayFromFrame_2);
function fl_ClickToGoToAndPlayFromFrame_2(event:MouseEvent):void
{
gotoAndPlay(1);
}
Thanks in advance!
What #Karma said is true. When you declare any variable on frame 36, it is accessible to any other frames that preceed it. You can also do the same by creating another layer called "Variables" with no keyframes in between which stores all your variables. This way, you would have confidence that the variable is acceccible to all the keyframes of the other layer.

AS3: pass Keyboard control to child movieclip and back to main timeline

EDIT: I don't know if this is the norm, but I preferred to leave the original question in and add updates. Please, feel free to let me know if I should eliminate the original code snippets and somesuch.
I am trying to create a slideshow-like presentation in flash CS6, using a main timeline with one symbol in each frame and the different animations (some quite complex) in those symbols. Since I'm going to use a presenter remote, I've captured the keystrokes and coded pg_up and pg_down to go to the next and previous frame respectively:
stage.addEventListener(KeyboardEvent.KEY_DOWN, pagerFunction);
var symb:movieClip;
function pagerFunction(e:KeyboardEvent):void
{
var myKey = e.keyCode;
if (myKey == Keyboard.PAGE_DOWN){
if (symb != null){
//some code that allows to control the symbols timeline forward
} else {
nextFrame();
}
}
if (myKey == Keyboard.PAGE_UP){
if (symb != null){
//some code that allows to control the symbols timeline backward
} else {
prevFrame();
}
}
The problem I'm having is the following. I've added framelabels and stop(); code inside the symbol animations where I needed to control the step from one animation to the next one. However, after having tried numerous solutions on the web, I haven't been able to succeed having the symbols react to pg_up and pg_down as if they were part of the main timeline.
To sum up, what I need to solve is this:
Enter Main timeline Frame
Identify symbol instance (labeled as _mc)
Inside symbol timeline, play from first frame (labeled '0') until next labeled frame ('1' and so on)
stop and wait for next pg_down to start playing from next labeled frame to the following (i.e. '1'-'2'), or pg_up to start playing from the previous labeled frame (i.e. '0' to '1') (for this, I would use a variable to keep track.
on last frame (labeled 'final') exit symbol focus and return keyboard control to main timeline to allow pg_down and pg_up to move to the next / previous frame. on pg_up on symbol.currentFrame == 0, do same.
BTW, if there's a better way to achieve this, I'm open (and quite desperate) for better suggestions / solutions.
Thank you so much to anyone who can help!
Edit: Ok, I guess I wasn't too clear on the issue, so I'll try to add a bit to this:
addEventListener(KeyboardEvent.KEY_DOWN, mc_pagerFunction);
var lbl:String;
var counter:Number = 0;
function mc_pagerFunction(e:KeyboardEvent):void {
var myKey = e.keyCode;
if (myKey == Keyboard.PAGE_DOWN){
lbl = this.currentFrameLabel;
if (this.currentFrameLabel == 'final'){
stop();
stage.focus = this.parent; //which would be the main timeline
} else if (Number(lbl) == counter){
this.gotoAndStop(lbl);
counter++;
} else {
this.gotoAndPlay(lbl);
}
}
if (myKey == Keyboard.PAGE_UP){
lbl = this.currentFrameLabel;
if (this.currentFrameLabel == '0'){
stop();
stage.focus = this.parent; //which would be the main timeline
} else if (Number(lbl) == counter){
this.gotoAndStop(lbl);
counter--;
} else {
this.gotoAndPlay(lbl);
}
}
}
Now, this bit is the behaviour I'd like to see inside the symbol when the main timeline goes into the next frame, thus being able to use the main timeline as sort of slideholder and the real thing happening inside the symbol.
Btw, I'd like to try and keep all code within the main action layer, not in the symbols. I tried that, shifting focus to the symbol and it didn't work either, and having code all over the place grates against my nerves ;).
I hope this throws some light on what I'm stuck at.
Again, any help is appreciated. Thanks all in advance
UPDATE:
Please someone help me out here!
This is what I'm trying. Logically, it makes all the sense in the world, except that it doesn't work.
var symb:MovieClip;
symb = MovieClip(root); //assign symbol I want to be controlled by pg_up/pg_down
symb.focusRect = false;
stage.focus = symb; //focus on current symbol
symb.addEventListener(KeyboardEvent.KEY_DOWN, mc_pager); //add keyboard event listener
function mc_pager(e:KeyboardEvent):void{
var myKey = e.keyCode;
if (myKey == Keyboard.PAGE_DOWN){
do{
symb.play(); // it plays, then checks if the lbl is null or final, then quits
} while (symb.currentFrameLabel == null && symb.currentFrameLabel != 'final');
symb.stop();
symb.removeEventListener(KeyboardEvent.KEY_DOWN, mc_pager);
stage.focus=MovieClip(root); //return focus to main timeline (in the next keyframes, the focus is on the nested _mc
}
if (myKey == Keyboard.PAGE_UP){
do{
symb.prevFrame();
} while (symb.currentFrameLabel == null && symb.currentFrameLabel != '0');
symb.stop();
symb.removeEventListener(KeyboardEvent.KEY_DOWN, mc_pager);
stage.focus=MovieClip(root);
}
}
Where am I being to moronic to get it right? Please, guys, you're the experts, I need your advice here. Thanks!
UPDATE:
Doing a trace on symb, it seems like as soon as it enters the function, it forgets the initial assignment (symb = MovieClip(root)) and shows null. Why?
In this sample, I created a basic proof of concept where I have a circle MC with an instance name of "c" on the main timeline. Within this mc, I created with 2 keyframes inside with stop actions on both. I colored the circle a different color on frame 2 and labeled it as "two".
In the Main timeline I have the following code:
import flash.events.KeyboardEvent;
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyEvt);
function keyEvt(e:KeyboardEvent):void{
if(e.keyCode == Keyboard.PAGE_DOWN){
trace("down");
c.gotoAndPlay("two");
}
}
This should help form a foundation for your code as long as you stick with targeting the symbol through direct reference and ensure your keyboard event is attached to the stage.
Also, always stick with getting a basic working version down first. I.E. Check to see if your keyboard listeners are working for your target object and then build additional functionality off of that.

Actionscript 3 - Passing one variable from one object to another in the same project

I'm fairly new at ActionScript 3 but I am working on it and trying to learn by reading and modifying ActionScript source codes.
So far so good, however I stumbled upon one problem which I seemingly can't solve by myself. It should be faily simple for you guys tho.
The situation:
I got one "object" which is clickable and gives a random value which is also being saved in a variable.
I got another "object" which does the same thing but only has a different name.
I want the variable from the first object to be passed to the second one, how can I do it?
One way to pass values relies on using references to objects...
// mc1 and mc2 exist as movieclips on the stage
mc1.addEventListener( MouseEvent.CLICK, onClick );
mc2.addEventListener( MouseEvent.CLICK, onClick );
function onClick( event:MouseEvent ):void
{
// reference clicked movieclip through click target
var mc:MovieClip = event.target as MovieClip;
// if our clip matches one, assign the other clip the value.
if ( mc === mc1 )
{
mc2.value = mc.value;
}
else if ( mc === mc2 )
{
mc1.value = mc.value;
}
}
There's a thousand ways to pass references around, and this is just one.
OK guys let me show you the important parts of the code (cant show it all since I paid for it and I don't know whether the author woudl be OK with me publishing all of it).
I got these two objects there. When I click on one of the objects (which is a DICE), it gives me this code basically
var faceValue:int = 6;
// Add mouse click functionality to roll the die
addEventListener(MouseEvent.CLICK, onClickDie, false, 0, true);
mouseChildren = false;
buttonMode = true;
function onClickDie(e:MouseEvent):void {
removeEventListener(MouseEvent.CLICK, onClickDie);
buttonMode = false;
// Initiate the roll-out sequence
if(faceValue == 6) {
gotoAndPlay("rollout6");
etc...
Then somewhere in the frame where it is SPINNING the dice it is randomizing a number and save it into facevalue
// Calculate a random face value between 1 and 6
faceValue = 1 + Math.floor(Math.random()*6);
// Initiate the roll-in sequence
if(faceValue == 6) {
gotoAndPlay("rollin6");
...etc
Now how can I get the randomized facevalue from the spinning the dice frame to pass it to the other dice?

How to apply action to mulitple flash layers

I have 5 layers with symbols on each: a, b, c, d and e.
I am trying to work out how to apply the action bellow to a, c, d and e when you hover over b.
Also is there another action similar to ' gotoAndStop(0); ' that instead of going immediately to frame 0 it goes back the way it came?
Link to .Fla http://www.fileden.com/files/2012/11/27/3370853/Untitled-2.fla
stop();
stage.addEventListener(MouseEvent.MOUSE_OVER, playMovie); function playMovie(event) { play(); }
stage.addEventListener(MouseEvent.MOUSE_OUT, stopMovie); function stopMovie(event) { gotoAndStop(0); }
stop();
Thanks
EDIT
After looking at your .fla, here is what is missing/misplaced:
Layers in flash don't mean anything other than z-order/depth. You cannot manipulate a layer in code. All your animations are on the same timeline, so they will always play together. If you want an individual item to animate without the others, you'll have to do the animation on it's own timeline (not just it's only layer). You access your symbols own timeline by double clicking it - do your animation in there.
To reference items that are on the stage, you need to give them an instance name. You do that by clicking on the item that's on the stage, then in properties panel, there is field where you can put in an instance name. For the code below to work, you'd need to give them an instance name of "a","b","c","d","e" respectively. This is different than the symbol name in your library (though it can be the same name).
One way you could do this:
var btns:Vector.<MovieClip> = new Vector.<MovieClip>(); //create an array of all your buttons
btns.push(a,b,c,d,e); //add your buttons to the array
for each(var btn:MovieClip in btns){
btn.addEventListener(MouseEvent.MOUSE_OVER, btnMouseOver); // listen for mouse over on each of the buttons
btn.addEventListener(MouseEvent.MOUSE_OUT, btnMouseOut);
}
function btnMouseOver(e:Event):void {
for each(var btn:MovieClip in btns){ //loop through all your buttons
if(btn != e.currentTarget){ //if the current one in the loop isn't the one that was clicked
btn.play();
try{
btn.removeEventListener(Event.ENTER_FRAME,moveBackwards); //this will stop the backwards animation if running. it's in a try block because it will error if not running
}catch(err:Error){};
}
}
}
function btnMouseOut(e:Event):void {
for each(var btn:MovieClip in btns){ //loop through all your buttons
if(btn != e.currentTarget){ //if the current one in the loop isn't the one that was clicked
goBackwards(btn);
}
}
}
There is no nice way to play a timeline backwards, but there are ways to do it. One such way:
//a function you can call and pass in the item/timeline you want played backwards
function goBackwards(item:MovieClip):void {
item.stop(); //make sure the item isn't playing before starting frame handler below
item.addEventListener(Event.ENTER_FRAME, moveBackwards); //add a frame handler that will run the moveBackwards function once every frame
}
//this function will move something one frame back everytime it's called
function moveBackwards(e:Event):void {
var m:MovieClip = e.currentTarget as MovieClip; //get the movie clip that fired the event
if(m.currentFrame > 1){ //check to see if it's already back to the start
m.prevFrame(); //if not move it one frame back
}else{
m.removeEventListener(Event.ENTER_FRAME,moveBackwards); //if it is (at the start), remove the enter frame listener so this function doesn't run anymore
}
}