AS3 switching between buttons - actionscript-3

I am trying to let the user click a button and that button determines which "tool" he/she is using. There will be multiple buttons and I need to distinguish the difference between them. For example, the user clicks the first button for one tool, then clicks the second button for the second tool. I thought I had it down, but i'm missing something. Here is what I have
function mMove(MouseEvent): void
{
if (mouseHolding && mouseY > 85 && mouseX < 610)
{
clearTemp();
switch (currentTool)
{
case thisTool:
temporaryDrawing.graphics.lineTo(mouseX, mouseY);
break;
}
thisTool.addEventListener(MouseEvent.CLICK, changeMode);
function changeMode(evt: MouseEvent): void
{
var button: Button = evt.target as Button;
currentTool = evt.currentTarget; // I get an error on this line.
}
Can I have some guidance on what i'm doing wrong, thanks :D

It looks like your mMove is missing a closing brace. Could that be the problem?

I've solved my own question :) I just needed to figure out a way to set which button is active by creating separate functions.

Related

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 Selecting a MovieClip

My situation is this:
I've got several (2+) MovieClips on the stage.
Each one contains an input-textbox in addition to the background.
When I click the first MovieClip, it gets selected and a light blue shadow is displayed to indicate it like so: http://puu.sh/aueAw/3575e83aca.png
If I click the second one, it looks like this: http://puu.sh/aueEj/826e1c9cb9.png
However, when the second MovieClip's textbox is clicked, the first MovieClip becomes selected! This doesn't make any sense to me.
What could be causing this? Everything works as it should as long as I don't take these nested textboxes into account.
Thanks in advance for your helpful answers!
Best regards,
Olin K.
EDIT: Here's the code that I use to add event listeners to the MovieClips.
public function updateVisualDocument()
{
if (!uniDocument.isEmpty())
{
//Update the Visual Document if the current Document contains any pages
visualDocument.uniPage.gotoAndStop(uniDocument.getCurrentPage().getLayout());
visualDocument.uniPage.pageNumber.text = uniDocument.getPageIndex();
//Update Thumbnails
for each (var someThumb in thumbnailArray)
{
someThumb.deselect();
}
thumbnailArray[uniDocument.getPageIndex() - 1].select();
for (var i:int = 0; i < visualDocument.uniPage.panelContainer.numChildren; i++)
{
var somePanelMC = visualDocument.uniPage.panelContainer.getChildAt(i);
if (!uniDocument.getCurrentPage().hasPanels())
{
uniDocument.getCurrentPage().addPanel(somePanelMC);
}
somePanelMC.addEventListener(MouseEvent.CLICK, panelClicked);
uniDocument.getCurrentPage().getPanel(i).setPanelMC(somePanelMC);
function panelClicked(e:Event)
{
//Panel gets selected
var panelIndex:int = int(e.target.name.substring(5));
uniDocument.getCurrentPage().deselectAllPanels();
uniDocument.getCurrentPage().getPanel(panelIndex).select();
}
}
uniDocument.getCurrentPage().panelsAreFull();
uniDocument.getCurrentPage().selectFirst();
}
}
EDIT: I tried changing the textbox to the dynamic text (from the input text) type and the problem is still exactly the same. I click the textbox, it selects the first MovieClip. I think it may have to do with using the same instance name, but since it's nested, why should it matter?
Looks like I figured it out on my own. Partially. I worked off what LDMS said in his comment "did you accidentally give them the same instance name?"
Well, no, I didn't. BUT- the textboxes all had the same instance name. This is irrelevant, but it got me focused on the textboxes names, and I realized that since I had mouseChildren set to false, the textboxes were the ones firing off the event listener.
So I changed up a bit of my code to look like this:
function panelClicked(e:Event)
{
//Panel gets selected
if (!e.target.name == "myText")
{
var panelIndex:int = int(e.target.name.substring(5));
uniDocument.getCurrentPage().deselectAllPanels();
uniDocument.getCurrentPage().getPanel(panelIndex).select();
}
}
And now it works! It's a simple workaround, since doing myText.mouseEnabled = false; was not an option because it needed to be clicked.
Hope this helps someone in the future! Cheers!

verifying a IF condition always AS3

I'm a beginner in AS3 so please if possible to give a point for a noob as answer. I want to have a specific button that is clicked to create a line, for example I click the button then I need to click twice on the stage
I click it and it is selected
I click first time on the stage to select the starting point of the line
I click second time on the stage to select the finishing point.
I tried to do it but i can`t manage to, if it is possible please help me. This is the code i wrote
dr_line.addEventListener(MouseEvent.CLICK,drawln);
var test:Boolean;
function drawln(e:MouseEvent):void{
test=true;
stage.addEventListener(MouseEvent.CLICK,reportClick);
}
var sx,sy,fx,fy:int;
var j:int;
function reportClick(event:MouseEvent):void
{
j=0;
j++;
if (test==true && j==1) {
sx=event.localX;
sy=event.localY;
}
j++;
test=true;
trace(j);
trace(test);
if (test==true && j==2) {
fx=event.localX;
fy=event.localY;
j=0;
test=false;
var line:Shape = new Shape();
line.graphics.beginFill(0x00FF00);
line.graphics.moveTo(sx,sy);
line.graphics.lineTo(fx,fy);
this.addChild(line);
}
}
How should i make it so this will work .. please help me , Thanks !!!! ,and yes the function reportClick should always be checked .... but i can`t get it going or when i press the dr_line button it should be active so it will be checked ....
You are assigning j=0 in click handler... you should do that in drawLn instead. Also, you require only one j++ in click handler.
But a cleaner approach would be to have two click listener point1ClickListener and point2ClickListener. You should attach to point1ClickListener in drawLn. Then inside point1ClickListener remove listening clicks to point1ClickListener and attach a click listener for point2ClickListener. Again, when point2ClickListener gets called remove listening for clicks to point2ClickListner.

Fake mouseclick on hover AS3

This morning I stumbled to this question:
When hovering a button, is it possible to click it automatically after X seconds? So the user doesn't need to click it with his mouse?
How can I let Flash believe my mouse really clicked some button on the stage or brought up with as3?
I have a lot of buttons in my movie. So I prefer to use some code which will cover this function for all existing or coming up buttons in my movie.
I would normally use a code like this but is there some workaround to accomplish this in a different way? I do no want to add code to every button.
this.addEventListener(MouseEvent.OVER, onMouseClickEvent);
public function onMouseClickEvent(event:Event)
{
trace(event);
if(event.buttonDown) // if button goes down normally
trace("MOUSE CLICKED NORMALLY");
else
trace("left button was not down");
}
The easiest way i think, is to subclass Button.
Then you should add mouse over/out listeners, add click listener that looks like that
:public function clickListener(event:MouseEvent = null){...}
When the mouse is hovering, raise a flag that the mouse is on the object, start a timer and when the timer callback function is called, you check the if the flag (you turn the flag down, when the mouse is out) is true and just call clickListener()
Listen for MouseEvent.MOUSE_OVER and start a timer, at the end of which the button will send the MouseEvent.CLICK event. In the mouseover handler, use the SystemManager to add a listener for MouseEvent.MOUSE_OUT which cancels the timer. The timer removes the listener using the SystemManager as well. So does clicking the button.
Finally! Solved!
This did the trick:
public function runOnce(event:TimerEvent):void {
btnSignal.dispatch("KEYBOARD", btnCode);
}
Robusto & Radoslav Georgiev: Thank you for pointing the right direction!
(I'm answering this a little late but would like to give input for future people).
One way to 'skin this cat' is to simply let your hover event trigger a timer (i.e. 3 seconds). In an EnterFrame or other function let a number or Boolean change when 3 seconds is reached.
//Pseudo code
if(timer == 3)
{ numberVar = 1;
//or
BooleanVar = True;
}
else
{
numberVar = 0;
//or
BooleanVar = false;
}
//end
Then just as you connected your methods to a mouseEvent, connect those same methods to fire when numberVar == 1 or BooleanVar == True. That's it.
For super simplicity and readability let your MouseClickEvent just be numberVar = 1 or BooleanVar = True.
These become super simple to implement over time and in my experience are 'very' error proof. Easy to fix also in the case of a typo or something else. No super elusive imports either. Hope that helped.
Great question by the way (+ 1)
:D