import multiple sounds in a for each loop, actionscript 3 - arrays

So im recreating my ear training program with more effective coding so i can add on to it.
original i did.
//88 C8
var mp3Req88:URLRequest = new URLRequest("88.mp3");
var mp3_88:Sound = new Sound();
mp3_88.load(mp3Req88);
I basically got 88 sound files (each note of the piano) doing this code 88 times for each sound. with mathamatical equations made my ear training program.
Is there a simpler way to import these sounds in a loop of some sort so i dont have to do this 88x for the piano and however many times for the other instruments i will be including?
thus var i have tried things along the lines of below with failure
var i:int;
for (i = 0; i < 5; i++)
{
var pianoMP3Req+i:URLRequest=new URLRequest("piano/"i+"mp3");
var pianoMP3_+i:Sound=new Sound();
pianoMP3_+i.load(pianoMP3Req+i);
}

I am not sure if your strings concatenate correctly (if they correctly produce the valid filename.)
Try like this:
var i:int;
for (i = 0; i < 5; i++) {
var request = pianoMP3 + "" + i;
request:URLRequest=new URLRequest("piano/" + i + ".mp3");
var temp = pianoMP3 + "" + i;
temp:Sound=new Sound();
temp.load(request);
}
for both the request and the mp3. I don't have an environment to test it at the monent.

Related

In Actionscript 3, how to create many instances of the same symbol?

Though coding, I must make many copies of the same MovieClip to be placed on the stage, each to be manipulated code-wise on its own
For instance, I have a MovieClip named MC and I wish to have 99 copies of ít loaded onto the stage, each in a different x coordinate. What should I do?
I think on doing this:
Step 1: in the library, turning MC into a class
Step 2: placing the following code in the scene's script
var MyArray:Array = new Array
for (var i:int = 0; i<99;i++)
{
var MCInstance:MC = new MC
MC Instance = MyArray[i]
MovieClip.(MyArray[i]).x = i*30
}
Would that make sense?
That's probably the right idea, your syntax is just a little off. Try this:
var myArray:Array = [];
for (var i:int = 0; i < 99;i++)
{
var mc:MC = new MC();
myArray[i] = mc;
mc.x = i * 30
}
AS3 style conventions: use lowerCamelCase for variable names, don't omit constructor parens even though they are optional, and create arrays using literals (source).
You could push each MovieClip to an Array after adding it to the Stage.
var myArray = [];
for(var i:int = 0; i < 99; i++)
{
var myMc:MC = new MC();
addChild(myMc);
myMc.x = myMc.width * i + 2;
myMc.y = 10;
myArray.push(myMc);
}

Actionscript 3 and sorting incoming bytes from an arduino

im new to using action script so i apologies if this wont make sense, the issue iam having is that the incoming bytes from my arduino are not being stored properly in an array. The bytes come in one at a time from my arduino and will be stored in an array in as3.
i have two values SF-F8-001, SF-F8-002 and SF-F8-003 etc... when i trace the incoming bytes i get this:
S
F
-
F
8
-
0
0
1
so when i look at that i realized i needed an array to store the byte as they come in however i have tried many different things but it hasnt worked
however this code below seems to get me close to my desired result
import flash.events.*;
import flash.net.Socket;
import flash.utils.ByteArray;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLVariables;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequestMethod;
var ary:Array = new Array();
var bar_grab:Array = new Array();
var array:Array = new Array();
trace("__AS3 Example__");
var socket:Socket = new Socket("localhost",5331);
socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
function socketDataHandler(event:ProgressEvent):void
{
var str:String = String(socket.readUTFBytes(socket.bytesAvailable));
var b:String;
bar_grab.push(str);
b = bar_grab.join("");
boxtwo.text = b;
}
this code gets me this
SF-F8-001SF-F8-002SF-F8-003 etc...
however the result iam looking for is this
SF-F8-001,SF-F8-002,SF-F8-003 etc....
so if anyone could help me sort this out i will be grateful
thank you
If you know a priori how many characters each item will consist of you could read everything to string and get each individual item like that:
//Main string containing all items
var allString:String = "123456789";
//Number of chars in of item
var charsInItem = 3;
var item:String;
var index:int;
var resultArray:Array = new Array();
for(var i:int = 0; i < allString.length/charsInItem; i++)
{
index= i*charsInItem;
//traces name of one item
item = allString.slice(index, index+charsInItem);
resultArray.push(item);
trace(item);
}
//Output:
//123
//456
//789
If you don't know a number of chars in one item or it varies, I would suggest tweaking Arduino code and putting some sort of a marker in between every item. Like say a comma (,). Then your string would look something like this: "item1,item2,longerItem3". And you could split that string into array like that:
var array:Array = new Array();
var allString:String = "item1,item2,longerItem3";
//This splts string into array items using comma (,) as a seperator
array = allString.split(",");
for(var i:int = 0; i < array.length; i++)
{
//trace every array element
trace(array[i]);
}
//Output:
//item1
//item2
//longerItem3
I should add that even if you know a number of chars in one item I would still suggest using method nr.2.

Why when I publish the project in Actionscript my screen does not visualize the content?

I've been the whole day looking for the error for this situation and I've not found an answer... I just started with AS (and with every the programming staff in general), sorry if this is a dump question, but I can't understand this:
I have an empty workflow. I've created a movieclip with 3 frames each of them with one label.
I've created then 3 arrays, 1 for the labels, and 2 for the position of the objects.
I publish the project and there is no errors, but I can visualize only the first addChild in the screen.
Here is the code:
var Piece:piece = new piece;
var Piece_type:Array = [
"tS", "tD", "tC"];
var X: Array = [25,55,85];
var Y: Array = [221,221,221];
PrintBoard();
function PrintBoard():void
{
for(var i:int = 0; i < Piece_type.length; i++)
{
addChild(Piece);
Piece.x = X[i];
Piece.y = Y[i];
Piece.label = Piece_type[i];
trace("why?");
}
}
There is no errors in the console and the loop is finishing with 3 walk throughs, but only with 1 object. I am using Actionscript 3 and the publishing setting are for Air 3.2 Android
If anyone knows what's going on it would be really helpful... thank you.
You need to create an instance of the class:
for(var i:int = 0; i < Piece_type.length; i++)
{
var myPiece:Piece = new Piece;
addChild(myPiece);
myPiece.x = X[i];
myPiece.y = Y[i];
myPiece.label = myPiece_type[i];
trace("why?");
}
Also, it is not a good idea to name things the same as actionscript keywords or properties – like naming your array "X" - may do no harm in some cases but can lead to confusing bugs in others.

Is it possible to reload or reset an array in as3?

I'm wondering if it is possible to reset / reload / reconstruct an array order?
I'm making this "Space Invaders" game and the enemy's need to restart to it's position when the game is being restarted. When I shoot down the enemy's and reset my game, the enemy's I've killed keep being gone.
So here's some of the code responsible:
var spiderArray:Array = new Array(enemyField.enemy1,enemyField.enemy2,
enemyField.enemy3,enemyField.enemy4,
enemyField.enemy5,enemyField.enemy6,
enemyField.enemy7,enemyField.enemy8,
enemyField.enemy9,enemyField.enemy10,
enemyField.enemy11,enemyField.enemy12,
enemyField.enemy13,enemyField.enemy14,
enemyField.enemy15,enemyField.enemy16,
enemyField.enemy17,enemyField.enemy18,
enemyField.enemy19,enemyField.enemy20,
enemyField.enemy21,enemyField.enemy22,
enemyField.enemy23,enemyField.enemy24,
enemyField.enemy25,enemyField.enemy26,
enemyField.enemy27,enemyField.enemy28,
enemyField.enemy29,enemyField.enemy30,
enemyField.enemy31,enemyField.enemy32,
enemyField.enemy33,enemyField.enemy34,
enemyField.enemy35,enemyField.enemy36,
enemyField.enemy37,enemyField.enemy38,
enemyField.enemy39,enemyField.enemy40,
enemyField.enemy41,enemyField.enemy42,
enemyField.enemy43,enemyField.enemy44,
enemyField.enemy45,enemyField.enemy46,
enemyField.enemy47,enemyField.enemy48,
enemyField.enemy49,enemyField.enemy50,
enemyField.enemy51,enemyField.enemy52,
enemyField.enemy53,enemyField.enemy54,
enemyField.enemy55,enemyField.enemy56,
enemyField.enemy57,enemyField.enemy58,
enemyField.enemy59,enemyField.enemy60,
enemyField.enemy61,enemyField.enemy62,
enemyField.enemy63,enemyField.enemy64,
enemyField.enemy65,enemyField.enemy66);
Now the place where the enemy's are being killed:
function enemyHitTest():void {
//for each of the three spiders
for(var i:int = 0; i < spiderArray.length; i++) {
//the each of the six bullets
for(var j:int = 0; j < 6; j++) {
//don't consider bullets that aren't in play:
if(bulletArray[j].y > SpelerMC.y) continue;
if(spiderArray[i].hitTestObject(bulletArray[j])) {
score += 10;
scoreTxt.text = score.toString();
trace("Invader " + i + " neergeschoten!");
spiderArray[i].parent.removeChild(spiderArray[i]);
bulletArray[j].x = j * 70 + 100;
bulletArray[j].y = 595;
}
}
}
Now I think I need to put some sort of theArray.pop(); or something, but don't know how to use it, but I need to place it in this function:
function startGame() {
trace("Start het spel opnieuw...");
gameTimer.addEventListener(TimerEvent.TIMER, onTick);
gameTimer.start();
enemyField.x = 400;
enemyField.y = 160;
SpelerMC.x = 83;
SpelerMC.y = 531;
}
Please help me! Have been searching for 5 hours already. Thanks in advance!
to remove element number i use array.splice(i, 1); ( http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html#splice().com/en_US/FlashPlatform/reference/actionscript/3/Array.html#splice%28%29) but keep in mind that array.length will decrease
to reset the array just invoke spidersArray = new Array(enemyField.enemy1, etc) again
UPDATE
in in the enemyHitTest function i changed the removing condition to if(enemyArray[i].visible && enemyArray[i].hitTestObject(laserArray[j])) and enemyArray[i].parent.removeChild(enemyArray[i]); to enemyArray[i].visible = false;
and added
function respawnEnemies():void{
for(var i:int = 0; i < enemyArray.length; i++) {
enemyArray[i].visible = true;
}
}
to call it from startGame
full code here
upd 2
so the problem was not in resetting the array but in the fact that your enemyField and its' enemies were added to stage manually and removed programmatically so there was no code to call to bring them back
if all your instances should be preserved - e.g. you generate all actors at the beginning and later all of them are reused (at the new game) you can set an array of them and on each start game make a copy and remove "dead" enemies from the copied array
also better option is to use a vector e.g.
var enemies:Vector.<Enemy> = Vector.<Enemy>([]);//in brackets references to the instances of Enemy class
var inGame:Vector.<Enemy> = enemies.concat();
also 5hrs of research? please be patient and try harder,
best regards

Flash AS 3 Loader OnComplete Inside a Loop

As a followup to the question, How to get associated URLRequest from Event.COMPLETE fired by URLLoader, how can I make the function work for loader object in a loop?
Here is my existing (rough) code; I always get the mylabel from the last element of the array.
var _loader = new Loader();
for (j = 0; j < 5; j++) {
//mylabel variable is correct setup in the loop
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void {
doneLoad(e, mylabel);
});
_loader.load(new URLRequest(encodeURI(recAC[j].url)));
}//for loop
As per the comments above, this won't work because:
1) You're just adding the same event listener 5 times to the loader.
2) You're just reseting your same loader object 5 times.
The final output will just be as though you only called it the last time.
There are a variety of ways to address this - loading stuff asynchronously is one of the great mindfucks of learning to code - but the simplest way is probably just to create five separate loaders.
I'd do something like this:
var loaders:Array = [];
var labels:Array = ["label1", "label2", "label3", "label4", "label5"];
for (var j:int = 0; j < 5; j++) {
loaders[j] = new Loader();
loaders[j].contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
loaders[j].load(new URLRequest(encodeURI(recAC[j].url)));
}
function completeHandler(e:Event):void {
doneLoad(e.currentTarget, labels[loaders.indexOf(e.currentTarget)]);
}
The confusing part is finding a good way to keep track of which load is associated with which label etc, since in theory your loads can finish in any order. That's why I've got a separate label array there, and then you just match up the desired label with the loader that just finished loading.
I hope that helps!
the line belove should work but it returns -1, always.
loaders.indexOf(e.currentTarget);
Here my code
for(i; i < total; i++){
imgLoaderArray[i] = new Loader();
imgLoaderArray[i].contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, urlError);
imgLoaderArray[i].contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
imgLoaderArray[i].load(new URLRequest(xmlList[i].image));
}
function loaded(e:Event):void{
trace("index: "+imgLoaderArray.indexOf(e.currentTarget)); // return -1 every time
}

Resources