how to stop button from become clickable after certain counter value? - actionscript-3

I try to make increase and decrease button but I want to make that if the increase button hit the max value it will become unavailable and stop the user from interact with the increase button and vice versa with the decrease button.
import flash.events.MouseEvent;
a1.visible=true;
a2.visible=false;
a3.visible=false;
plus.visible=false;
minus.visible=false;
final var clickCounter:Number=0;
e1.addEventListener(MouseEvent.CLICK, decider);
function decider(event:MouseEvent):void{
plus.visible=true;
minus.visible=true;
if (a1.visible==true){
plus.addEventListener(MouseEvent.CLICK, changer1);
plus.addEventListener(MouseEvent.CLICK, increaser1);
minus.addEventListener(MouseEvent.CLICK, changer1);
minus.addEventListener(MouseEvent.CLICK, decreaser1);
}
}
function increaser1(event:MouseEvent):void{
clickCounter++;
if(clickCounter==3){
plus.removeEventListener(MouseEvent.CLICK, changer1);
plus.removeEventListener(MouseEvent.CLICK, increaser1);
minus.addEventListener(MouseEvent.CLICK, changer1);
minus.addEventListener(MouseEvent.CLICK, decreaser1);
}
}
function decreaser1(event:MouseEvent):void{
clickCounter--;
if(clickCounter==-1){
plus.addEventListener(MouseEvent.CLICK, changer1);
plus.addEventListener(MouseEvent.CLICK, increaser1);
minus.removeEventListener(MouseEvent.CLICK, changer1);
minus.removeEventListener(MouseEvent.CLICK, decreaser1);
}
}
function changer1(event:MouseEvent):void{
if(clickCounter==0){
trace("1");
}
if(clickCounter==1){
trace("2");
}
if(clickCounter==2){
trace("3");
}
}
This code manages to do what I want to archive but when I click the increase button more than 3 times and try to click decrease button, it will take time to decrease it.

It's much simpler than you did it, actually.
var clickCounter:int = 2;
arrangeButtons();
plus.addEventListener(MouseEvent.CLICK, onPlusMinus);
minus.addEventListener(MouseEvent.CLICK, onPlusMinus);
function onPlusMinus(e:MouseEvent):void
{
// Check for non-mouse interactions.
if (!e.target.mouseEnabled) return;
// Change the value based on which botton was clicked.
clickCounter += ((e.currentTarget == plus)? 1: -1);
// Adjust buttons to current counter value.
arrangeButtons();
// Output the values.
trace(clickCounter + 1);
}
function arrangeButtons():void
{
// Enable and disable buttons on margin values.
minus.mouseEnabled = (clickCounter > 0);
plus.mouseEnabled = (clickCounter < 2);
// Display enabled/disabled status.
minus.alpha = (minus.mouseEnabled? 1: 0.5);
plus.alpha = (plus.mouseEnabled? 1: 0.5);
}

Related

How to create a sequence of clicks in ActionScript?

I am creating a puzzle in which the player have to click on the buttons on the right order or sequence to go to the next level (Scene 2 for example). I don't know how to do it. If any one have any idea to how to achieve this in Action Script.
Thank you
Scene 1:
enter image description here
each number is a button. Now the player has to click in the right order or sequence (1 2 3 4 5 6 7 8) to open the next level (Scene 2)
var checkString:String = "";
//Create event listeners and their functions.
btn1.addEventListener(Mouse.CLICK, oneClick);
btn2.addEventListener(Mouse.CLICK, twoClick);
btn3.addEventListener(Mouse.CLICK, threeClick);
btn4.addEventListener(Mouse.CLICK, fourClick);
btn5.addEventListener(Mouse.CLICK, fiveClick);
btn6.addEventListener(Mouse.CLICK, sixClick);
btn7.addEventListener(Mouse.CLICK, sevenClick);
btn8.addEventListener(Mouse.CLICK, eightClick);
function oneClick(evt:Event):void
{
//In each event listener function, add a letter or
//string to the checkString variable.
checkString += "on";
//Then, see if the string matches or not.
check();
}
function twoClick(evt:Event):void
{
checkString += "tw";
check();
}
function threeClick(evt:Event):void
{
checkString += "th";
check();
}
function fourClick(evt:Event):void
{
checkString += "fo";
check();
}
function fiveClick(evt:Event):void
{
checkString += "fi";
check();
}
function sixClick(evt:Event):void
{
checkString += "si";
check();
}
function sevenClick(evt:Event):void
{
checkString += "se";
check();
}
function eightClick(evt:Event):void
{
checkString += "ei";
check();
}
//If the proper sequence is one, two, three, four, five, six, seven, eight the string would read "ontwthfofisiseei".
function check():void
{
if(checkString == "ontwthfofisiseei")
{
//Clear the checkString for convenience before going on.
clearString();
//CODE TO GO TO NEW FRAME
gotoAndPlay(1, "Scene 3");
}
}
function clearString():void
{
//You will want to have a function for clearing the string.
//This is especially useful if you have a button for "start over."
checkString = "";
}
this the code i used before but it show error in the listener and it doesn't. work
To answer your updated question:
Your error is likely that Mouse.CLICK should be MouseEvent.CLICK.
Your other error is telling you that there is no scene called "Scene 3"
Let's assume you have 8 MovieClips (or buttons) that are on a timeline in Flash/Animate.
One (of many) ways to accomplish this would be the following:
Give each of those buttons an instance name. To make for less code, lets give them the name btn + their respective correct order number - so btn1, btn2, btn3 etc.
You'll need to add a click listener to each button, so they can have something happen when they are clicked.
You could do this 8 times (one for each button): btn1.addEventListener(MouseEvent.CLICK, buttonClick); but to make things simpler, you can just iterate through all the objects on the timeline and add the listener to each object whose name starts with "btn":
var totalBtns:int = 0; //create a var to store how many buttons there are
//loop through each child of the current timeline
var i:int = numChildren;
while(i--){
//if the child's name starts with 'btn'
if(getChildAt(i).name.indexOf("btn") == 0){
//add the click listener
getChildAt(i).addEventListener(MouseEvent.CLICK, buttonClick,false,0,true);
totalBtns++; //increase the total buttons variable by 1
}
}
This also means less work later if you add/remove buttons
You need a way to track when a button was clicked. To accomplish this, we'll use an array.
var clickArray:Array = []; //this creates a new array
//When a button is clicked, you add it to this array
lets create the function that is called when a button is clicked:
function buttonClick(e:Event):void {
//add the item that was just clicked (represented by the event's currentTarget property) to the array
//so if btn1 was just clicked, btn1 would be e.currentTarget
clickArray.push(e.currentTarget);
//now disable the button so it can't be clicked anymore
SimpleButton(e.currentTarget).enabled = false;
//check if all button have been clicked
if(clickArray.length == totalBtns){
//lets go through every item in the array, and see if it's in the right order
var ctr:int = 0; //a counter to keep track of the expected next number var i:int = 0; //iterator for the for loops
for(i=0;i<clickArray.length;i++){
//lets convert everything after the 3rd character of the name to a number - so for btn1, that would be 1
if(parseInt(clickArray[i].name.substring(3)) == ctr + 1){
ctr++; //increment the counter to the next expected number
}else{
break; //leave the for loop early since a click was out of place
}
}
//if the correct order was achieved
if(ctr == totalBtns){
nextScene(); //or however you continue
}else{
//the correct order was NOT acheived
//make all the buttons clickable again
for(i=0;i<clickArray.length;i++){
SimpleButton(clickArray[i]).enabled = true;
}
//reset the array
clickArray = [];
//probably want to tell the user to try again
}
}
}

AS3 multiple (movieclip buttons) to animate one movieclip

I am developing a desktop application. I am using ActionScript 3 via Adobe Animate CC. I designed the application, animated the GUI, and started coding. The main functions were successfully coded well, but I have added some additional features which are out of the scope of the application's original goals. All of this just to link the application to a website and some other information, which made me totally crazy because I've spent too much time with very simple if statement LOGIC!
Anyway, I created a menu with three MovieClip buttons. These menu button clicks affect one MovieClip that has a white background that moves with each click. I need there to be one background to show the beautiful effect of easeIn and easeOut animation tweens when clicking each button.
About clicked
Gallery clicked
Contact clicked
To make it easy to understand, I recreated the code with a very simple ball and 3 buttons. If you click first button, the ball moves to the right above the 2nd button. Then the first button should be unclickable, unless another button is clicked. If the second button is clicked, then the ball would move to the right above the third button. Then the second button should be unclickable also, unless another button is clicked. The same thing goes for the third button.
Now, if the first button is clicked again, the animation of the white background should not start from the default position when starting up the application!
It should animated back from its current position to the default position... and so on...
I replaced the white background with a ball for simplicity
This is very easy but I lost it with the eventListeners, eventHandlers, and if statements! :/
I also made this table which studies the cases:
I know my coding technique is not smart enough, but that is because I HATE using classes, packages, project folders... etc..
Even if the code runs too long & repeats, It would be better for me for simplicity, as programming is not my day-job!
Please, any help and quick response would be highly appreciated!
Code:
import flash.ui.Mouse;
import flash.events.MouseEvent;
one.addEventListener(MouseEvent.CLICK, moveToSecondPos);
two.addEventListener(MouseEvent.CLICK, moveToThirdPos);
//three.addEventListener(MouseEvent.CLICK, moveToFirstPos);
var buttonState:Boolean;
one.buttonState = 0;
two.buttonState = 0;
//three.buttonState = 0;
function moveToSecondPos(event:MouseEvent){
if(one.buttonState == 0){
theBall.gotoAndPlay("go1");
one.buttonState = 1;
}
else if(two.buttonState == 1){
theBall.gotoAndPlay("backToOne");
// two.buttonState = 0;
// one.buttonState = 1;
}
else{
//disable About Button
one.removeEventListener(MouseEvent.CLICK, moveToSecondPos);
}
}
function moveToThirdPos(event:MouseEvent){
if((two.buttonState == 0)&&(one.buttonState == 0)){
theBall.gotoAndPlay("goProducts");
two.buttonState = 1;
}
else if(one.buttonState == 1){
theBall.gotoAndPlay("go2");
// two.buttonState = 1;
// one.buttonState = 1;
}
else{
two.removeEventListener(MouseEvent.CLICK, moveToThirdPos);
}
}
//function moveToFirstPos(event:MouseEvent){
// if(three.buttonState == 0){
// theBall.gotoAndPlay("go3");
// three.buttonState = 1;
// }
// else{
// three.removeEventListener(MouseEvent.CLICK, moveToFirstPos);
// }
//}
First, you mentioned you wanted to have the
white background should not start from the default position when starting up the application
For that, you'll need a ShareObject or comparable method of saving and loading data.
Secondly, It appears you may be trying to do some of this with Scenes and Timeline' frames. I highly encourage you not to pursue that.
Below is a solution to the problems you mentioned. Notice that without your project, I had to recreate the scene. You can copy & paste the solution into a new scene and it will compile.
To prevent buttons from being clicked, you can remove the event listener by calling myButton.removeEventListener("click"). Alternatively, you can simply stop the object from responding to mouse events by setting its mouseEnabled property to false.
To animate the box smoothly, you can use the built-in Tween class. Alternatively, I'd direct you Greensock's TweenLite.
Because you appeared to want a series of labels to appear depending on the button clicked, I created an array which stores data specific to each button (btns:Array). By using an organized structure, it's easier to write re-useable code which doesn't depend on explicit functions. Note that there's only one btnListener() function which works for all of your buttons.
Solution
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import fl.motion.Color;
import fl.transitions.*;
import fl.transitions.easing.*;
// the list of buttons we want, along with the descriptions for each
var btns:Object = [
{
"label":"About",
"desc":"Learn more about us",
"btn":null
},
{
"label":"Gallery",
"desc":"See our photos",
"btn":null
},
{
"label":"Contact",
"desc":"Write, call, or message",
"btn":null
}
];
var nav:Sprite; // our navigation bar of buttons
var whiteBox:Sprite; // the "ball" with the content text
// where we save the coordinates of the whiteBox between loads
var settings:Object = SharedObject.getLocal("foo");
init();
function init():void {
// Create our navigation of three buttons
// our container for buttons
nav = new Sprite();
// reference to the last button
var last:Sprite = null;
// loop through the list of buttons
for each (var entry:Object in btns) {
// For each button, create a new button
var btn:Sprite = createButton(entry.label);
entry.btn = btn;
nav.addChild(btn);
// If there was a previous button, place this beside it.
if (last != null) {
btn.x = last.x + last.width + 1;
}
last = btn;
}
// Place the nav onscreen
addChild(nav);
nav.x = stage.stageWidth/2 - nav.width/2;
nav.y = stage.stageHeight - nav.height*2;
// Create the whitebox
whiteBox = new Sprite();
whiteBox.graphics.beginFill(0xFAFAFA);
whiteBox.graphics.drawRect(0, 0, 150, 50);
whiteBox.graphics.endFill();
var txt:TextField = new TextField();
txt.name = "txt";
txt.width = 150;
whiteBox.addChild(txt);
nav.addChild(whiteBox);
// Load the settings from the last run of the program.
if (settings.data.hasOwnProperty("x")) {
whiteBox.x = settings.data.x;
whiteBox.y = settings.data.y;
}
}
function createButton(label:String):Sprite {
// Creates a simple button
// Create the label
var txt:TextField = new TextField();
txt.text = label;
// Create the background
var btn:Sprite = new Sprite();
btn.graphics.beginFill(0xA1A1A1);
btn.graphics.drawRect(0, 0, txt.width + 60, txt.height + 30);
btn.graphics.endFill();
btn.addChild(txt);
btn.name = label;
txt.x = 30;
txt.y = 15;
// Hookup events
btn.addEventListener("mouseOver", btnListener);
btn.addEventListener("mouseOut", btnListener);
btn.addEventListener("click", btnListener);
return btn;
}
function btnListener(e:Event):void {
var btn:Sprite = e.currentTarget as Sprite;
var c:Color = new Color();
var entry:Object;
// Find our button in the list.
for each (entry in btns) {
if (entry.label == btn.name) {
break;
}
}
switch (e.type) {
case "mouseOver":
if (btn.mouseEnabled) {
c.setTint(0x0096ff, 0.5);
btn.transform.colorTransform = c;
}
break;
case "mouseOut":
if (btn.mouseEnabled) {
c.setTint(0x00, 0);
btn.transform.colorTransform = c;
}
break;
case "click":
// Set the text, and position of our whitebox
whiteBox.getChildAt(0)["text"] = entry.desc;
whiteBox.y = -whiteBox.height;
var tween:Tween = new Tween(whiteBox, "x", Regular.easeOut, whiteBox.x, btn.x, 0.35, true);
tween.addEventListener("motionFinish", saveState);
for each (var v:Object in btns) {
if (v.btn == btn) {
// make our button unclickable
btn.mouseEnabled = false;
c.setTint(0xFFFFFF, 0.5);
btn.transform.colorTransform = c;
} else {
// Make the other buttons clickable;
v.btn.mouseEnabled = true;
c.setTint(0x00, 0);
v.btn.transform.colorTransform = c;
}
}
break;
}
}
function saveState(e:Event):void {
settings.data.x = whiteBox.x;
settings.data.y = whiteBox.y;
settings.flush();
}

Making layers invisible with mouse click

Is it possible to make it so that when you click on a button the first time, a specific layer will become invisible... and then once you click on the button a second time, a different layer would become invisible, and so on? If so could I see an example? Thanks!
What I've tried :
/************************* RESET BUTTON **************************/
reset_btn.addEventListener(MouseEvent.CLICK,reset);
function reset(e:Event) : void
{
eraserClip.graphics.clear();
initEraser();
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
penny.visible = true;
maskee4.visible = true;
card.visible = false;
greencard.visible = true;
}
The idea is, once I hit the reset button once, the layer named card, will disappear. Underneath that a layer will be there, which is titled greencard. Once I hit the reset button a second time I want the greencard to disappear. As you see above, I was just doing (property name).visible = false;. This works for the first card but not any after because they would not appear.
If I understand you correctly, you could try something like this below :
reset_btn.addEventListener(MouseEvent.CLICK, reset);
var clickCount : int = 0; //# start with zero since no clicks yet
card.visible = true;
greencard.visible = true;
function reset(e:Event) : void
{
clickCount += 1; //# adds +1 to current count of clicks
eraserClip.graphics.clear();
initEraser();
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
penny.visible = maskee4.visible = true; //# if same value (true) you can chain them like this
if ( clickCount == 1) //if now 1 click
{
card.visible = false;
}
if ( clickCount == 2) //if now 2 clicks
{
greencard.visible = false;
}
}

Hide button after click two times or more on as3

i am new on as3.
i want to ask how to hide button after click two times or more on as3.
the code below i got from code snippets, but the button hide after one click.
BTNhint.addEventListener(MouseEvent.CLICK, fl_ClickToHide);
function fl_ClickToHide(event:MouseEvent):void
{
BTNhint.visible = false;
}
You have just to count the button clicks and then after two clicks you can hide your button :
var click_counter:int = 0;
BTNhint.addEventListener(MouseEvent.CLICK, fl_ClickToHide);
function fl_ClickToHide(event:MouseEvent):void
{
click_counter ++; // you can write it : click_counter = click_counter + 1;
if(click_counter >= 2){ // you can write it : if(click_counter > 1)
BTNhint.visible = false;
}
}
You can use a constant (LIM) to determine how many times your button must be clicked, compare it to a variable (c) that is counting your clicks, and use your MouseEvent's target property to target your button itself when you want it to disappear:
var c:int = 0;
const LIM:int = 2;
BTNhint.addEventListener(MouseEvent.CLICK, hideMe);
function hideMe(event:MouseEvent):void
{
if(++c >= LIM) event.target.visible = false;
}

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