How to measure the time of an event in flash? - actionscript-3

If there is some event on any button such as rollover event by mouse how to measure how much time that rollover event took place?

You could time the difference between MOUSE_OVER and MOUSE_OUT.
var myButton:Button = new Button();
var diff:Number = 0;
var startDate:Date;
myButton.addEventListener(MouseEvent.MOUSE_OVER, function(evt:MouseEvent):void {
startDate = new Date();
});
myButton.addEventListener(MouseEvent.MOUSE_OUT, function(evt:MouseEvent):void {
diff = (new Date()).time - startDate.time;
if (diff >= 5000)
// do something
});
I do not have Flash Builder up but this should be a good start. Check out these docs for more info:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/events/MouseEvent.html
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Date.html#time

Well, only one rollover is fired unless yuo roll out and then back on.
So here's what I would do:
private var timeoutId:uint=-1;
private function onRollover(e:MouseEvent):void {
timeoutId=setTimeout(play, 5000);
}
private function onRollout(e:MouseEvent):void {
if(timeoutId != -1) clearTimeout(timeoutId);
}
private function play():void {
//code to play music
}
and of course, onRollover and onRollout handle the respective events.

Maybe you should take a look at the Timer class. Here's a simple example of what you can do with it:
var timer:Timer = new Timer(5000,1);
timer.addEventListener(TimerEvent.TIMER, playVideo);
btnInstance.addEventListener(MouseEvent.MOUSE_OVER,
function(evt:MouseEvent):void {
timer.start();
});
btnInstance.addEventListener(MouseEvent.MOUSE_OUT,
function(evt:MouseEvent):void {
timer.stop();
});
function playVideo(evt:TimerEvent):void {
// play video
}
Hope it helps.

Related

AS3 running an event for a set duration after button (or anything) event

For the purposes of the question, Imagine I have an object onstage. When I click on another button, I want the colour to change for 1 second, then revert back again when finished.
Here's what my demo code looks like:
Button.addEventListener(MouseEvent.CLICK, Colour_Change);
function Colour_Change(evt: MouseEvent): void {
var my_color: ColorTransform = new ColorTransform();
my_color.color = 0xFF0000;
Coloured_Object.transform.colorTransform = my_color;
}
What I am wanting is some sort of timer function to be incorporated in the above function. I haven't got any idea how to do it, hence why there's no implementation.
You should use the flash.utils.Timer class.Adobe ActionScript 3.0 Reference for the Timer class
The following should be enough to get you headed in the right direction:
import flash.utils.Timer;
var myTimer:Timer = new Timer(1000, 1); // 1 second
var running:Boolean = false;
Button.addEventListener(MouseEvent.CLICK, Colour_Change);
myTimer.addEventListener(TimerEvent.TIMER, runOnce);
function Colour_Change(evt: MouseEvent): void {
var my_color: ColorTransform = new ColorTransform();
my_color.color = 0xFF0000;
Coloured_Object.transform.colorTransform = my_color;
if(!running) {
myTimer.start();
running = true;
}
}
function runOnce(event:TimerEvent):void {
// code to revert the button's color back goes here
myTimer.reset();
running = false;
}
Let me know if you need more help or if this example has errors via this answer's comments section.
To further explain the Timer class as used above:
when creating a new timer
myTimer=new Timer(1000,1)
the first number in the brackets is the number of milliseconds you want the timer to run for (e.g. 1000 = 1 second)
The second number is how many times you want the timer to repeat (or 0 for infinite repetition).
Every time the timer reaches the time you entered (1000), this is will trigger any event listeners for the event Timer_Event.TIMER, so for example if u wanted to make it change color on and off, you could have multiple repetitions on the timer and change the function.
Other useful things timers can do:
You can add an event listener for
Timer_Event.TIMER_COMPLETE
(goes off when all repetitions are complete)
myTimer.currentCount
will return the number of repetitions the timer has done so far.
To do that you can use, as other answers said, a Timer object or the setTimeout() function, like this :
// the current color of our target object
var default_color:ColorTransform;
// the delay in milliseconds
var delay:int = 1000;
btn.addEventListener(MouseEvent.CLICK, Colour_Change);
function Colour_Change(evt: MouseEvent): void {
// save the current color of our target object
default_color = target.transform.colorTransform;
var new_color:ColorTransform = new ColorTransform();
new_color.color = 0xFF0000;
target.transform.colorTransform = new_color;
var timer:Timer = new Timer(delay, 1);
timer.addEventListener(TimerEvent.TIMER, function(e:TimerEvent):void {
// after the delay, we use the default color of our target
target.transform.colorTransform = default_color;
})
timer.start();
// using setTimeout(), you have to disable this if using the Timer
var timeout:int = setTimeout(
function(){
clearTimeout(timeout);
// after the delay, we use the default color of our target
target.transform.colorTransform = default_color;
},
delay
);
}
Hope that can help.

actionScript3 ENTER_FRAME Event is not working

I am trying to to use the ENTER_FRAME Event on playing audio ,but the code is not executing the handler function.
public function play_mp3(path:String,path1:String):void {
var snd:Sound = new Sound();
snd.load(new URLRequest(path), new SoundLoaderContext());
channel = snd.play();
addEventListener(Event.ENTER_FRAME,myFunction);}
public function myFunction(e:Event){
LogFB.info('test1234'); }
You're issue is likely that the class whose code you've posted, is not on the display tree. (it's not a display object or hasn't been added to the stage).
If it's not on the display tree, then ENTER_FRAME will not dispatch on it.
You can get around this a few ways.
Pass into the class a reference to something that is on the stage (or the stage itself). Then add the ENTER_FRAME listener on that object.
var stage:Stage;
public function MyClass(stage_:Stage){
stage = stage_;
}
....
stage.addEventListener(Event.ENTER_FRAME, myFunction);
Forgo ENTER_FRAME, and just use a Timer
var timer:Timer
public function play_mp3(path:String,path1:String):void {
var snd:Sound = new Sound();
snd.load(new URLRequest(path), new SoundLoaderContext());
channel = snd.play();
timer = new Timer(250); //tick every quarter second
timer.addEventListener(TimerEvent.TIMER, myFunction);
timer.start();
}
public function myFunction(e:Event){
LogFB.info('test1234');
}
Your problem is in LogFB.
Try this and you will see the trace from inside the function...
var channel : SoundChannel = new SoundChannel();
function play_mp3(path:String,path1:String):void {
var snd:Sound = new Sound();
snd.load(new URLRequest(path), new SoundLoaderContext());
channel = snd.play();
addEventListener(Event.ENTER_FRAME,myFunction);
}
function myFunction(e:Event){
//LogFB.info('test1234'); here is the problem
// trace("is working!");
hi();
}
play_mp3('aasa','aaa');
function hi() {
trace("goooooddddd!"); //is working, I am using Flash CC
}
All the best!
there doesnt seem any error try this one
public function play_mp3(path:String,path1:String):void {
addEventListener(Event.ENTER_FRAME,myFunction);
var snd:Sound = new Sound();
snd.load(new URLRequest(path), new SoundLoaderContext());
channel = snd.play();
}
public function myFunction(e:Event){
LogFB.info('test1234'); }
ie put the enterframe event the first thing that hapen in your code to check if at least it initialise it?

How to get a percentage from new Date();

I have a digital clock for now, and I need the corn to know when 10 seconds as passed, this way it can go to the next frame. Im having difficulty finding out how to gather the 10 secs and make it out of 100% for example
its 9:30:21 and i pushed the button
at 9:30:31 it should be done
but I want to create a percentage bar based on that 10sec.. heres my code
farmSlot1.addEventListener(MouseEvent.CLICK, farmClick1);
var startTime: Date = new Date();
var startSec: Number = startTime.seconds;
function farmClick1(e: MouseEvent): void {
addChild(menu);
menu.x = 400;
menu.y = 90;
menu.buyCornBtn.addEventListener(MouseEvent.CLICK, buyCorn1);
}
function buyCorn1(e: MouseEvent): void {
var startTime: Date = new Date();
startSec = startTime.seconds;
menu.buyCornBtn.addEventListener(Event.ENTER_FRAME, cornloading1);
farmSlot1.progressB.visible = true;
menu.buyCornBtn.removeEventListener(MouseEvent.CLICK, buyCorn1);
removeChild(menu);
}
function cornloading1(event: Event): void {
var now: Date = new Date();
var hr: Number = now.hours;
var min: Number = now.minutes;
var sec: Number = now.seconds;
var finished: Number = startSec + 5
var percent = Math.round((finished-sec) * 100)
if(sec < finished){
farmSlot1.loader_txt.text = percent
Object(root).farmSlot1.progressB.bar.scaleX = percent;
trace("hit");
}else if (sec == finished && farmSlot1.currentLabel != "corn") {
removeEventListener(Event.ENTER_FRAME, cornloading1);
trace("It did it");
farmSlot1.loader_txt.text = ""
farmSlot1.gotoAndStop("corn");
}
}
At first, as I see you are writing the code inside Flash frames. Incapsulating your code within classes is better approach which allows to avoid tons of problems in the future. Here is a link described some basic approaches for using classes:
http://www.kirupa.com/developer/as3/classes_as3_pg1.htm
In answer to your question:
You can simply use flash.utils.Timer class instead of using Date and ENTER_FRAME event: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/Timer.html
Some piece of code:
//Import timer class
import flash.utils.Timer;
...
//In the class's body
//Create a timer instance. Timer will be executed 10 times every 100 milliseconds
private var timer:Timer = new Timer(100, 10);
...
//Somewhere in class's method (usually in the constructor)
timer.addEventListener(TimerEvent.TIMER, timerHandler);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, timerCompleteHandler);
//Add click handler
button.addEventListener(MouseEvent.CLICK, buttonClickHandler);
...
private function buttonClickHandler(event:MouseEvent):void
{
//Do some stuff and start timer.
timer.start();
}
private function timerHandler(event:TimerEvent):void
{
//Update progress indicator
}
private function timerCompleteHandler(event:TimerEvent):void
{
//1 second is over so do some stuff.
}

How to get this code to show movieclip correctly?

I have the following code and it works fine, except I want it to play the Explosion movieclip in the library when an EnemyShip disappears but I only want it to play once and then disappear but not quite sure how to do it (I've tried a few things and it either makes the explosion animation loop and the ships don't disappear, which I believe is as a result of putting it inside the kill function, or I get other ArgumentErrors).
var speed:Number;
var shot = new ShotSound();
var explosion = new Explosion();
this.x = 800;
this.y = Math.random() * 275 + 75;
speed = Math.random()*5 + 9;
addEventListener("enterFrame", enterFrame);
addEventListener(MouseEvent.MOUSE_DOWN, mouseShoot);
function enterFrame(e:Event)
{
this.x -= speed;
if(this.x < -100)
{
removeEventListener("enterFrame", enterFrame);
stage.removeChild(this);
}
}
function kill()
{
stage.addChild(this);
explosion.x = this.x;
explosion.y = this.y;
removeEventListener("enterFrame", enterFrame);
stage.removeChild(this);
shot.play();
}
function mouseShoot(event:MouseEvent)
{
kill();
}
Thank for for any help I may receive.
You need some script to fire when the Explosion reaches it's final frame. A few ways you can do this:
1.
Dispatch an event on the last frame of your explosion animation. eg. this.dispatchEvent(new Event(Event.COMPLETE)); then listen for that event:
var explosion = new Explosion();
addChild(explosion);
explosion.addEventListener(Event.COMPLETE, removeExplosion);
function removeExplosion(e:Event):void {
MovieClip(e.currentTarget).stop();
MovieClip(e.currentTarget).removeEventListener(Event.COMPLETE, removeExplosion);
removeChild(MovieClip(e.currentTarget));
}
2.
Have the explosion remove itself on the last frame of the animation. eg. if(this.parent) parent.removeChild(this);
3.
If you can't or don't want to modify the explosion timeline, use the undocumented AddFrameScript command:
var explosion = new Explosion();
addChild(explosion);
explosion.addFrameScript(explosion.totalFrames-1, function():void {
explosion.stop();
if(explosion.parent){
explosion.parent.removeChild(explosion);
}
});
Here is a tip with your setup:
add a function called removeMe (or similiar) to avoid redundant code (so you call this function on kill or when the ship goes out of bounds
function removeMe(e:Event = null):void {
this.removeEventLIstener(Event.ENTER_FRAME,enterFrame);
if(this.parent){
this.parent.removeChild(this);
}
//any other cleanup that's required
}
Next, an updated kill function:
function kill(){
var explosion = new Explosion();
explosion.addEventListener(Event.COMPLETE, removeMe); //you need to dispatch this event on the last frame of the explosion timeline as shown below
addChild(explosion); //add it to the ship so it stays with it as the ship moves
//not sure what shot.play() does and if that belongs here.
}
//on the last frame of your explosion timeline:
stop();
dispatchEvent(new Event(Event.COMPLETE));
For starters, you're never adding explosion to the display list.
Change
var explosion = new Explosion();
stage.addChild(this);
to
var explosion = new Explosion();
stage.addChild(explosion);
Once you've done that, you'll want to add a listener to explosion to find out when it has finished playing:
explosion.addEventListener(Event.ENTER_FRAME, onExplosionProgress);
function onExplosionProgress(e:Event):void
{
if(explosion.currentFrame == explosion.totalFrames)
{
// explosion has reached end of its timeline
explosion.removeEventListener(Event.ENTER_FRAME, onExplosionProgress);
explosion.stop();
stage.removeChild(explosion);
}
}

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