AS3 Dynamic access to a sound channel - actionscript-3

I have a flash project with many soundchannels active at the same time. I want a little function to play one and loop it, and the name of the sound channel will be passed as a parameter. This is the function:
function playBGMusic(channel:String):void
{
SoundChannel(channel) = bgSound1.play();
SoundChannel(channel).addEventListener(Event.SOUND_COMPLETE, loopBGMusic);
}
playBGMusic("bgChannel1");
This doesn't works, flash gives me this error:
1105: Target of assignment must be a reference value.
I tried to simplify the function, using an static string only in the listener
function playBGMusic():void
{
bgChannel1 = bgSound1.play();
SoundChannel("bgChannel1").addEventListener(Event.SOUND_COMPLETE, loopBGMusic);
}
playBGMusic();
This time it compiles, but it gives me this error:
Error #1034: Type Coercion failed: cannot convert "bgChannel1" to
flash.media.SoundChannel.
How can I access to a sound channel from a string?
Thaks.

You need to access it in the context of this:
SoundChannel(this[channel]) or SoundChannel(this["bgChannel1"])

Related

How to assign a custom object to bytesArray? As3

I have a TActor class and a function to_bytes() inside it that should compress it to a bytes array as in this example: http://jacksondunstan.com/articles/1642
public function to_bytes():ByteArray
{
registerClassAlias("TActor",TActor);
var bytes:ByteArray=new ByteArray();
bytes.writeObject(this as TActor);
bytes.position=0;
trace(bytes.readObject());
bytes.position=0;
trace(bytes.readObject() as TActor);
return bytes;
}
However, the first trace prints undefined and the second one null instead of [object TActor].
What do I do wrong?
It's important to note that the this keyword returns the current instance of the object. What you are currently doing is attempting to pass the this instance to writeObject, which will only work if there is an instance of TActor instantiated. So it would work in this scenario:
In some class where you instantiate TActor:
var tactor:TActor = new TActor();
tactor.to_bytes();
Then it should serialize correctly.
Also as we discovered in the comments, TActor is of type MovieClip, currently you cannot use writeObject() on Objects of type MovieClip. More specifically any object that is a dynamic class cannot be used in writeObject. Changing it to Sprite solved this particular case.

Deep cloning using write byteArray not working

I'm writing a clone function for a class of mine.
var buffer:ByteArray = new ByteArray();
buffer.writeObject(this);
buffer.position = 0;
var gameblock:* = buffer.readObject();
Now at the last line when the time comes to read the object. I get these three errors together:
TypeError: Error #1009: Cannot access a property or method of a null
object reference. TypeError: Error #1034: Type Coercion failed: cannot
convert Object#c60efe9 to model.BlockData. TypeError: Error #1034:
Type Coercion failed: cannot convert Object#c5141c1 to
flash.geom.Matrix.
The class 'this' contains a user defined class BlockData and a Point . The errors are coming on that. How do you think I should clone this class?
I do overwrite the BlockData and the point again to make sure they get returned properly
Check this answer for better copy method with using of registerClassAlias method, but remember, that you can use this method only for simple cases, for example copy of data objects like TextFormat or Value Objects, you can't copy DisplayObject and its successor.

AS3 Access the methods of a dynamically created movieclip

How do I access the methods of a dynamically created movieclip/object?
For simplicity sake I didn't post code on how I dynamically created the movieclip. Instead, assume its already created. It is an object. It is called field_2. Below it is referenced by using getChildByName('field_' + field.id);
Check_box_component.as
public var testVar:String = 'test';
public function testReturn()
{
return 'value returned';
}
Main.as
var temp:MovieClip = MovieClip(getChildByName('field_' + field.id));
trace(temp);
trace(temp.testReturn);
trace(temp.testVar);
Output:
[object Check_box_component]
function Function() {}
test
When I trace temp.testReturn, why does it show "function Function() {}" instead of "value returned"?
This link below helped me get this to this point.
http://curtismorley.com/2007/06/13/flash-cs3-flex-2-as3-error-1119/
have you tried:
trace(temp.testReturn());
... instead of your
trace(temp.testReturn);
... ?
I think you will have the result you are waiting for.
Actually, when doing "temp.testReturn", you are not calling the function. You need to add the parenthesis to make the actual call.
When you make a trace of temp.testReturn, the function is not executed: the trace function tell you the type of temp.testReturn, which is here correctly returned as a "function" type.
There is a difference between a function reference and a function call. Parenthesis '()' are an operator sign of ActionScript. They tell the compiler "please try to make a call to what was just behind us". Or at least I hope they are that polite.
A function in ActionScript is an object, like all other stuff. A member of Function class. You can pass it's reference back and forth, you can even call it's methods like call() or apply().
If you want a call, and not a reference, you have to use call operator.
trace(temp.testReturn());
EDIT You accepted an answer while I was typing, sorry for a duplicate answer.

AS3 JSON.decode throwing #1009 error

I am using the as3corelib JSON library and decoding some JSON from a URLLoader request. However, I'm having issues with JSON.decode throwing an error:
TypeError: Error #1009: Cannot access a property or method of a null
object reference. at
com.adobe.serialization.json::JSONTokenizer/nextChar()
at
com.adobe.serialization.json::JSONTokenizer()
at
com.adobe.serialization.json::JSONDecoder()
at
com.adobe.serialization.json::JSON$/decode()
at Main/drawMap() at
flash.events::EventDispatcher/dispatchEventFunction()
at
flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()
My code is as follows:
private function storeAssets(e:Event):void
{
// returned variables from PHP call
var variables:URLVariables = new URLVariables(e.target.data);
assets = JSON.decode(variables.assets);
}
I have passed my JSON input into validators and it always returns as valid so I'm really scratching my head on this.
Your right in putting e.target.data into the URLVariables, as per this example: http://actionscriptexamples.com/2008/02/27/decoding-url-encoded-strings-in-a-flash-application-using-the-urlvariables-class-in-actionscript-30/
What I believe is happening is that URLVariables is decoding your entire string into an object, thus variables.assets is not in JSON format because it has already been converted. It could also be that variables.assets is not defined in the return data.
Trace out your variables.assets and see if it is null, or not in JSON format.
I would use eithervar variables:URLVariables = new URLVariables(e.target.data) or assets = JSON.decode(e.target.data) but not both at the same time.

"index is out of bounds" error when using readObject with Sockets

I'm trying to build a simple as3 server/client app.
When the client has connected to the server, it should send a message like "1" to the server.
The server does the following:
private function onConnect(e:ServerSocketConnectEvent):void
{
incomingSocket = e.socket;
incomingSocket.addEventListener(ProgressEvent.SOCKET_DATA, onData);
// You can now read and write data from the socket instance
trace("looks like a connection happened!");
}
private function onData(e: ProgressEvent):void {
var s:String = incomingSocket.readObject();
interrupt(s);
}
So flash throws me the error:
RangeError: Error #2006: The supplied
index is out of bounds. at
flash.net::Socket/readObject()
The line number flash provides me, shows that the problem is
var s:String = incomingSocket.readObject();
Has anyone an idea whats going on here?
Thank you!
n
readObject is used to read a serialized object on the socket.
If you sent a string, use readUTF, or readUTFBytes if you know the length the string should have.
If you sent a Int, use readInt, or the corresponding method.