Actionscript 3: How to detect when a button isn't pressed in time? - actionscript-3

Okay, this is another question for the game I am making. I am putting together a second level, where you need to press a long series of keys at the right time. Pressing them too early or too late results in failure. What I need to know is how to detect when a key ISN'T pressed, when it should have been. This is what I have so far:
var count3:Number = 23;
var myTimer3:Timer = new Timer(1000, count3);
var timeLeft3:Number = count3;
var buttonPressed:Boolean = false;
var btnCounter:Number = 2;
var btnTimer:Timer = new Timer(1000, btnCounter);
myTimer3.addEventListener(TimerEvent.TIMER, countdown3);
myTimer3.start();
btnTimer.addEventListener(TimerEvent.TIMER, btnCountdown);
btn1.addEventListener(MouseEvent.CLICK, buttonPress);
btn1.visible = false;
btn2.visible = false;
btn3.visible = false;
btn4.visible = false;
btn5.visible = false;
btn6.visible = false;
btn7.visible = false;
btn8.visible = false;
btn9.visible = false;
function countdown3(event:TimerEvent): void {
if (((count3)-myTimer3.currentCount)==20) {
btn1.visible = true;
btnTimer.start();
} else if (((count3)-myTimer3.currentCount)==19) {
btn1.visible = true;
} else {
btn1.visible = false;
}
}
function btnCountdown(event:TimerEvent):void {
if (((btnCounter)-btnTimer.currentCount)==0) {
if (buttonPressed = true) {
btnTimer.stop();
} else {
gotoAndStop(2);
}
}
}
function buttonPress (event:MouseEvent): void {
buttonPressed = true;
}
For some reason, it won't do anything when btnCounter hits 0. If someone could help me sort this out, that would be awesome. Thanks.
N.B. This is a personal project, I am just learning actionscript

Start a timer for the time duration when the button is supposed to be pressed (for example, if the button must be pressed within 2 seconds, set the timer's interval to 2 seconds).
Then create a global Boolean variable (or class member variable, however your scene is set up) and set it to false initially. When the button is pressed, set this variable to true and disable the timer.
If the timer fires and this variable is false, it means that it hasn't been disabled by the button so the user didn't click the button within 2 seconds.
Don't use terribly short times - timers are not very accurate and processor speed may have an effect on their duration. (Human reaction times aside.)

Related

Bad increment AS3

I need to get my work increment and decrement variables mcnf5 and cnt5. The problem is that in this first pass code adds / subtracts 1, then 3, 5, etc ... I do not know exactly what causes it, but I need to impute variable when it clicks zdenca_volba1, zdenca_volba2 or zdenca_volba3 and with the delay I set. But the increment works just as it is not part of these functions. How to modify your code to work correctly delay and increment ?? Code is in actionscript3
function zdeClick5(event:MouseEvent):void{
if ((zdenca5ON == false)&&(mcnf5 > 0)) {
zdenca_prace5.visible = true;
zdenca_prace5.zdenca_volba1.addEventListener(MouseEvent.CLICK,z1Click5);
function z1Click5(event:MouseEvent):void{
zdenca_prace5.visible = false;
zdenca5.play();
zdenca5ON = true;
setTimeout(timedFunction51,3000);
function timedFunction51() {
mcnf5--;
mcnt5++;
mcnft5.text = mcnf5.toString();
mcntt5.text = mcnt5.toString();
zdenca5ON = false;
zdenca5.stop();}
}
zdenca_prace5.zdenca_volba2.addEventListener(MouseEvent.CLICK,z2Click5);
function z2Click5(event:MouseEvent):void{
zdenca_prace5.visible = false;
zdenca5.play();
zdenca5ON = true;
setTimeout(timedFunction52,10000);
function timedFunction52() {
mcnf5--;
mcnt5++;
mcnft5.text = mcnf5.toString();
mcntt5.text = mcnt5.toString();
zdenca5ON = false;
zdenca5.stop();}
}
zdenca_prace5.zdenca_volba3.addEventListener(MouseEvent.CLICK,z3Click5);
function z3Click5(event:MouseEvent):void{
zdenca_prace5.visible = false;
zdenca5.play();
zdenca5ON = true;
setTimeout(timedFunction53,5000);
function timedFunction53() {
mcnf5--;
mcnt5++;
mcnft5.text = mcnf5.toString();
mcntt5.text = mcnt5.toString();
zdenca5ON = false;
zdenca5.stop();}
}
so the problem here is each time you call zdeClick5()... you are adding ANOTHER set of listeners to all of the sub objects (i.e... denca_prace5.zdenca_volba2.addEventListener()). These listeners are all pointing to inline handlers (i.e.... function timedFunction53()). So, when you add duplicate listeners, as3 will ignore it. BUT, these aren't duplicates because each time you add one... it is pointing to a brand new inline function.
to fix this I would set up the event listeners and handlers outside of your function zdeClick5() (so they don't get added over and over again, and so they can point to one concrete function pointer for each listener).

Objects on the stage are not read when jumping to their frame

I am working on an Air desktop application. At some point when the user presses a button, it will jump to a specific frame, the problem is after going to that frame some Movieclips on the stage at that frame are not read though they were read from the very beginning.
The following error occurs.
Error #1009: Cannot access a property or method of a null object
reference.
I do not know why he can not read what is already on the stage, I guess it is something related to the arrangement of the layers. I noticed that sometimes though I do not find it logical, It is supposed to read ALL that is in the same frame as long as it is stopped on it, right?
The project is as follows:
1) At the very beginning an intro is played and then it goes to the first frame of the course.
2) At first frame the user chooses one of 5 buttons to click, based on each one it goes to different frame.
3) When the user is at any frame it should return to the main frame if he clicked a back button, this button command is gotoAndStop(1) and some conditional removeChild() to clean the stage from any objects generated by code depending on the frame the function was called from.
4) The problem arises when this back button is clicked, one or more of the very first 5 buttons suddenly disappears and an error generated as - for some unknown reason - it can not be read by the program any more, it can not read any events for it and generates the above error.
My code is as follows:
var myLettersLoader:URLLoader= new URLLoader();
mainMenu.addEventListener(MouseEvent.CLICK,gotomainMenu);
letters.addEventListener(MouseEvent.CLICK,showLetters);
lessons.addEventListener(MouseEvent.CLICK,showLessons);
revision.addEventListener(MouseEvent.CLICK,showRevision);
myLettersLoader.load(new URLRequest("data/letters/letters.xml"));
myLettersLoader.addEventListener(Event.COMPLETE,loadXML);
function showLetters(e:MouseEvent)
{
//gotoAndStop(2)
//aaaaa.alpha=1;
//aaaaa.visible=true;
Tweener.addTween(e.currentTarget, {width:originalWidth,height:originalHeight, time:0.25, transition:"linear"});
myPlace.visible = true;
myPlace2.visible = false;
myPlace3.visible = false;
jewels.visible = false;
mainContainer.visible=false;
close.visible=false;
studentBook.visible = false;
mainButton = e.currentTarget.name;
Tweener.addTween(myPlace, {alpha:1, transition:"linear"});
lettersContainer.visible=true;
Tweener.addTween(letterContainerText, {alpha:1, transition:"linear"});
for (var i=1; i<29; i++)
{
var letter = "L" + i;
myPlace[letter].id = i;
myPlace[letter].alpha = 1;
myPlace[letter].addEventListener(MouseEvent.CLICK,gotoLetterFrame);
myPlace[letter].buttonMode = true;
}
}
function showLessons(e:MouseEvent)
{
Tweener.addTween(e.currentTarget, {width:originalWidth,height:originalHeight, time:0.25, transition:"linear"});
myPlace.visible= false;
myPlace2.visible = true;
myPlace3.visible = false;
jewels.visible = false;
mainContainer.visible=false;
close.visible=false;
studentBook.visible = false;
lettersContainer.visible=true;
mainButton = e.currentTarget.name;
Tweener.addTween(myPlace2, {alpha:1, transition:"linear"});
studentBook.alpha = 0;
for (var i=0; i<5; i++)
{
var lesson = "Lesson" + i;
myPlace2[lesson].id = i;
myPlace2[lesson].alpha = 1;
myPlace2[lesson].addEventListener(MouseEvent.CLICK,gotolessonFrame);
myPlace2[lesson].buttonMode = true;
}
}
//=======================Revision functions==================================
function showRevision(e:MouseEvent)
{
Tweener.addTween(e.currentTarget, {width:originalWidth,height:originalHeight, time:0.25, transition:"linear"});
myPlace.visible= false;
myPlace2.visible = false;
myPlace3.visible = true;
jewels.visible = false;
mainContainer.visible=false;
close.visible=false;
studentBook.visible = false;
lettersContainer.visible=true;
mainButton = e.currentTarget.name;
Tweener.addTween(myPlace3, {alpha:1, transition:"linear"});
studentBook.alpha = 0;
for (var i=0; i<7; i++)
{
var revision = "Revision" + i;
myPlace3[revision].id = i;
myPlace3[revision].alpha = 1;
myPlace3[revision].addEventListener(MouseEvent.CLICK,gotoRevisionFrame);
myPlace3[revision].buttonMode = true;
}
}
//========================================================
function gotoLetterFrame(e:MouseEvent)
{
reloadButton.visible=true;
mainMenu.visible=true;
myClose.visible=true;
reloadButton.visible=true;
myNext.visible=true;
currentTarget=(e.currentTarget.id-1);
currentName = arrOfLetters[currentTarget];
xmlListOfClass=new XMLList(myxml.letter.(#id==currentName).children());
gotoAndStop(xmlListOfClass[counter].localName());
abc.visible=abcd.visible=true;
mainMenu.buttonMode=true;
}
function gotolessonFrame(e:MouseEvent)
{
reloadButton.visible=true;
mainMenu.visible=true;
myClose.visible=true;
reloadButton.visible=true;
myNext.visible=true;
currentTarget=(e.currentTarget.id);
xmlListOfClass = new XMLList(lessonsArr[currentTarget].lesson.children());
gotoAndStop(xmlListOfClass[counter].localName());
abc.visible=abcd.visible=true;
mainMenu.buttonMode=true;
}
function gotoRevisionFrame(e:MouseEvent)
{
reloadButton.visible=true;
mainMenu.visible=true;
myClose.visible=true;
reloadButton.visible=true;
myNext.visible=true;
currentTarget=(e.currentTarget.id);
myRevisionLoader.load(new URLRequest("data/revisions/"+currentTarget+"/revision.xml"));
myRevisionLoader.addEventListener(Event.COMPLETE,loadRevisionXML);
}
//=====================================
function loadLessonXML(e:Event)
{
lessonsArr[xx] = new XML(e.target.data);
xx++;
}
//==============================For revision==================================
function loadRevisionXML(e:Event)
{
revisionArr = new XML(e.target.data);
xmlListOfClass = new XMLList(revisionArr.revision.children());
gotoAndStop(xmlListOfClass[counter].localName());
abc.visible=abcd.visible=true;
mainMenu.buttonMode=true;
}
function loadXML(e:Event)
{
myxml = new XML(e.target.data);
}
//====================================
function gotomainMenu(e:MouseEvent)
{
gotoAndPlay(1);
}
This code is in the first frame, and in the second frame the button mainButton
is the button responsible for going back to frame 1
The buttons lessons,letters,revision disappears when returning to frame 1, or one of them sometimes with no logical reason
I solved it.It was all about the arrangement of layers.
All what I did is that I put the layer which contains the 5 buttons under the other layers. This surprisingly solved the problem. I do not know the reason till this moment but all what I know is that for some reason the caller of some event must be under the other layers containing some other objects or at least at the same layer.

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

as3: Mute button and volume slider on one sound channel

I have truly exhausted all my knowledge on this problem so I hope that my peers will be able to help me?
I am building a audio mixer that has five tracks with a volume slider and mute button per track. The reason for a mute button as opposed to a start/stop button per track is so that all the samples will be in sync regardless of when a sample is introduced.
The app has global start, stop and pause buttons which all function normally but I cannot get the volume slider and mute button to work in tandem on an individual sound channel.
The volume slider and the mute button will both work if I comment out the other function but when both are in play then only the volume slider works.
I'm guessing that there is a conflict because I have two separate variables using the soundTransform object/class but maybe you can shed some light on this conundrum?
Here is my code for one track... Any help appricated.
var mySound1:Sound1 = new Sound1();
var myChannel1:SoundChannel = new SoundChannel();
var volumeAdjust1:SoundTransform = new SoundTransform();
volumeAdjust1.volume = 0;
mute_btn1.stop();
mute_btn1.addEventListener(MouseEvent.CLICK,togglemute_btn1);
var Mute1:Boolean = false;
function togglemute_btn1(event:MouseEvent)
{
if (Mute1)
{
mute_btn1.gotoAndStop(1);
volumeAdjust1.volume = 1;
myChannel1.soundTransform = volumeAdjust1;
Mute1 = false;
}
else
{
mute_btn1.gotoAndStop(2)
volumeAdjust1.volume = 0;
myChannel1.soundTransform = volumeAdjust1;
Mute1 = true;
}
}
/*if the section below is commented out then the mute_btn1 works fine
otherwise the volume slider functions are dominent*/
var dragging1:Boolean = false;
var mySliderLength1:uint = 300;
var boundingBox1:Rectangle = new Rectangle(0,0,0,mySliderLength1);
slider_mc1.knob_mc1.addEventListener(MouseEvent.MOUSE_DOWN, dragKnob1);
stage.addEventListener(MouseEvent.MOUSE_UP, releaseKnob1);
slider_mc1.knob_mc1.buttonMode = true;
function dragKnob1(myEvent:Event):void
{
slider_mc1.knob_mc1.startDrag(false, boundingBox1);
dragging1 = true;
slider_mc1.knob_mc1.addEventListener(Event.ENTER_FRAME, adjustVolume1);
}
function releaseKnob1(myEvent:Event):void
{
if (dragging1)
{
slider_mc1.knob_mc1.stopDrag();
dragging1 = false;
}
}
function adjustVolume1(myEvent:Event):void
{
var myVolume1:Number = slider_mc1.knob_mc1.y / mySliderLength1;
var myTransform1:SoundTransform = new SoundTransform(myVolume1);
if (myChannel1!=null)
{
myChannel1.soundTransform = myTransform1;
}
}
You should check your Mute1 variable in that listener of yours, and if muted, then volume=0, otherwise volume is calculated. And indeed, do remove your enter frame listener at the point of stopDrag() call.
function dragKnob1(myEvent:Event):void
{
slider_mc1.knob_mc1.startDrag(false, boundingBox1);
dragging1 = true;
slider_mc1.knob_mc1.addEventListener(Event.ENTER_FRAME, adjustVolume1);
}
function releaseKnob1(myEvent:Event):void
{
if (dragging1)
{
slider_mc1.knob_mc1.stopDrag();
dragging1 = false;
slider_mc1.knob_mc1.removeEventListener(Event.ENTER_FRAME, adjustVolume1);
// ^ this line added
}
}
function adjustVolume1(myEvent:Event):void
{
if (Mute1) return;
// ^ and this line added
var myVolume1:Number = slider_mc1.knob_mc1.y / mySliderLength1;
var myTransform1:SoundTransform = new SoundTransform(myVolume1);
if (myChannel1!=null)
{
myChannel1.soundTransform = myTransform1;
}
}
I believe your issue is you keep adding the Enter_Frame listener every time the mouse is clicked but it never gets removed. So even after you let go of the knob the adjustVolume1 function is still getting called (which messes up anything the mute function call is doing on the frame after the mute toggle function is called).
So how I think I would deal with this given the current state is move the Enter_Frame listener addition outside of the dragKnob function and in the adjustVolume1 handler just check if dragging1 is true otherwise just return.
slider_mc1.knob_mc1.addEventListener(Event.ENTER_FRAME, adjustVolume1);
function dragKnob1(myEvent:Event):void
{
...
}
function adjustVolume1(myEvent:Event):void
{
if(!dragging1)
return;
...
}

music playing over and over in Actionscript 3

Greeting,
I I developed a website using flash with Actionscript 3.
I included a music as a background for the website and the music will loaded when the site loaded.
but the problem that when I click buttons to move between pages(frames) then go and click button_01 the music will play again so I will have music playing more than one time in the background
and the sound_btn will not work any more so even I click sound_btn the music will not stop.
the code I'm using is listed down.
Please advice me what I should modify to not allow the music play more than one time in the background while moving from one page(frame) to another.
Regards,
stop();
//number that is redefined when the pause button is hit
var pausePoint:Number = 0.00;
//a true or false value that is used to check whether the sound is currently playing
var isPlaying:Boolean;
//think of the soundchannel as a speaker system and the sound as an mp3 player
var soundChannel:SoundChannel = new SoundChannel();
var sound:Sound = new Sound(new URLRequest("music.mp3"));
//you should set the xstop and xplay values to match the instance names of your stop button and play/pause buttons
//mute_btn.addEventListener(MouseEvent.CLICK, clickStop);
sound_btn.addEventListener(MouseEvent.CLICK, clickPlayPause);
soundChannel = sound.play();
isPlaying = true;
myVideo.stop();
function clickPlayPause(evt:MouseEvent) {
if (isPlaying) {
pausePoint = soundChannel.position;
soundChannel.stop();
isPlaying = false;
} else {
soundChannel = sound.play(pausePoint);
isPlaying = true;
}
}
button_01.addEventListener(MouseEvent.CLICK, onClick1);
button_02.addEventListener(MouseEvent.CLICK, onClick2);
button_03.addEventListener(MouseEvent.CLICK, onClick3);
button_04.addEventListener(MouseEvent.CLICK, onClick4);
button_05.addEventListener(MouseEvent.CLICK, onClick5);
button_06.addEventListener(MouseEvent.CLICK, onClick6);
function onClick1(e:MouseEvent):void
{
gotoAndStop(1);
}
function onClick2(event:MouseEvent):void
{
gotoAndStop(2);
}
function onClick3(event:MouseEvent):void
{
gotoAndStop(3);
}
function onClick4(event:MouseEvent):void
{
gotoAndStop(4);
}
function onClick5(event:MouseEvent):void
{
gotoAndStop(5);
}
function onClick6(event:MouseEvent):void
{
gotoAndStop(6);
}
The problem is your code for the sound is initialized on the frame that you send the timeline to when clicking button_01. It will reinitialize each time you do that. Try initializing your sound code one frame earlier so that you do not land on that frame ever again once your page loads.
You also might find that wrapping your pages into movieclips, and using visible = true/false to change sections might be a better approach than advancing the timeline to change sections. That method would not result in the sound code reinitializing each time you changed sections. something like this:
function onClick1(e:MouseEvent):void
{
hideAll();
section_01.visible = true;
}
function onClick2(event:MouseEvent):void
{
hideAll();
section_02.visible = true;
}
function onClick3(event:MouseEvent):void
{
hideAll();
section_03.visible = true;
}
function onClick4(event:MouseEvent):void
{
hideAll();
section_04.visible = true;
}
function onClick5(event:MouseEvent):void
{
hideAll();
section_05.visible = true;
}
function onClick6(event:MouseEvent):void
{
hideAll();
section_06.visible = true;
}
function hideAll():void
{
section_01.visible = false;
section_02.visible = false;
section_03.visible = false;
section_04.visible = false;
section_05.visible = false;
section_06.visible = false;
}
If you wanted tweened transitions you could use a tweening class to handle the transitions by tweening the current section out in the hide function and then tweening the next section in in its respective onCLick function.