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?
Related
I found this code on the net, and it's almost perfect for my needs - but I need it to continuously loop the clip.
var so: Sound= new Sound();
var audioChannel: SoundChannel= new SoundChannel();
var audioTransform: SoundTransform = new SoundTransform();
var video:Video=new Video(320,240);
var nc:NetConnection=new NetConnection ;
nc.connect(null);
var ns:NetStream=new NetStream(nc);
var meta: Object = new Object();
meta.onMetaData = function(meta:Object){
trace(meta.duration);
};
ns.client=meta;
addChild(video);
video.attachNetStream(ns);
ns.play("vid.flv");
//clip is a transparent clip (alpha=0) for the entire scene
clip.addEventListener(MouseEvent.MOUSE_OVER,mute);
clip.addEventListener(MouseEvent.MOUSE_OUT,unmute);
function mute(e:MouseEvent) {
ns.soundTransform=audioTransform;
audioTransform.volume=0;
}
function unmute(e:MouseEvent) {
ns.soundTransform=audioTransform;
audioTransform.volume=1;
}
To loop a video stream in AS3:
Listen for the streams NET_STATUS event.
//ns is a netstream object
ns.addEventListener(NetStatusEvent.NET_STATUS, streamStatus);
In your streamStatus event handler, check if the status code is the video stop event:
function streamStatus(status:NetStatusEvent) {
if (status.info.code == "NetStream.Play.Stop") {
//the video has stopped
}
}
To loop the video, just seek to the beginning.
ns.seek(0);
So this is the final code:
ns.addEventListener(NetStatusEvent.NET_STATUS, streamStatus);
ns.play("vid.flv");
function streamStatus(status:NetStatusEvent) {
if (status.info.code == "NetStream.Play.Stop") {
ns.seek(0);
}
}
To see whatever status codes you can check for, see the documentation.
I am a student who's working for months on a game and now I've got stuck on a problem.
I am new to actionscript 3 but i learn fast.
I can load my menu screen ("startScreen.swf") into my game (firstgame) automatically and everything works fine when I click play or storyScreen or instructionsScreen. But the problem is that I want to return after pressing ESC button. I have tried many code but nothing works exactly how I want.
Example: I click on story and the swf (storyScreen.swf) loads and I can read the story and when I am finished, I want to press ESC to reload my swf (startScreen.swf) and all the functions in it. Like play and instructions.
You can find my code and empty space in the function (esc).
I know it is maybe easy to solve but I really don't know how. :(
public class FirstGame extends MovieClip
{
public var Player:MovieClip
private var leftKeyIsDown:Boolean;
private var RightKeyIsDown:Boolean;
private var aMissileArray:Array;
private var aEnemyArray:Array;
public var scoreTxt:TextField;
public var ammoTxt:TextField;
public var MenuEnd:EndGameScreen;
public var menuAgain:EndGameScreen;
private var MenuStart:mcStartGameScreen;
private var MenuStory:mcStartGameScreen;
private var MenuInstructions:mcStartGameScreen;
private var nScore:Number;
private var nAmmo:Number;
private var tEnemyTimer:Timer;
public function FirstGame()
{
//Create a loader object
var startLoader:Loader = new Loader();
//add event listener to listen for the complete event
startLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, startLoaded);
//load our loader object
startLoader.load(new URLRequest("startScreen.swf"));
}
public function startLoaded(e:Event):void
{
MenuEnd.hideScreen();
Player.visible = false;
scoreTxt.visible = false;
ammoTxt.visible = false;
//get a reference to the loaded movieclip
MenuStart = e.target.content as mcStartGameScreen;
//listen for start game event
MenuStart.addEventListener("START_GAME", playGameAgain);
//add it to the stage
addChild(MenuStart);
//get a reference to the loaded movieclip
MenuStory = e.target.content as mcStartGameScreen;
//listen for start game event
MenuStory.addEventListener("SHOW_STORY", storyGameScreen);
//add it to the stage
addChild(MenuStory);
//get a reference to the loaded movieclip
MenuInstructions = e.target.content as mcStartGameScreen;
//listen for start game event
MenuInstructions.addEventListener("SHOW_INSTRUCTIONS", instructionsGameScreen);
//add it to the stage
addChild(MenuInstructions);
}
private function instructionsGameScreen(e:Event):void
{
var instructionsLoader:Loader = new Loader();
var url:URLRequest = new URLRequest("instructionsScreen.swf");
instructionsLoader.load(url);
addChild(instructionsLoader);
stage.addEventListener(KeyboardEvent.KEY_UP, esc);
}
private function storyGameScreen(e:Event):void
{
var storyLoader:Loader = new Loader();
var url:URLRequest = new URLRequest("storyScreen.swf");
storyLoader.load(url);
addChild(storyLoader);
stage.addEventListener(KeyboardEvent.KEY_UP, esc);
}
private function esc(e:KeyboardEvent):void
{
if (e.keyCode == 27)
{
//fscommand("quit");
/////////test//////////////////(new URLRequest(stage.loaderInfo.url), "FirstGame.swf");
}
}
private function playGameAgain(e:Event):void
{
//initialize variables
aMissileArray = new Array();
aEnemyArray = new Array();
nScore = 0;
nAmmo = 20;
Player.x = 262,95
Player.y = 323,30
Player.visible = true;
scoreTxt.visible = true;
ammoTxt.visible = true;
MenuStart.hideScreen();
MenuEnd.addEventListener("PLAY_AGAIN", playGameAgain);
MenuEnd.hideScreen();
updateScoreText();
updateAmmoText();
//trace("First Game Loaded");
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUp);
stage.addEventListener(Event.ENTER_FRAME, gameLoop)
//creat an timer object
tEnemyTimer = new Timer(1000)
//listen for the timer ticks/intervals
tEnemyTimer.addEventListener(TimerEvent.TIMER, addEnemy)
//start our timer
tEnemyTimer.start();
}
I believe you should be able to start a new request on the same loader object. Either way, you're dealing with object creation + cleanup. The crux of the solution I'm offering is that you reuse your loaders.
Your current code is somewhat repetitious, so I've modified it slightly to demonstrate how you could simplify the code. Some thoughts while reviewing your code:
You're adding the same object to the stage multiple times (ie.,
MenuStart, MenuStory, MenuInstructions); these are all pointers to
the same root swf you loaded (a.k.a., startLoader).
You've registered events the stage at multiple locations. Best
practice is to place these in your constructor as they are
persistent.
Because you want to reuse your loaders at a later point, keeping a
table with them makes it easier to reference.
Any time you find yourself programming the same code in similar ways,
it's a good indication that you can simplify with a single function
(simply change the arguments).
Give this a try:
public var Player:MovieClip
private var leftKeyIsDown:Boolean;
private var RightKeyIsDown:Boolean;
private var aMissileArray:Array;
private var aEnemyArray:Array;
public var scoreTxt:TextField;
public var ammoTxt:TextField;
public var MenuEnd:EndGameScreen;
public var menuAgain:EndGameScreen;
private var MenuStart:mcStartGameScreen;
private var MenuStory:mcStartGameScreen;
private var MenuInstructions:mcStartGameScreen;
private var nScore:Number;
private var nAmmo:Number;
private var tEnemyTimer:Timer;
private var screens:Object = {
"SHOW_INSTRUCTIONS":{
"loader":new Loader(),
"url":new URLRequest("instructionsScreen.swf")
},
"SHOW_STORY":{
"loader":new Loader(),
"url":new URLRequest("storyScreen.swf")
},
"START_GAME":{
"loader":new Loader(),
"url":new URLRequest("startScreen.swf")
}
}
public function FirstGame() {
var startLoader:Loader = loadScreen({"type":"START_GAME"});
//Register our event listeners
startLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, startLoaded);
stage.addEventListener(KeyboardEvent.KEY_UP, esc);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
stage.addEventListener(Event.ENTER_FRAME, gameLoop)
}
private function loadScreen(e:Object):Loader {
screens[e.type].loader.load(screens[e.type].url);
addChild(screens[e.type].loader);
return screens[e.type].loader;
}
public function startLoaded(e:Event):void {
//initialize variables
aMissileArray = new Array();
aEnemyArray = new Array();
nScore = 0;
nAmmo = 20;
Player.x = 262, 95
Player.y = 323, 30
Player.visible = true;
scoreTxt.visible = true;
ammoTxt.visible = true;
MenuEnd.addEventListener("PLAY_AGAIN", playGameAgain);
MenuEnd.hideScreen();
updateScoreText();
updateAmmoText();
//creat an timer object
tEnemyTimer = new Timer(1000)
tEnemyTimer.addEventListener(TimerEvent.TIMER, addEnemy)
tEnemyTimer.start();
var swfRoot = screens.START_GAME.loader["content"];
swfRoot.addEventListener("START_GAME", loadScreen);
swfRoot.addEventListener("SHOW_STORY", loadScreen);
swfRoot.addEventListener("SHOW_INSTRUCTIONS", loadScreen);
}
private function esc(e:KeyboardEvent):void {
if (e.keyCode == 27) {
//fscommand("quit");
// Loop through our loaders, and reset them all.
for each (var entry:Object in screens) {
entry.loader.unloadAndStop();
removeChild(entry.loader);
}
// Reload the start screen
var startLoader:Loader = loadScreen({"type":"START_GAME"});
startLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, startLoaded);
}
}
The last thing I want to be guilty of is telling you how to run your project, however, I think you may be taking the wrong approach, here.
Instead of setting up the story and the game as separate swf files, what you would probably need to do is set up the story as a MovieClip, and the game as a MovieClip. (Yes, MovieClips can contain other symbols, including other MovieClips.) Then, you'll want to hide/show or add/remove these MovieClips from your stage using code.
If you need to know how to do this, let me give you the age-old admonishment: RTD (Read the Documentation). These are basic tasks that are covered both in the online Adobe Flash documentation, and across numerous tutorials online.
I hope that helps!
I have a really simple code piece like that;
loadingMc.visible = true;
trace("ok");
// send photo to server
loadingMc.visible = false;
Sending photo takes 3-5 seconds but movie clip becomes visible only for last second of process. I can see "ok" message in output at start of the process. So i assume problem is not redrawing movie clip. Is there any option to force redraw before process starts?
UPDATE:
Sending to server part;
upload.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void{
loadingText.visible = true;
trace("ok");
var bmd:BitmapData = new BitmapData(1024,768,true,0);
bmd.draw(imageArea);
savePicToServer(bmd);
});
function savePicToServer(bmd:BitmapData):void
{
var jpgEncoder:JPGEncoder = new JPGEncoder(85);
var jpgStream:ByteArray = jpgEncoder.encode(bmd);
var loader:URLLoader = new URLLoader();
configureListeners(loader);
var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
var request:URLRequest = new URLRequest("http://localhost/test/upload.php?key=prvkey");
request.requestHeaders.push(header);
request.method = URLRequestMethod.POST;
request.data = jpgStream;
loader.load(request);
}
In the COMPLETE event;
loadingText.visible = false;
EDIT
Just from reading your code, I don't see why this should not be working - but FP does strange things sometimes.
In similar cases, I used setTimeout() to force the player to delay the subsequent actions and allow the screen to refresh:
upload.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void{
loadingText.visible = true;
trace("ok");
setTimeout( doSave, 10 );
});
private function doSave() : void {
var bmd:BitmapData = new BitmapData(1024,768,true,0);
bmd.draw(imageArea);
savePicToServer(bmd);
}
If this still doesn't work, perhaps a longer timeout will do the trick - but 10ms usually should be enough to refresh the screen.
EDIT
Another way would be to add and remove an ENTER_FRAME listener to make sure the frame really was refreshed:
upload.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void{
loadingText.visible = true;
trace("ok");
addEventListener( Event.ENTER_FRAME, onNextFrame );
});
private function onNextFrame( ev:Event ) : void {
removeEventListener( Event.ENTER_FRAME, onNextFrame );
doSave();
}
private function doSave() : void {
var bmd:BitmapData = new BitmapData(1024,768,true,0);
bmd.draw(imageArea);
savePicToServer(bmd);
}
I would be very thankful if you help me with this problem.
I´m trying to play in my application for ipad one MovieClip once. i tried to do stopping in this way, but the movie dont stop
var loader:Loader = new Loader();
var swfFile:URLRequest= new URLRequest("/test.swf");
loader.load(swfFile);
movieClip = new MovieClip();
movieClip.addChild(loader);
movieClip.addFrameScript(movieClip.totalFrames - 1, callbackFunc);
movieClip.play();
private function callbackFunc():void
{
movieClip.stop();
}
var loader:Loader = new Loader();
var swfFile:URLRequest= new URLRequest("/test.swf");
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onFileLoaded);
loader.load(swfFile);
//I assume you have declared 'movieClip'?
//if not do:
//var movieClip:MovieClip;
private function onFileLoaded(e:Event):void
{
movieClip = loader.content;
addChild(movieClip);
movieClip.play();
addEventListener(Event.ENTER_FRAME, onEnter, true, 0, false);
}
private function onEnter(e:Event):void
{
if (movieClip.currentFrame == movieClip.totalFrames)
{
movieClip.stop();
removeEventListener(Event.ENTER_FRAME, onEnter, true, 0, false);
//do other stuff
}
}
This should do what you need.
var loader:Loader = new Loader();
var swfFile:URLRequest= new URLRequest("/test.swf");
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
loader.load(swfFile);
private function callbackFunc():void
{
movieClip.stop();
}
function onCompleteHandler(loadEvent:Event)
{
movieClip = MovieClip(loadEvent.currentTarget.content);
addChild(movieClip);
movieClip.addFrameScript(movieClip.totalFrames - 1, callbackFunc);
movieClip.play();
}
Your code will not work because it's not the movieClip that is played, it's the external SWF that you load into it that will play it's keyframes. The created movieClip only has 1 keyframe, and on that 1 keyframe the external SWf is placed. You should add the stop() function into the external SWF. If you do this correct the external SWF plays once, and is then stopped.
You can also wrap the external SWF into a new MovieClip and put the code you already have onto it...
Or If you want full control, you can adapt the external SWF code so that this dispatches an event when the last frame is played. Provide a custom stop / replay function on the SWF which you can then call from the parent SWF.
Good luck!
Currently I'm trying to change image loaded in a sprite with mouseover event and change it back with mouseout. But it's not working correctly, am i missing something?
public class Tab extends Sprite
{
var imageLoader:Loader = new Loader();
var TabSprite:Sprite = new Sprite();
var SkinImages:Array = [Skin.TAB_ACTIVE,Skin.TAB_DISABLED,Skin.TAB_HOVER,Skin.TAB_VIEW];
public function Tab()
{
for each (var Image:String in SkinImages){
imageLoader.load(new URLRequest(Image));
}
TabSprite.buttonMode = true;
addChild(TabSprite);
TabSprite.addChild(imageLoader);
TabSprite.addEventListener(MouseEvent.MOUSE_OVER, onTabHover);
}
private function onTabHover(e:MouseEvent){
trace("HOVER");
TabSprite.removeEventListener(MouseEvent.MOUSE_OVER, onTabHover);
imageLoader.load(new URLRequest(Skin.TAB_HOVER));
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void{
TabSprite.addEventListener(MouseEvent.MOUSE_OUT, onTabOut);
});
}
private function onTabOut(e:MouseEvent){
trace("OUT");
TabSprite.removeEventListener(MouseEvent.MOUSE_OUT, onTabOut);
imageLoader.load(new URLRequest(Skin.TAB_VIEW));
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void{
TabSprite.addEventListener(MouseEvent.MOUSE_OVER, onTabHover);
});
}
}
You shouldn't nest listeners that way. Just add two in the constructor:
TabSprite.addEventListener(MouseEvent.ROLL_OVER, onTabHover);
TabSprite.addEventListener(MouseEvent.ROLL_OUT, onTabOut);
Note changing MOUSE_OVER to ROLL_OVER it's better in most cases. You shouldn't also load images at every mouse event. Preload them, and then use. Also using anonymous functions in listeners is bad practice as you are not able to remove that listener:
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void{
TabSprite.addEventListener(MouseEvent.MOUSE_OUT, onTabOut);
});
And in fact you are not removing it - this is bad.
for each (var Image:String in SkinImages){
imageLoader.load(new URLRequest(Image));
}
I doubt it works, I think you cannot load many images at once by using one loader.
Try this:
public class Tab extends Sprite
{
var imageOverLoader:Loader = new Loader();
var imageOutLoader:Loader = new Loader();
var TabSprite:Sprite = new Sprite();
var SkinImages:Array = Skin.TAB_ACTIVE,Skin.TAB_DISABLED,Skin.TAB_HOVER,Skin.TAB_VIEW];
public function Tab()
{
TabSprite.buttonMode = true;
this.addChild(TabSprite); // you also need to add as a Child "Tab" object in the Main Class
imageOutLoader.load(new URLRequest(Skin.TAB_VIEW));
imageOverLoader.load(new URLRequest(Skin.TAB_HOVER));
TabSprite.addChild(imageOutLoader);
TabSprite.addEventListener(MouseEvent.ROLL_OVER, onTabHover);
TabSprite.addEventListener(MouseEvent.ROLL_OUT, onTabOut);
}
private function onTabHover(e:MouseEvent){
TabSprite.removeChild(imageOutLoader);
TabSprite.addChild(imageOverLoader);
trace("HOVER");
}
private function onTabOut(e:MouseEvent){
TabSprite.removeChild(imageOverLoader);
TabSprite.addChild(imageOutLoader);
trace("OUT");
}
}
Try this.