reading out multi dimensional array - actionscript-3

the multi array is read in correctly
but reading out the array he messes up.
the action that suppose to be done on each element from array in array, he doesn't do it anymore when more indexes in 2 array are made.
when a second index in 2 array i made he doesn't do this action anymore on previous index, only the last made index.
thanks
private var Enemy:Array = new Array();//1st array
private var EnemyHull:Array = new Array();
private var waves:Array = new Array();//2 array ==> array 1 get in this
private function enterFrame(e:Event):void
{
//Enemy Ai
for(var i2:uint; i2 < waves.length; i2++){
for(var i:uint; i < Enemy.length; i++){
waves[i2][i].x -= 1;//when a second index in 2 array i made he doesn't do this action anymore on previous index, only the last made index.
}
}
}
private function enemySpawnen(event:TimerEvent):void
{
for(var i:uint = 0; i < hoeveelheidEnemy;i++){
//
}
if(Enemy[i] != null){;
viewContainer.addChild(Enemy[i]);
//
}
}
waves[iwaves] = Enemy;
iwaves++;
}
function shoot(e:Event):void
{
//
try{
for(var i2:uint; i2 < waves.length; i2++){
for(var i:uint = Enemy.length-1; i >= 0;i--){
if(kogel.hitTestObject(waves[i2][i])){
//
}
}
}
}
}
catch(e:Error){
}
}
}

Your for loops misses an important thing to work properly : you have to initialize your iterator (i or i2) to a starting value.
You wrote :
for(var i2:uint; i2 < waves.length; i2++){
for(var i:uint; i < Enemy.length; i++){
waves[i2][i].x -= 1;
}
}
But what you need is :
for(var i2:uint = 0; i2 < waves.length; i2++){
for(var i:uint = 0; i < Enemy.length; i++){
waves[i2][i].x -= 1;
}
}
Dont forget the = 0 in your loop declaration !

Related

Is there any difference in performance between these two for loop?

As I said: Is there any difference (in performance) between these two for loop?
Between this:
var n:int = displayObjects_.length;
for (var i:int = 0; i < n; i++)
{
var currentObject:DisplayObject = displayObjects_[i];
currentObject.width = newWidth;
}
and this:
var n:int = displayObjects_.length;
for (var i:int = 0; i < n; i++)
{
displayObjects_[i].width = newWidth;
}
I tested them before. The result said the first one was faster but I don't know if I did it right.
I know it's not really an answer to your question, but if you're looking for fastest way to iterate through this array you should do:
for each(var currentObject:DisplayObject in displayObjects_) {
currentObject.width = newWidth;
}
I tried this out on a bare-bones project using SDK 4.6. This is the code.
public class Main extends Sprite
{
public function Main()
{
var displayObjects_:Array = [];
for (var i:int = 0; i < 1000000; i++)
{
displayObjects_.push(new Sprite());
}
var start:int = getTimer();
for (i = 0; i < displayObjects_.length; i++)
{
var currentObject:Sprite = displayObjects_[i];
currentObject.width = 100;
}
var end:int = getTimer()
trace(end, start, end - start);
start = getTimer();
for (i = 0; i < displayObjects_.length; i++)
{
displayObjects_[i].width = 100;
}
end = getTimer()
trace(end, start, end - start);
}
}
These are the results.
Done(0)
[Starting debug session with FDB]
16703 16250 453
17141 16703 438
Like I said, it would be very surprising to see any difference between the two. You'll probably see more improvements through using Vector instead of Array. Otherwise, this stuff is too mundane to fuss over.
As I know, Actionscript compiler automatically moves variable definitions to the begin of the function. So, this loop doesn't declare variable each time, first sample the same that:
var currentObject:DisplayObject;
var n:int = displayObjects_.length;
for (var i:int = 0; i < n; i++)
{
currentObject = displayObjects_[i];
currentObject.width = newWidth;
}
So, I think the difference only in one additional variable declare and it willn't affects performance. But 3vilguy's example is better.

AS3 Array 1 to 100

I'm having trouble finding a way to do an array that doesn't make me type all the numbers , for example :
(i found this code online)
var array:Array=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
var odds:Array=[],
evens:Array=[],
odds_sum:int=0,
evens_sum:int=0
;
for(var i:int = 0; i < array.length; i++){
if(array[i] % 2 == 1){
odds.push(array[i]);
odds_sum += array[i];
} else {
evens.push(array[i]);
evens_sum += array[i];
}
}
trace(odds);
trace(odds_sum);
trace(evens);
trace(evens_sum);
i wanted the code to trace all the numbers between 1 and 100 (including the 1 and 100) but don't have to type them all down.
Help solving this would be much appreciated
Your question is ambiguous , If you simply need all the numbers between 1 and 100 you simply do
for(var i:int = 1; i <= 100; i++){
trace(i);
}
or if you want them in your array
var arr:Array = new Array();
for(var i:int = 1; i <= 100; i++){
arr.push(i);
}
or if you want odd and even numbers in separate array
var odds:Array = new Array();
var evens:Array = new Array();
for(var i:int = 1; i <= 100; i++){
if(i%2==0)
evens.push(i);
else
odds.push(i);
}
where the array odds/even have appropriate numbers between 1 and 100.

Adding indexes in array

I am adding two matrices (or possibly many) in ActionScript 3.0.
Now my problem is how can I add indexes in array that is something like this?
array1[1,2,3,4] + array2[2,4,5,6] = answer[3,6,8,10]
This function adds up all the arrays that are passed to it:
function sumOfArrays(...args):Array
{
var sum:Array = [];
var arrays:Array = [];
var longestArrayLength:uint = 0;
for (var i:int = 0, n:int = args.length; i < n; i++)
{
if (args[i] is Array)
{
arrays.push(args[i]);
longestArrayLength = args[i].length > longestArrayLength ? args[i].length : longestArrayLength;
}
}
for (var j:int = 0; j < longestArrayLength; j++)
{
sum[j] = 0;
for (i = 0; i < n; i++)
{
sum[j] += isNaN(arrays[i][j]) ? 0 : arrays[i][j];
}
}
return sum;
}
It can be used like this:
var sum:Array = sumOfArrays(array1, array2);
That's not possible. Arrays only allows access via one index. You'd have to write a method on your own for this. But be aware of the fact, that null would be referenced on answer at, 0, 1, 2, 4, 5 and so on.

XMLListCollection find index value

I want to find specific value on a XMLListCollection.
I try to use something like this but it doesn't work!
var xmllisteRDV:XMLList= XML(event.result).RDVClinik;
xmlCollSuivi = new XMLListCollection(xmllisteRDV);
var index:Number = -1;
for(var i:Number = 0; i < xmllisteRDV.length(); i++)
{
if(XML(xmllisteRDV[i]).#grDateDeb == todayDate)
{
index = i;
break;
}
}
First going to try pointing out errors in the original code:
var xmllisteRDV:XMLList= XML(event.result).RDVClinik; //Unnecessary cast, event.result is Object compiler will not check or know the run-time type, doesn't care because Object is declared dynamic meaning properties can be added to it dynamically, if RDVClinik didn't exist on the particular Object type it would simply be null casting as XML gives it no information about this "property"
xmlCollSuivi = new XMLListCollection(xmllisteRDV);
var index:Number = -1;
for(var i:Number = 0; i < xmllisteRDV.length(); i++) //length is a property not a method on XMLListCollection this should throw a compile time error
{
if(XML(xmllisteRDV[i]).#grDateDeb == todayDate)// I see no type when debugging for the result of xmllisteRDV[i] not positive here but this cast is at the least unnecessary
{
index = i;
break;
}
}
Here's a version I think will work possibly with changes to how todayDate is built
var date:Date = new Date();
var todayDate:String = date.dateUTC+"/"+date.dayUTC+"/"+date.fullYear;
var index:int=-1;
for(var i:int = 0; i < flex3Projects.length; i++)
{
trace(xmllisteRDV[i].#grDateDeb)
if(xmllisteRDV[i].#grDateDeb.toString() == todayDate)
{
index = i;
break;
}
}
With you help, I found the solution
private function setSelectedItem():void
{
var gData:Object = dgSuiviClini.dataProvider;
var todayDate:String= new DateUtility().DateAsToString(new Date());
for(var i:Number=0; i < gData.length; i++)
{
var thisObj:Object = gData.getItemAt(i);
if(thisObj.grDateDeb == todayDate)
{
dgSuiviClini.selectedIndex = i;
//sometimes scrollToIndex doesnt work if validateNow() not done
dgSuiviClini.validateNow();
//dgSuiviClini.scrollToIndex(i);
}
else{
dgSuiviClini.validateNow();
// dgSuiviClini.scrollToIndex(gData.length);
}
}
dgSuiviClini.validateNow();
dgSuiviClini.editedItemPosition = { rowIndex: gData.length-1, columnIndex: nColSaisie };
}
Thanks

Why does my Actionscript 3 program randomly get stuck in an infinite loop?

mBlocks is a 2-dimensional array of Block objects. Every time my application runs, it runs the InitGridNumbers function. Sometimes, it will get stuck in an infinite loop. Other times, it builds and runs without issues.
public function InitGridNumbers():void
{
var tempRow:Array;
var tempColumn:Array;
var tempNum:int;
for (var i:int = 0; i < mNumRows; i++)
{
tempRow = GetRow(i);
for (var j:int = 0; j < mNumColumns; j++)
{
// if number is unassigned
if (tempRow[j] == 0)
{
var cantMoveOn:Boolean = true;
while (cantMoveOn)
{
tempNum = Math.random() * mNumColumns + 1;
if (!CheckRow(i, tempNum) && !CheckColumn(j, tempNum))
cantMoveOn = false;
}
mBlocks[i][j].SetNumber(tempNum);
}
}
}
}
public function CheckRow(rowNum:int, checkNum:int):Boolean
{
var tempRow:Array = GetRow(rowNum);
for (var i:int = 0; i < mNumColumns; i++)
{
if (checkNum == tempRow[i])
return true;
}
return false;
}
public function CheckColumn(columnNum:int, checkNum:int):Boolean
{
var tempColumn:Array = GetColumn(columnNum);
for (var i:int = 0; i < mNumColumns; i++)
{
if (checkNum == tempColumn[i])
return true;
}
return false;
}
public function GetRow(rowNum:int):Array
{
var rowArray:Array = new Array(mNumRows);
for (var i:int = 0; i < mNumRows; i++)
rowArray[i] = mBlocks[rowNum][i].mNumber;
return rowArray;
}
public function GetColumn(columnNum:int):Array
{
var columnArray:Array = new Array(mNumColumns);
for (var i:int = 0; i < mNumColumns; i++)
columnArray[i] = mBlocks[i][columnNum].mNumber;
return columnArray;
}
To begin with, checkColumn, getColumn and getRow methods are wrong. To get a row, you should copy numColumns items and to get a column, you should copy numRows items. In other words, if there are r rows and c columns, there would be c items per each row and r items per each column.
public function checkColumn(columnNum:int, checkNum:int):Boolean
{
var tempColumn:Array = getColumn(columnNum);
for (var i:int = 0; i < mNumRows; i++)
{
if (checkNum == tempColumn[i])
return true;
}
return false;
}
public function getRow(rowNum:int):Array
{
var rowArray:Array = new Array();//needn't specify length in advance.
for (var i:int = 0; i < mNumColumns; i++)
rowArray[i] = mBlocks[rowNum][i].mNumber;
return rowArray;
}
public function getColumn(columnNum:int):Array
{
var columnArray:Array = new Array();
for (var i:int = 0; i < mNumRows; i++)
columnArray[i] = mBlocks[i][columnNum].mNumber;
return columnArray;
}
while (cantMoveOn)
{
//call Math.floor
tempNum = Math.floor(Math.random() * mNumColumns) + 1;
if (!checkRow(i, tempNum) && !checkColumn(j, tempNum))
cantMoveOn = false;
}
It looks like you're checking for a number that is not present in the current row and column. It's hard to say without knowing more details, but can you think of a scenario where this would be impossible?
For example, if there are four columns and five rows, the tempNum would always be between one and four. Now if the number of rows is five and the corresponding column already has all numbers up to four, the if statement would never evaluate to true and hence you'd end up in an infinite loop
0 1 2 3
1
2
3
4
in case grid is a square, how about this:
0 1 2 3
4
0
0