How can I make a symbol appear after clicking in two different buttons in actionscript 3.0? - actionscript-3

I am a little bit new in this programming stuff and I need help to program in ActionScript 3.0 (Adobe Animate CC). I want to make a symbol (graph) visible but only after clicking in two different buttons (button1 and button 2). I can make that with just one button, but I can't make it with two buttons... Can anyone help me? I tried this code but it isn't working as it should:
button1.addEventListener (MouseEvent.CLICK, fl_MouseClickHandler_1);
button2.addEventListener (MouseEvent.CLICK, fl_MouseClickHandler_1);
function fl_MouseClickHandler_1(event:MouseEvent):void
{
graph.visible = true;
}
Tom

Simplest way would be to do this, although there may be other ways to do it as well:
var isButton1Clicked:Boolean = false;
var isButton2Clicked:Boolean = false;
button1.addEventListener (MouseEvent.CLICK, fl_MouseClickHandler_1);
button2.addEventListener (MouseEvent.CLICK, fl_MouseClickHandler_1);
function fl_MouseClickHandler_1(event:MouseEvent):void
{
if (event.currentTarget == button2)
isButton2Clicked = true;
else if (event.currentTarget == button1)
isButton1Clicked = true;
if (isButton1Clicked && isButton2Clicked)
{
graph.visible = true;
isButton1Clicked = isButton2Clicked = false;
}
}
Note that I reset both the Boolean values to false, once the graph is visible so that it works like a reset.
On a side note, I would recommend to use better names for your buttons and your event handlers. Just best practice.
Hope this helps. Cheers.

Related

Swapping the image used for my character, to a seperate image on button click

So first off i'd like to state that i am not very good at AS3, i'm completely self taught so i am sure that there are many things i've done badly, inefficiently or plain wrong and i'm happy for any comments on these if there is things i can improve.
Okay so, this seems like a really simple problem but i don't know the exact code for it and i can't find an example anywhere
what i want to do is to change the image which i am using for my character to a separate image on a button click, then after a certain amount of time for him to go back to the original.
My image is set as a movie clip and i am calling it like so :
public var Smallclock_hero = new Smallclock;
it is worth noting that smallclock has it's own separate class.
is there a way that i can change this image on a mouse click event ?
A simple way would be:
Add a new image on the second frame of the Smallclock movieclip. Have this new image span several frames of the timeline for the duration you want it to appear for.
Place a stop(); action on the first frame of the Smallclock movieclip.
btn.addEventListener(MouseEvent.CLICK, btnChangeCharacterFrame);
function btnChangeCharacterFrame(e:MouseEvent)
{
Smallclock_hero.gotoAndPlay(2);
// Or use a frame label
// Smallclock_hero.gotoAndPlay("jump");
}
This can be achieved relatively simply using the visible property and setTimeout. When you click on your MovieClip you'll want to make the old image invisible and the new image visible:
oldImage.visible = false;
newImage.visible = true;
Then you'll want to use setTimeout to change the visible properties back to:
oldImage.visible = true;
newImage.visible = false;
setTimeout can run a function after a specified number of milliseconds. Here is an example of this technique on wonderfl : http://wonderfl.net/c/acxl
private var imageA:ImageA = new ImageA();
private var imageB:ImageB = new ImageB();
private var revertId:int;
public function Main() {
imageB.visible = false;
addChild(imageA);
addChild(imageB);
addEventListener(MouseEvent.CLICK, onClick);
}
private function onClick(e:MouseEvent):void{
clearTimeout(revertId);
revertId = setTimeout(revert, 1000);
imageB.visible = true;
imageA.visible = false;
}
private function revert():void{
imageB.visible = false;
imageA.visible = true;
}

Actionscript 3 drag and drop on multiple specific targes and change alpa for the dropped objects as well as stack targets

I have been trying to achieve three things in the project without success. I am new at this and have relied on tutorials to get this far. Here we go!!
a. I want to be able to drop label_3 and label_4 on either or targetlabel_3 and targetlabel_4 but not effect the other labels and targets.
b. I want to be able to drop label_2 on top of label_1 once it has been dropped. I am finding that when label_1 has been dropped, it hides the targetlabel_2 and label_2 can't find it's target.
c. I want to change the Alpa of each of labels _1, _2, _3, _4 and _5 to zero when they are dropped on their targets and change the Apha for labels _11, _21, _31, _41 and _51 to 100. (I have changed the Apha to 25 on these for the sake of making it easier for someone to see what I am trying to do).
I have been mucking around for days on this and have hit a brick wall.
Can anyone help please?
import flash.display.DisplayObject;
import flash.geom.Rectangle;
/* Drag and Drop
Makes the specified symbol instance moveable with drag and drop.
*/
var startX:Number;
var startY:Number;
var counter = 0;
var attempts = 0;
var rect:Rectangle;
rect=new Rectangle(100,100,700,500);
correct_txt.text=counter;
attempts_txt.text=attempts;
label_1.addEventListener(MouseEvent.MOUSE_DOWN,Drag);
label_1.addEventListener(MouseEvent.MOUSE_UP,Drop);
label_2.addEventListener(MouseEvent.MOUSE_DOWN,Drag);
label_2.addEventListener(MouseEvent.MOUSE_UP,Drop);
label_3.addEventListener(MouseEvent.MOUSE_DOWN,Drag);
label_3.addEventListener(MouseEvent.MOUSE_UP,Drop);
label_4.addEventListener(MouseEvent.MOUSE_DOWN,Drag);
label_4.addEventListener(MouseEvent.MOUSE_UP,Drop);
label_5.addEventListener(MouseEvent.MOUSE_DOWN,Drag);
label_5.addEventListener(MouseEvent.MOUSE_UP,Drop);
label_1.buttonMode = true;
label_2.buttonMode = true;
label_3.buttonMode = true;
label_4.buttonMode = true;
label_5.buttonMode = true;
function Drag(event:MouseEvent):void
{
event.target.startDrag(true,rect);
feedback_txt.text="";
event.target.parent.addChild(event.target);
startX=event.target.x;
startY=event.target.y;
}
function Drop(event:MouseEvent):void
{
event.target.stopDrag();
var myTargetName:String="target" + event.target.name;
var myTarget:DisplayObject=getChildByName(myTargetName);
if (event.target.dropTarget!=null&&event.target.dropTarget.parent==myTarget){
feedback_txt.text="Well done! You have selcted the correct label and placed it in the recommended position on the package.";
feedback_txt.textColor = 0xCC0000
event.target.removeEventListener(MouseEvent.MOUSE_UP,Drop);
event.target.removeEventListener(MouseEvent.MOUSE_DOWN,Drag);
event.target.buttonMode = false;
event.target.x=myTarget.x;
event.target.y=myTarget.y;
counter++;
correct_txt.text=counter;
correct_txt.textColor = 0x0000ff
attempts++;
attempts_txt.text=attempts;
attempts_txt.textColor = 0x0000ff
}else{
feedback_txt.text="Your attempt is not quite correct. You have either selected the incorrect label or placed it in the wrong position. Please try again.";
event.target.x = startX;
event.target.y = startY;
attempts++;
attempts_txt.text = attempts;
}
if (counter==5){
feedback_txt.text="Well done! You have correctly placed all 5 labels";
percentage_txt.text ="Based on your attempts, you have scored "+Math.round ((counter/attempts) *100)+" %";
percentage_txt.textColor = 0x0000ff
}
}
The easiest way to detect when a label is on another label is by using hittest in an enter frame event listener.
stage.addEventListener(Event.ENTER_FRAME, hit_test);
function hit_test(e:Event):void{
if (label_1.hitTestObject(targetLabel_1)) {
trace("Label_1 is hitting targetlabel_1");
label_hit();
}
if (label_2.hitTestObject(targetLabel_2)) {
trace("Label_2 is hitting targetlabel_2");
label_hit();
}
}
When the hittest is activated, the trace text is shown and the function is called. To change the alphas of the labels, use the function being called by the hittest. For example:
function label_hit()
{
label_1.alpha = 0;
label_2.alpha = 0;
label_3.alpha = 0;
}
If you are trying to have conditions to when things can be dragged, seen, or hit tested, that function is also where you can take care of them. For example, If you don't want a label to be visible until the hittest, you have the alpha set to 0 until the function sets it to 100. If you don't want a label to be drageable until then, you create the listener inside the function instead of earlier.
function label_hit()
{
label_1.alpha = 100;
label_1.addEventListener(MouseEvent.MOUSE_DOWN,Drag);
label_1.addEventListener(MouseEvent.MOUSE_UP,Drop);
}
If you want hittests to occur only after other hittests have already occured, place them in conditions and have the conditions met in the functions.
stage.addEventListener(Event.ENTER_FRAME, hit_test);
function hit_test(e:Event):void{
if (label_1.hitTestObject(targetLabel_1)) {
trace("Label_1 is hitting targetlabel_1");
label_hit();
}
if(condition)
{
if (label_2.hitTestObject(targetLabel_2)) {
trace("Label_2 is hitting targetlabel_2");
label_hit();
}
}
function label_hit()
{
var condition = true;
}

AS3 - Tools that drag and rotate in flash TOOL MODE

I'm making an app/program that allows you to design your own piece of art with two basic functions by clicking the buttons on the UI, We'll call the 'Modes' for now.
Tweezer mode: you can drag the selected set of objects about in this mode.
Rotate Mode: this allows you to rotate a certain set of movie clips on the stage.
Assigning it.
I want it so that when rotate mode or tweezer mode is active the other is disenaged (enabled = false) or to that effect. I have arrived at a fork in the road where I need group them under method rotate or method tweezer. When tweezer is clicked, you move stuff about (only), and when rotate mode is selected you can rotate the movie clips...(only) this works fine until after you come away from rotate mode back tweezer that you can still rotate the movie clip! Could anyone shed some light on this so when I leave this mode you still can rotate it? Could any suggest the best way to organize this sort of functionality?
Thanks for your help - I'm an AS3 newbie.
// UI btns TOOLS ---------------------
spinny_mc.addEventListener(Event.ENTER_FRAME, fl_RotateContinuously);
function fl_RotateContinuously(event:Event)
{
spinny_mc.rotation += 20;
}
rotate_btn.visible = true;
tweezer_btn.visible = false;
//----- rotate tool
rotate_btn.addEventListener(MouseEvent.CLICK, spinmode);
function spinmode(event:MouseEvent):void
{
Mouse.hide();
stage.addEventListener(MouseEvent.MOUSE_MOVE,followspin);
function followspin(evt:MouseEvent)
{
spinny_mc.x = mouseX;
spinny_mc.y = mouseY;
rotate_btn.visible = false;
tweezer_cur.visible = false;
tweezer_btn.visible = true;
rotate_btn.enabled = true;
tweezer_btn.enabled = false;
skullface_mc.addEventListener(MouseEvent.CLICK, turnerbone);
function turnerbone(event:MouseEvent):void
{
skullface_mc.rotation+=45;
}
}
}
// ------------------------ tweeze tool
Mouse.hide();
stage.addEventListener(MouseEvent.MOUSE_MOVE,follow);
function follow(evt:MouseEvent){
tweezer_cur.x = mouseX;
tweezer_cur.y = mouseY;
}
tweezer_btn.addEventListener(MouseEvent.CLICK, tweezer);
function tweezer(event:MouseEvent):void
{
Mouse.hide();
stage.addEventListener(MouseEvent.MOUSE_MOVE,tweezer);
function tweezer(evt:MouseEvent){
tweezer_cur.x = mouseX;
tweezer_cur.y = mouseY;
rotate_btn.visible = true;
tweezer_cur.visible = true;
tweezer_btn.visible = false;
spinny_mc.visible = false;
rotate_btn.enabled = false;
tweezer_btn.enabled = true;
}
}
The problem comes down to your event listeners. They don't go away after you leave the function, as they are essentially objects in and of themselves. You need to do that manually.
At the top of the spinmode() function, add the line
stage.removeEventListener(MouseEvent.MOUSE_MOVE,tweezer);
At the top of the tweezer() function, add the line
stage.removeEventListener(MouseEvent.MOUSE_MOVE,followspin);
WARNING: I cannot rightly recall if this will throw an error if the event listener has not yet been created. If so, you can get around that using a Try/Catch, or an if-statement that links to a variable indicating what mode the user is in.
You may also need to rearrange your code a bit. I do not recommend nesting functions that affect the stage, as they can make life kinda difficult. Define the functions separately, and then call the other functions from the one you want.
Keep in mind, ActionScript is Object-Oriented, not procedural (and NOT strictly top-down). I'm not sure if you're coming from another language, but I know that took a lot of getting used to for me, coming from a procedural top-down technique.
WRONG
function myFunction1()
{
function myFunction 2()
{
//foobar
}
}
RIGHT
function myFunction1()
{
myFunction2();
}
function myFunction2()
{
//foobar
}

Creating a vector array of movie clips AS3

I have several movie clips on the stage of my main .fla named btn1-btn7 which will act as buttons. I have a class file named Functions.as where an event listener is created when a button is clicked. onButtonClicked is just going to a frame on the timeline.
obj.addEventListener(MouseEvent.CLICK, onButtonClicked);
I would like the ability to set the buttonMode, visibility, etc. of all of the buttons simultaneously. I have been looking into this for a few hours and am not able to find any solutions. I am now looking into adding them to a vector (which is a new concept for me), but I am not sure how to go about executing this properly. This is what I have so far.
public var buttons:Vector.<MovieClip > = new Vector.<MovieClip > ();
function addButtons()
{
buttons.push(btn1,btn2,btn3,btn4,btn5,btn6,btn7);
for (var i:int; i<buttons.length; i++)
{
trace(buttons[i].name);
}
}
How would I go about, for example, adding the event listener to all of the objects? I will also be setting the buttonMode to true, and making them all invisible simultaneously. I don't even know if it's possible to accomplish this. Thank you in advance for any suggestions.
I'm going to asume that you use timeline code, and have instances of the buttons already placed on the stage. So, first, create the vector:
var _btns:Vector.<MovieClip> = new Vector.<MovieClip>;
_btns.push(btn1,btn2,btn43....) //add all the buttons
Than, you can init the properties of all the buttons:
var _mc:MovieClip;//helper var
for(var i:int=0,i<_btns.length;i++)
{
_mc = _btns[i];
_mc.visible = false;
_mc.buttonMode = true;
_mc.addEventListener(MouseEvent.CLICK, onClick);
}
Then, the event handler:
function onClick(e:MouseEvent):void
{
for(var i:int=0,i<_btns.length;i++)//reset all the buttons
{
_btns[i].visible = false;
}
_mc = MovieClip(e.eventTarget);
_mc.visible = true; //make visible the clicked one
}
You just need to do what you are doing with the .name property in your example code. You need to loop thru every single button in your array (or vector, if you prefer). Here is an example how to set the property of buttonMode:
function setButtonMode(b:Boolean):void {
for(var i:int=0; i<buttons.length; i++) {
var btn:MovieClip = buttons[i]; //store the current reference in a var for faster access
btn.buttonMode = b;
btn.mouseChildren = !b;
}
}

Disable a function temporarily as3

On my screen are tiles generated from an array. I have a mouse roll over function called rollover, that adds a movieclip that highlights the edge of the tiles that I am currently on. I want it so that once I click a tile, the roll over function doesn't work until another button is clicked. I tried putting removeEventListener for the roll over function in the click function, doesn't seem to work. How would I go about this if possible?
I will post more information if needed.
function rollover(event:MouseEvent)
{
var tileHover = true;
if (tileHover == true){
(event.currentTarget as Tile).outline.gotoAndStop("hover");
}
if(tileHover == false){
(event.currentTarget as Tile).outline.gotoAndStop("blank");
}
}
Below is the mouseclick function
function mouseclick(event:MouseEvent)
{
tileHover = false;
if (tileHover == false){
tile_MC.removeEventListener(MouseEvent.ROLL_OVER, rollover)
}
}
See below. You set a property and immediately check what the value of that property is. It will always be true because you just set it as true.
var tileHover = true;
if (tileHover == true){
(event.currentTarget as Tile).outline.gotoAndStop("hover");
}
Also, don't forget your data types.
I think you need to have (event.currentTarget as Tile).outline.gotoAndStop("blank"); in mouseclick.
Also, I assume tilehover is some global variable used for tracking the hover state. Explicitly setting it true/false in the handler is just for debugging purposes!!