i really need some AS3 Script for run some function when i leave a specfic frame.
my reason is to put some function to stop video and resume my sound of mp3 player AFTER i exit the frame that contain FLV playback .
i use this script and it`s work great in FLash projector but stage.invalidate(); cause the Third party application maker like Swfkit and Zinc Not responding after i try to exit from flv playback frame.
Here is my Script :
stage.invalidate();
mene.addEventListener(Event.RENDER,exitingF);
mene.addEventListener(Event.REMOVED_FROM_STAGE, removedF);
function exitingF(e:Event):void{
controller.gotoAndStop(2);
pausePosition = sndChannel.position;
sndChannel.stop();
isPlaying = false;
}
function removedF(e:Event):void{
mene.stop();
controller.gotoAndStop(1);
sndChannel = soundClip.play(pausePosition);
isPlaying = true;
}
all i need is some another way to say flash run some script right after exit specfic frame ( go to another frame )
Try using the addFrameScript() function.
It works like so: OBJECT.addFrameScript(FRAME, CALLBACK)
This will add a script to a timeline and the callback will be executed whenever the specified frame is reached.
Here's an example I found: http://blog.newmovieclip.com/2007/04/30/add-a-frame-script-addframescript-dynamically-in-flash-cs3/
package com.newmovieclip{
import flash.display.MovieClip;
public class Main extends MovieClip {
public var myStar:Star;
//constructor
public function Main() {
//place a star on stage
myStar = new Star();
addChild(myStar);
//add script to star timeline on frame 5
myStar.addFrameScript(4,frameFunction); // (zero based)
}
private function frameFunction():void {
trace("Executing code for star Frame 5" );
//delete frame script by passing null as second parameter
myStar.addFrameScript(4,null);
}
}
}
Remember that frames are 0 based as mentioned in the inline comment from the example
Related
The js code generated in the files output in Adobe Animation for HTML5 Canvas contains an object for the movie clip that include the code that is to be run in each frame.
(lib.cdseacc02_07 = function(mode,startPosition,loop) {
// timeline functions:
this.frame_0 = function() {
if(typeof showNarration !== "undefined"){ showNarration(1); }
}
this.frame_644 = function() {
playSound("02_07_01wav");
}
this.frame_652 = function() {
this.closeBtn_1.addEventListener("click", closepopup_1.bind(this));
}
this.frame_738 = function() {
this.stop();
}
}).prototype = p = new cjs.MovieClip();
If gotoAndPlay is called on the movieclip from this code the code on the frame function is not run on the frames as they are passing by, this frame code only works the first time the timeline is played. Is there any way to make it so that the code on the frames can run each time the playhead passes that frame even if it was through a gotoAndPlay call in the code?
Frame actions should absolutely be played each time the timeline passes that frame, whether during gotoAndPlay or gotoAndStop. In fact, this sometimes causes issues where things event listeners are added multiple times (each time the framehead passes the script, like on your frame 652).
Can you post a simplified example of this not working?
I have make a menu in Flash that can expand and there music setting inside.
The music plays when the application starts. To stop the music you must expand the menu and click the music icon.
It's working fine after I open the program and stop the music.
And it's working if I want to play again.
But there's problems after that:
I can't stop the music again and the music playing double in background.
This is my FLA file:
https://drive.google.com/file/d/1DpqdH64kDnI8xN6fBAt3pwi_bIRQ52mT/view?usp=drivesdk
Can anyone tell me the fault of my program? Thanks.
About "music playing double" does your (audio) playback function create a new anything? (eg: = new Sound or = new SoundChannel)? If yes...
Create your audio variables once outside of functions, then use your functions only to stop/start audio playback.
Use new Sound only when loading a new track, once loaded then use one SoundChannel to play/stop that Sound object.
You need a Boolean to keep track of whether a Sound is already playing or not. If true then don't send another .play() command (now gives two sounds to output/speakers).
See if the code logic below guides you toward a better setup:
//# declare variables globally (not trapped inside some function)
var snd_Obj :Sound;
var snd_Chann :SoundChannel = new SoundChannel();
var snd_isPlaying :Boolean = false;
//# main app code
loadTrack("someSong.mp3"); //run a function, using "filename" as input parameter
//# supporting functions
function loadTrack (input_filename :String) : void
{
snd_Obj = new Sound();
snd_Obj.addEventListener(Event.COMPLETE, finished_LoadTrack);
snd_Obj.load( input_filename ); //read from function's input parameter
}
function finished_LoadTrack (event:Event) : void
{
snd_Chann = snd_Obj.play(); //# Play returned Speech convert result
snd_Obj.removeEventListener(Event.COMPLETE, onSoundLoaded);
//# now make your Play and Stop buttons active
btn_play.addEventListener(MouseEvent.CLICK, play_Track);
btn_stop.addEventListener(MouseEvent.CLICK, stop_Track);
}
function play_Track (event:Event) : void
{
//# responds to click of Play button
if(snd_isPlaying != true) //# check if NOT TRUE, only then start playback
{
snd_Chann = snd_Obj.play();
snd_isPlaying = true; //# now set TRUE to avoid multiple "Play" commands at once
}
}
function stop_Track (event:Event) : void
{
//# responds to click of Play button
snd_Chann.stop();
snd_isPlaying = false; //# now set FALSE to reset for next Play check
}
New to AS 3.0 and I seem to have an issue where an external AS file is run when I test an individual scene in Flash Pro but not when I test the entire movie or when I test from Flash Builder. Anyone know what the problem might be?
Here's the code from the AS file:
package {
import flash.display.MovieClip;
public class Level1 extends MovieClip {
public var myplayer:MyPlayer;
public function Level1() {
super();
myplayer.x = 516;
myplayer.y = 371;
if (myplayer.x == 516)
{
trace("player x is 516");
}
else if (myplayer.y == 371)
{
trace("player y is 371");
}
}
}
}
Any ideas?
EDIT
I think I figured out the problem. The swf contained two scenes, and the external AS file started running at the start of Scene 1, but the myPlayer movie clip was not instantiated until Scene2, which, I think was causing the problem I was having, in addition to giving a 1009 null object error.
So I simply deleted the first scene, and now everything works fine. Maybe I will put that first scene in a separate SWF? Or, is there some way to delay a script's execution until a certain scene?
Your problem:
When the constructor of your doucment class runs, myPlayer doesn't yet exist so it throws a 1009 runtime error and exits the constructor at the first reference to myPlayer.
Solutions:
Put all the myPlayer code on the first frame of the MyPlayer timeline. OR use your current document class as the class file for MyPlayer (instead of documentClass). Change all references to myPlayer to this.
Listen for frame changes and check until myPlayer is populated, then run your code.
this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
function enterFrameHandler(e):void {
if(myPlayer){
//run the myPlayer code
this.removeEventListener(Event.ENTER_FRAME,enterFrameHandler);
}
}
If your frame rate is 24fps, this code though will run 24 times every second (until it finds myPlayer), so it's not the most performant way to go.
Use events. Add an event to the first frame of myPlayer (or to a class file for MyPLayer) that tells the document class that it exists now.
stage.dispatchEvent(new Event("myPlayerReady"));
Then listen for that event on the document class:
stage.addEventListener("myPlayerReady",playerReadyHandler);
playerReadyHandler(e:Event):void {
//your player code
var myPlayer = MyPlayer(e.target); //you can even get the reference from the event object
}
Thanks for your constructive, helpful responses, LDMS. I thought I had found a solution when I hadn't. Your advice worked. What I did was add the following code to the timeline of MyPlayer
this.x = 516;
this.y = 371;
if (this.x == 516)
{
trace("player x is 516");
}
if (this.y == 371)
{
trace("player y is 371");
}
and I removed the code from the document class. Everything seems to be working fine now. Thanks again for your help!
Hi im trying to use the FLVPlayback function in a emagazine flippage
and i can get the FLV to play if i remove all the code from the flash file then its starts and plays .
but i need it to be controlled by the code that i posted under here
When the magazine loads i need the flash movie to stop or pause when the viewer gets to the page where this film is located its sends a signal startAnimation4 and it should start playing the flash movie including the FLVPlayback , if the viewr flips to next page there is a event called onpageLeave that send the signal stopAnimation4 and the flash film and FLVPlayback should pause or stop.
Is there some one that have a idea of how i can do this ?
//Prevent automatic playback
stop();
FLVPlayback.pause();
//Import eMagStudio AS3 API
//import SWFHolderAPI.*;
//Initiate the EMSMediator class
EMSMediator.instance.init(this, eMagListener);
//Set variable that controls playing when the clip is called using playonce
if(playedOnce == undefined){
var playedOnce:Boolean = false;
}
//Callback function for events in the eMag. Responds to the broadcasts startAnimation and stopAnimation
function eMagListener(event:MessageEvent):void{
//Broadcast coming from eMagStudio
var eMagBrdcast:String = String(event.message);
if(eMagBrdcast == "startAnimation4"){
setTimeout(myFunction, 800);
function myFunction() {
play();
}
}else if(eMagBrdcast == "startAnimationOnce4"){
if(!playedOnce){
playedOnce = true;
play();
}
}
if(eMagBrdcast == "stopAnimation4"){
stop();
}else if(eMagBrdcast == "stopAnimationOnce4"){
if(!playedOnce){
playedOnce = true;
stop();
}
}
}
I think that your best approach here would be to create a custom event class for the page flipping events if possible. That way you can pass the video player object through the custom event class when the pageflip events are triggered so that you can instruct them what to do (i.e. play, stop, etc.) So basically, if you do have control of the dispatching of the page flip events, you would create the event object, assign the movie player component instance to a variable in the event object you instantiated, and then dispatch the event with the event object you just created.
Also, if memory serves me right, isn't FLVPlayback the name of the component used to provide FLV Player Controls? Are you using that same name as the instance name of your video players that you have added to the stage? If so, I would not do that and instead rename them to something else.
I have a swf file loaded into a main movie. When the child is finished playing, ie reaches its final frame, I would like the swf to unload. Can anyone tell me what bits I can add to this code?
//start button
start_button_aboriginal.addEventListener(MouseEvent.CLICK, fl_ClickToLoadUnloadSWF_3,false,0,true);
import fl.display.ProLoader;
var fl_ProLoader_3:ProLoader;
var fl_ToLoad_3:Boolean = true;
function fl_ClickToLoadUnloadSWF_3(event:MouseEvent):void
{
//ADDED APR02 START
fl_ProLoader_3.contentLoaderInfo.addEventListener(Event.INIT, childInitHandler);
fl_ProLoader_3.load(new URLRequest("myths/myth_aboriginal.swf"));
//ADDED APR02 END
if(fl_ToLoad_3)
{
fl_ProLoader_3 = new ProLoader();
fl_ProLoader_3.load(new URLRequest("myths/myth_aboriginal.swf"));
addChild(fl_ProLoader_3);
fl_ProLoader_3.x = 114;
fl_ProLoader_3.y = 41;
}
else
{
removeChild(fl_ProLoader_3);
fl_ProLoader_3.unloadAndStop();
fl_ProLoader_3 = null;
}
// Toggle whether you want to load or unload the SWF
fl_ToLoad_3 = !fl_ToLoad_3;
}
You could
1) Use the undocumented addFrameScript function defined in the MovieClip class to place a callback on the last frame of the child SWF. Useful if you don't have control over the code in your loaded SWF.
addFrameScript() has the following signature:
addFrameScript(frameNumber, callback); //frameNumber is zero-based (unlike in the Flash authoring suite, here you would enter 0 to refer to the first frame, and 1 for the second.)
In the parent SWF, add the following:
function fl_ClickToLoadUnloadSWF_3(event:MouseEvent):void {
...
fl_ProLoader_3.contentLoaderInfo.addEventListener(Event.INIT, childInitHandler);
fl_ProLoader_3.load(new URLRequest("myths/myth_aboriginal.swf"));
...
}
function childInitHandler(event:Event):void {
MovieClip(fl_ProLoader_3.content).addFrameScript(MovieClip(fl_ProLoader_3.content).totalFrames-1, unloadChild);
}
function unloadChild() {
fl_ProLoader_3.unloadAndStop();
}
If you're worried about addFrameScript going away - don't be. When you put code on the timeline, all that code is actually compiled into functions in the document class, with frame listeners added via addFrameScript.
Remember to define function unloadChild().
function unloadChild():void {
fl_ProLoader_3.unloadAndStop();
}
-OR-
2) Dispatch an event from your loaded SWF when it reaches the final frame.
In last frame of child SWF:
this.dispatchEvent(new Event("lastFrameReached"));
In parent SWF, add the following:
fl_ProLoader_3.content.addEventListener("lastFrameReached", unloadChild);
-OR-
3) Subscribe to the ENTER_FRAME event of the child and check if the child is on its last frame.
In parent SWF, add the following:
fl_ProLoader_3.content.addEventListener(Event.ENTER_FRAME, checkIfEnded);
function checkIfEnded(event:Event):void {
if (fl_ProLoader_3.content.currentFrame == fl_ProLoader_3.content.totalFrames) {
unloadChild();
}
}
I personally prefer addFrameScript - seems to me a cleaner solution. Callback runs once, you don't have to poll and you don't need to modify the child SWF.
There are a number of ways to solve this, and it has been asked many times...
Unload child swf on last frame of child swf
When External SWF has reached Frame X, how do I unload it?
That said, one way you could resolve this without creating event listeners on the child swf, is by periodically checking the child swf for the current frame. If it's the last one on the swf, call the unload method.
// once every second, indefinitely.
var tick:Timer = new Timer(1000, 0);
tick.addEventListener(TimerEvent.TIMER, checkSWF);
tick.start();
//Load something to the stage.
var loader:Loader = new Loader();
loader.load(new URLRequest("child.swf"));
addChild(loader);
function checkSWF(e:Event):void {
if (loader.content.currentFrame == loader.content.totalFrames) {
tick.stop(); // stop the timer
loader.unloadAndStop();
}
}