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;
}
Related
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
}
}
}
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();
}
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;
}
}
Hey Everyone so I am currently working on a game and the objective is for the user to click on objects on the stage. But the user has to click on the largest objects first before the user clicks on the smaller objects. I wanted to make it that if the user clicks on a smaller object first and not the larger one then the game will be over. I thought I could go about setting this up with booleans for each object on the stage but my if statements arent cutting it here is how I have it set up:
Here are my objects and booleans I use:
//Add box references
public var box_1:MovieClip;
public var box_2:MovieClip;
public var box_3:MovieClip;
public var box_4:MovieClip;
//Booleans
private var b1:Boolean;
private var b2:Boolean;
private var b3:Boolean;
private var b4:Boolean;
now I set all the Booleans to false and if the user clicks on one of the objects I set the Boolean to true.
Here are my if statements tied to my main ENTER_FRAME Listener:
private function level_1():void
{
if (b1)
{
mainScreen.box_1.gotoAndPlay("B1GONE");
b1 = false;
}else
if (b2)
{
mainScreen.box_2.gotoAndPlay("B2GONE");
b2 = false;
}else
if (b3)
{
mainScreen.box_3.gotoAndPlay("B3GONE");
b3 = false;
}else
if (b2 && !b1)
{
endGameCondition();
}
}
On this statement:
if (b2 && !b1)
{
endGameCondition();
}
I was trying to state that if box_2 is true meaning that its clicked on and box_1 hasnt been clicked on yet which is the larger object then the game is now over due to the user not clicking on the largest object first. I have it setup to where box_1 is the largest object and the others are the next size down.
Can anyone see why this isnt working correctly or if there is a better method in doing this?
**** UPDATE HOW MY MAIN CLASS IS SETUP NOW **************
Where I add all my Movie clips and variables:
public class boxTapEngine extends MovieClip
{
//Screens
private var mainScreen:mcMainScreen;
//Add box references
public var box_1:MovieClip;
public var box_2:MovieClip;
public var box_3:MovieClip;
public var box_4:MovieClip;
private var aBoxesArray:Array;
in my constructor function:
aBoxesArray = [box_1, box_2, box_3, box_4];
//AddMainScreen
mainScreen = new mcMainScreen();
mainScreen.x = (stage.stageWidth / 2);
mainScreen.y = (stage.stageHeight / 2);
stage.addChild(mainScreen);
//Initiate numbers
nLevel = 1;
for each(var box:MovieClip in aBoxesArray)
{
box.addEventListener(MouseEvent.CLICK, boxClick);
}
finally on the boxClick function:
private function boxClick(e:MouseEvent):void
{
var box:MovieClip = e.currentTarget as MovieClip; //get a reference to one that was just clicked
box.mouseEnabled = false; //we'll use this as a flag to know if it's been clicked yet
box.gotoAndPlay("BGONE");
//check to see if previous boxes have been clicked.
//this will iterate through all the boxes in order
for (var i:int = 0; i < aBoxesArray.length; i++)
{
if(aBoxesArray[i] == box) return; //if we've reached the currently clicked box, all is good, no need to keep checking so let's exit this loop and function
if (!aBoxesArray[i].mouseEnabled)
{ //one of the previous boxes hasn't been clicked yet
endGameCondition();
}
}
}
Probably isn't working because your final else if statement won't ever be reached (because you're handling b2 == true earlier on which will then bypass all other else statements). Plus your setting b2 to false when you handle it earlier, so it will always be false by the time it gets your final statement.
You need to move that final else if before you check for the other things. See code comments:
//Do this first, and not as a else if
if (b2 && !b1){
endGameCondition();
return; //no need to check checking things if it's game over
}
//now you can do the rest
if (b1)
{
mainScreen.box_1.gotoAndPlay("B1GONE");
b1 = false;
}else
if (b2)
{
mainScreen.box_2.gotoAndPlay("B2GONE");
b2 = false;
}else
if (b3)
{
mainScreen.box_3.gotoAndPlay("B3GONE");
b3 = false;
}
As an aside, you don't need the enter frame handler, you can just check everything on click. Something like this would work:
var boxes:Array = [box_1,box_2,box_3,box_4]; //make sure this is in order of what needs to be clicked first
//if you wanted to actually sort them dynamically based off total size (regardless of what order you've stuffed them in the array), you could add in something like this, which will order them from biggest to smallest:
boxes.sort(function(a,b){
//compare which item has a greater total area (width * height)
if(a.width * a.height > b.width * b.height) return -1; //A is bigger, so put a before b in the array
if(a.width * a.height < b.width * b.height) return 1; //put b before a in the array
return 0; //return 0 if they are the same
});
for each(var box:MovieClip in boxes){
box.addEventListener(MouseEvent.CLICK, boxClick,false,0,true);
}
function boxClick(e:Event):void {
var box:MovieClip = e.currentTarget as MovieClip; //get a reference to one that was just clicked
box.mouseEnabled = false; //we'll use this as a flag to know if it's been clicked yet
box.gotoAndPlay("BGONE");
//or you could just do this to get rid of the box:
if(box.parent) box.parent.removeChild(box);
//check to see if previous boxes have been clicked.
//this will iterate through all the boxes in order
for(var i:int=0;i<boxes.length;i++){
if(boxes[i] == box) return; //if we've reached the currently clicked box, all is good, no need to keep checking so let's exit this loop and function
if(!boxes[i].mouseEnabled){ //one of the previous boxes hasn't been clicked yet
endGameCondition();
}
}
}
//Store your clips in an array
var myClips:Array = [mc1,mc2,mc3,mc4];
//get the clip sizes and store it to an array.
var sizes:Array = new Array();
for (var i:uint = 0; i < myClips.length; i++) {
sizes.push(myClips[i].width);
}
//apply Numeric array sort.
sizes.sort(Array.NUMERIC);
function onClickAction(e:MouseEvent):void {
//Check wheather the array is empty or not.
if (sizes.length != 0) {
//Check wheather the clicked object bigger or not.
if (e.target.width == sizes[sizes.length - 1]) {
trace("Bigger");
e.target.alpha = .5;
sizes.splice(sizes.length-1,1);
} else {
trace("Smaller");
}
}
}
I have 9 movieclips, all with their function and i want to show a message after the user clicked on all the movieclips.
EX:
button1.addEventListener(MouseEvent.CLICK, showText1);
button2.addEventListener(MouseEvent.CLICK, showText2);
button3.addEventListener(MouseEvent.CLICK, showText3);
function showText1(e.Event)
{
text1.visible=true;
}
...
How do i check if all the buttons are clicked and after that, show a message?
Thank you.
Call a function like test on each click. In that function do something similar to:
function test() {
for (var i:uint = 0; i < 9; i++) {
if (this["text" + i].visible != false) { // do proper check; maybe visible, or maybe some variables - whatever fits your needs
return false;
}
}
return true; // do whatever you want here - all are 'clicked';
}