Is it possible to save logs of Trace somewhere, so that I can look up traces for players?
Yes, but for that you need a logger function instead of trace(). By the way, if you compile your SWF in release mode, no traces will happen. Say like this one:
private static var COMPLETE_LOG:String='';
public static function log(...args):void {
var i:int; var s:String='\n';
for (i=0;i<args.length;i++) {
if (i>0) s+=' ';
s+=args[i].toString();
}
COMPLETE_LOG+=s;
}
Use log() instead of trace() to capture traces you need. And then say upload that COMPLETE_LOG somewhere.
Related
I'm an as3 newbie and I'm trying to send a message through netstream to a function that will handle it.
Here is the line that sends
public function _attachLocalVideoAndAudio(muteCam:Boolean = false, muteMic:Boolean =
false):void
{
...
_outgoingStream.send("flagVideo",true);
...
}
public function flagV():Boolean
{
var client:Object;
client.flagVideo=function(flag:Boolean):void{
check=flag;
}
return check;
}
*check is defined
I'm using Monster Debugger to debug and it seems that there is a problem with the inner function that handles the flag. There isn't much tutorials on the web on netstream.send() but I wrote this code based on something I saw online.
The Sound API seems to be missing a function to indicate that a sound is finished playing. Is there some other way of finding out if the sound is done?
Not without submitting a patch to libgdx as far as I know the underlying Sound Backends for both OpenAL and Android don't even track the information internally, though the Music API has an isPlaying() function and getPosition() function as per the documentation.
just set this
sound.setLooping(false);
this way it will not run again and again.
and to check whether sound is playing or
not do this.
make a boolean variable
boolean soundplaying;
in render method do this
if(sound.isPlaying()){
soundplaying =true
}
and make a log
gdx.app.log("","sound"+soundplaying);
You can track this by storing the sound instance id that e.g. play() and loop() return. Example code:
private Sound sound;
private Long soundId;
...
public void startSound() {
if (soundId != null) {
return;
}
soundId = sound.loop(); // or sound.play()
}
public void stopSound() {
sound.stop(soundId);
soundId = null;
}
If you didn't want to have to call stopSound() from client code, you could just call it from startSound() instead of the return, to ensure any previous sound is stopped.
I have tried this for HOURS. There must be a simple solution to stop the sound and unload it in as3.
This is not all of my code, but in short I am loading random sounds. I need certian vars to be outside of the function so I can reference them with other functions for a progress bar.
How do I unload a sound so I can load a new one using the same names without getting an error the second time its called?
I have two buttons in this test. A play Sound and a Stop Sound Button.
here is my code:
var TheSound:Sound = new Sound();
var mySoundChannel:SoundChannel = new SoundChannel();
PlayButton.addEventListener(MouseEvent.CLICK, PlaySound);
StopButton.addEventListener(MouseEvent.CLICK, Stopsound);
function PlaySound(e:MouseEvent)
{
TheSound.load(new URLRequest("http://www.MyWebsite.com/Noel.mp3"));
mySoundChannel = TheSound.play(0);
}
function StopSound(e:MouseEvent)
{
delete TheSound;
}
HERE IS THE ERROR I GET:
Error: Error #2037: Functions called in incorrect sequence, or earlier call was unsuccessful.
at flash.media::Sound/_load()
at flash.media::Sound/load()
at Untitled_fla::MainTimeline/PlaySound()[Untitled_fla.MainTimeline::frame1:21]
UPDATE.... I TRIED STOPING THE SOUND AND THEN UNLOADING IT AS FOLLOWS
mySoundChannel.stop();
TheSound.close();
BUT NOW I GET THIS ERROR:
Error: Error #2029: This URLStream object does not have a stream opened.
at flash.media::Sound/close()
at Untitled_fla::MainTimeline/shut1()[Untitled_fla.MainTimeline::frame1:35]
I believe I am closer. Thanks so much for your help so far.
In order to stop the sound from playing, you first have to tell the SoundChannel instance to stop like so :
mySoundChannel.stop();
Once you did that, you can close the stream used by the sound instance by invoking the close method like so :
TheSound.close();
Also, the delete keyword is rarely used in as3 and you should not it while some methods are trying to access the variable you are deleting. If you want to dispose of the instance that is currently assigned to your TheSound variable, you should set its value to null. This way, flash will properly garbage collect the old Sound instance that is no longer used when it finds the appropriate time to do so.
You can initialise the variable outside of the function, but define it as a new Sound object each time the function is called. That way it has global scope, and you can load a new URL at any time.
var TheSound:Sound;
var mySoundChannel:SoundChannel = new SoundChannel();
PlayButton.addEventListener(MouseEvent.CLICK, PlaySound);
StopButton.addEventListener(MouseEvent.CLICK, StopSound);
function PlaySound(e:MouseEvent)
{
TheSound = new Sound();
TheSound.load(new URLRequest("http://www.MyWebsite.com/Noel.mp3"));
mySoundChannel = TheSound.play(0);
}
function StopSound(e:MouseEvent)
{
mySoundChannel.stop();
TheSound.close()
}
I have read this article about abstracting assets from ActionScript:
Abstracting Assets from Actionscript in AS3.0 – Asset Libraries and DuplicateMovieClip
But it requires to set the Linkage Class name. How can I get the same result without setting the linkage class name?
What I want to do is to cache a loaded asset, and use the cached version every time I request the same URL. A solution is to clone the loaded DisplayObject, but I think it's unnecessary since I only want a new copy.
I think the way to do that is to use byte arrays
here's a quick sample
// once you load your data...
private function loaderComplete(event:Event):void
{
var loaderInfo:LoaderInfo = LoaderInfo(event.target);
var byteArray:ByteArray = loaderInfo.bytes; //<- this will create your byte array
}
you can then use byteArray.readObject(); to generate the new class;
look at senocular's post at http://www.kirupa.com/forum/showthread.php?p=1897368
where he's got a function like this:
function clone(source:Object):* {
var copier:ByteArray = new ByteArray();
copier.writeObject(source);
copier.position = 0;
return(copier.readObject());
}
//that you use with
newObjectCopy = clone(originalObject);
hope this gets you started
As of Flash 11.3, there's a function named getQualifiedDefinitionNames that tells me exactly what linkage names should I use with getDefinition, so there's no need to know the values beforehand.
I wondered if there is a simple way I have have a snippet which traces the name of a method when called. I found className which is half-way there, but not something for the method... a 1-line trace(...) is what I'm after so I avoid typing the method name and leaving myself open to mistakes.
This is for testing the order things happen, when I don't want to step through in the debugger.
If you have compiled your swf with debug information and use the debug version of the player you can take a look at getStackTrace property from the Error object:
Quick example:
public function getCallingInfos():Object{
var tmp:Array=new Error().getStackTrace().split("\n");
tmp=tmp[2].split(" ");
tmp=tmp[1].split("/");
return {namespaceAndClass:tmp[0], method:tmp[1]};
}
var infos:Object=getCallingInfos();
trace(infos.namespaceAndClass, infos.method);
public static function getCurrentClassName(c:Object):String
{
var cString:String = c.toString();
var cSplittedFirst:Array = cString.split('[object ');
var cFirstString:String = String(cSplittedFirst[1]);
var cSplittedLast:Array = cFirstString.split(']');
var cName:String = cSplittedLast.join('');
return cName;
}
Used to check if a certain class is constructed or not.
Usage (here I put the code in the main class):
trace('[DEBUG]: '+ClassData.getCurrentClassName(this)+' constructed.');
trace returns:
[DEBUG]: Main constructed.