AS3 putting each element of an array on a separate line - arrays

I'm working on a game which contains the following code; what it's meant to do is pick 8 random names from an array and enter them into some text onscreen, so that each element is on a separate line. Here's the summary of my code:
var a:Array
for (var i:Number=1; i<=packQ; i++)
{
shuffle(packShuffler);
//Note: this function randomly reorganizes the array "packShuffler", it's a pretty complicated function so lets leave it at that.
a.push(packShuffler[0])
a.push(packShuffler[1])
a.push(packShuffler[2])
a.push(packShuffler[3])
a.push(packShuffler[4])
a.push(packShuffler[5])
a.push(packShuffler[6])
a.push(packShuffler[7])
}
cardGet.text=""+a
//textbox looks something like this:
//blue,white,dragon,beast,great,black,Sword,Circle
I know it looks very very awkward, especially the push part, but it's the only way I know at the moment :/
Well, my problem is, at the last line {cardGet.text=""+a}, the text appears as a big block of elements with commas between them, what I want is to make each element appear on a separate line. How do I do this?

Part of the problem is that a.toString() is getting called implicitly, on the line that says cardGet.text=""+a. That being said, an Array's toString() method will, by definition, return element1 + ", " + element2 + ", " + ... + elementn.
But why are you pushing them onto a new array? Why not simply shuffle the old one, as you have, and then just build your own string out of it? Kind of like this:
shuffle(packShuffler);
cardGet.text = "";
// takes every element, except for the last, and adds it and a newline
// to the string
for (var j:int = 0; j < packShuffler.length - 1; j++)
{
cardGet.text += packShuffler[j] + "\n";
}
// adds the very last element to the string without a newline
cardGet.text += packShuffler[packShuffler.length - 1];

Related

Operate multiple arrays simultaneously

I am using as3 in adobe animate to create a video game.
I have created multiple arrays with movie clips e.g.
var A:Array [mc1, mc2, mc3]
var B:Array [mc4, mc5, mc6]
var C:Array [mc7, mc8, mc9]
var anObject:DisplayObject;
How can I operate all movie clips in all arrays simultaneously?
I have tried this:
mc_Player.addEventListener(MouseEvent.CLICK, Change_Position);
function Change_Position (event:MouseEvent):void
{
{for each (anObject in A) & (anObject in B) & (anObject in C) // how can I get this right?
{anObject.x -= 100;
}}
}
I am also trying to understand if there is a way to operate all movie clips in my project simultaneously without using arrays.
e.g.
mc_Player.addEventListener(MouseEvent.CLICK, Change_Position);
function Change_Position (event:MouseEvent):void
{
{all movie_clips // how can I get this right?
{anObject.x -= 100;
}}
}
Thank you.
There's no such thing as simultaneous in programming (well, unless you are multi-threading with the perfect sync, which is not an AS3 story at all).
There are to ways to get close to that simultaneous thing:
Put all the objects into a single container. You will be able to change x and y of that container so all the in-laid objects will change their visible positions at once. The downside is that you cannot rotate or scale them individually (think of them as clipped to a board and imagine you rotate the whole board), or you won't be able to move half of them.
Arrays and loops. You iterate through all the items one by one, very fast. It looks simultaneous from the outside, but it never is.
All that said, in order to achieve the things you want you need to figure a way to put all the objects you want to process simultaneously into a single Array and then do the thing you want on them.
Case №1: many Arrays to one.
// This methods takes a mixed list of items and Arrays
// and returns a single flattened list of items.
function flatten(...args:Array):Array
{
var i:int = 0;
// Iterate over the arguments from the first and on.
while (i < args.length)
{
if (args[i] is Array)
{
// These commands cut the reference to the Array
// and put the whole list of its elements instead.
aRay = [i,1].concat(args[i]);
args.splice.apply(args, aRay);
}
else
{
// The element is not an Array so let's just leave it be.
i++;
}
}
return args;
}
Then all you need to do is to get a single list out of your several Arrays:
var ABC:Array = flatten(A, B, C);
for each (var anObject:DisplayObject in ABC)
{
anObject.x -= 100;
}
Performance-wise, it is a good idea to pre-organize, if logically possible, these Arrays so you don't have to compile them each time you need to process all the objects. Simply, if sometimes you would need A + B, and sometimes B + C, and sometimes A + B + C, just create them and have them ready. If you know what you are going to deal with, you won't even need that complicated flatten method:
var AB:Array = A.concat(B);
var BC:Array = B.concat(C);
var ABC:Array = A.concat(B).concat(C);
Case №2: all the children at once. As I already explained in my answer to one of your previous questions, you can iterate over all the children of a certain container, and you can put them into — guess what — Array for later use. Also, you can filter the objects while doing so and put only those ones you actually want to be there.
var ALL:Array = new Array;
// Iterate over the amount of children of "this" container.
for (var i:int = 0; i < numChildren; i++)
{
// Obtain a reference to the child at the depth "i".
var anObject:DisplayObject = getChildAt(i);
// Here go possible criteria for enlisting.
// This will ignore texts and buttons.
// if (anObject is MovieClip)
// This will take only those with names starting with "mc".
if (anObject.name.substr(0, 2) == "mc")
{
ALL.push(anObject);
}
}
// Viola! You have all the objects you want in a single Array
// so you can bulk-process them now, which is ALMOST simultaneous.

Should be easy array situation

My question shouldn't be too difficult but I haven't solved it yet. Basically, what I'm trying to do is to take a message (like this one), preserve each letter in the message, but generate a random message using each letter. So, I can currently read into a textbox (say) "Hello!", but I need to take the message in that textbox and (on the click of a button) have something like "lolH!e". There's got to be a simple way to read each letter into an array (or list, or whatever), and spit them out at random, but while using each letter only once as in the original message. Any thoughts?
In JavaScript you can do something like this:
function randomize(s){
var a = Array.from(s);
for(var j, x, i = a.length; i; j = parseInt(Math.random() * i), x = a[--i], a[i] = a[j], a[j] = x);
return a.join("");
}
Then use it like:
randomize("Hello!")
There are some other good solutions here: How do I shuffle the characters in a string in JavaScript?

Replace input values in arraylist with a custom made class

Replacing userinput with the card index
presented on a new row, and is not replacing the actual number the user typed. I've tried to put the letter and the number in the same arraylist but I have no idea how to display these.
one thing I see you should replace String secondCardLetter = card.getCardLetter(); with String secondCardLetter = deck.getCards(i); otherwise second card is same as first try that and let me know
Also recommend replacing ArrayList<Card> card = new ArrayList<Card>(); with List<Card> cards = new ArrayList<Card>(); please note the variable name change too since its a collection of Card(s). Initialize the deck with a loop
char A = 'A';
int repeats = 2, numOfCards = 8;
for ( int i = 0; i<numOfCards;i++){
for (int j = 0; j<repeats; j++){
cards.add(new Card((char) ( A + i ) + "",i+1,""));
}
}
Please pay attention to your names as the to depict what the method may be doing. You getCards method takes an integer and returns the "Card", where as getCards shouldnt take any parameters and simply return the cards list you have stored. If you want to return a specific card, declare a method called public Card getCard(int i) notice the missing letter s as it shows this will return one card, and on the other hand public List<Card> getCards() method would return a List of cards, then that for loop would work.
If I understand you correctly, what you are looking to do is to keep replacing the characters in the terminal output, without breaking the output into new lines right? i.e: a counter going from 1 to 100?
For that you need to use the carriage return character: '\r'
I think this is the line you are printing the letter of the card right?
System.out.println(format("%10s","\n[ " + firstCardLetter + " ]"));
Try changing this to
System.out.println(format("%10s","\r[ " + firstCardLetter + " ]"));
edit
Sorry what you have to use is the \033[F character, as mentioned here
System.out.println(format("%10s","\033[F[ " + firstCardLetter + " ]"));

AS3 How to split Strings in an Array and put them in an new Array?

You got this list and you want to trace it like this:
"Bim","Bum","Bom","Bam","Bem","Beem","Beeem"
var list: Array = new Array ( "Bim and Bum","Bom, Bam","Bem,Beem and Beeem");
var ordnenList:Array = list.map(
function (item:*,index:int, array:Array):Array{
return (item as String).replace(" und " , ", ").split(", ");
}
);
I began like this, but it doesn't work.
Thanks :-)
It is generally easiest to use a for in loop for these purposes. We can implement the string.replace function, as you have been, and then split the string afterwards.
I'm parking all of this in a function to make it easier.
function breakDownArray(list:Array):Array
{
var newList:Array = []; //Use this array for storing changes, so we don't mess up the for in loop.
for each(var s:String in list) //For each item in array...
{
//We're going to use , as the character to split by in a moment...
s = s.replace(" and ", ","); //Replace the " and " separator with a comma.
//You can keep putting additional search terms in here.
var splitString:Array = s.split(","); //Split string using ",".
newList = newList.concat(splitString); //We combine our newList array with the splitString array.
}
return newList; //Return newList.
}
Barring bugs, here (code untested), output should look like this...
breakDownArray["Bim and Bum","Bom, Bam","Bem,Beem and Beeem"];
//"Bim", "Bum", "Bom", "Bam", "Bem", "Beem", Beeem"
It can be tempting to combine commands into single lines of code, like you originally did, but be aware that you are making bug tracking much harder. There are exceptions, but as a general rule of thumb, one line of code should accomplish one task, two at the most.

AS3 make an array of movieclip moves constantly. (this array constantly increases in size)

ActionScript 3.0
I got this bullet_array.
and it pushes new bullet everytime I pressed spacebar.
There's this "for loop", which works - only when I pressed spacebar.
but I wanted the bullets to constantly move.
the 'for loop' is inside update(), which is from Event.ENTER_FRAME
so technically, the for loop should constantly be looping (i think), but it only went through ONCE, and only after the array increases in size. And it only worked on the new object, and didn't touch the old object.
public function update(evt:Event = null)
{
stage.focus = stage;
//fire = true is set by spacebar
if (fire == true)
{
var snowball:MovieClip = new Snowball;
snowball.x = (mcPlayer.x);
snowball.y = (mcPlayer.y - 5);
snowballArray.push(snowball);
SBAlength = +1; //stands for snowballArray's length
addChild(snowball);
fire = false;
}
for (var i = SBAlength - 1; i >= 0; i--)
{
snowballArray[i].y -= snowballSpd; //snowballSpd is already declared as 5
for (var j = snowmanArray.length - 1; j>=0; j--)
{
for (var k = numberArray.length -1; k>0; k--)
{
if (snowballArray[i].hitTestObject(snowmanArray[j]))
{
if (snowmanArray[j].hitTestObject(numberArray[k]))
{
bosslife -= numberArray[k];
numberArray[k].splice(k,1);
}
snowballArray[i].gotoAndPlay("hit");
snowmanArray[j].splice(j,1);
break;
}
if(numberArray[k] >= 0)
{
numberArray[k].splice(k,1);
randomNo= Math.floor(Math.random()*(max-min+1))+min;
numberArray[k].push(randomNo);
}
snowmanArray[j].txtNumber.text = numberArray[j];
}
}
There may be other issues here, but:
Maintaining the array length
SBAlength = +1; // Sets your length to 1
Instead use:
SBAlength += 1; // Increases your length by 1
But really, you might as well use the array's length property in the loop, instead of maintaining SBALength (and risking it getting out of sync due to some future code):
for (var i = snowballArray.length - 1; i >= 0; i--)
Manipulating arrays
Also (don't think this is related to your problem, but it will certainly cause errors), in your inner loop, you're constantly doing things like this:
snowmanArray[j].splice(j,1);
numberArray[k].push(randomNo);
// etc.
That would only work if the items in numberArray and snowmanArray are themselves arrays - not sure if they are, but doesn't seem like it, since you're also using the items as numbers:
bosslife -= numberArray[k];
The first statement is asking to remove an item from an array stored in snowmanArray[j] - not removing an item from snowmanArray itself. If you want to remove an item from snowmanArray, you'd do snowmanArray.splice(j, 1).
In the same way, to add an item to numberArray, you'd do numberArray.push(randomNo), rather than numberArray[k].push(randomNo).
Manipulating arrays inside loops etc.
It's fine to e.g. remove the current array item while iterating over that array - but only as long as you do it in the way you do, starting from the end and going backwards. However...
After doing (or rather, intending to do) this if the snowman was hit:
snowmanArray.splice(j,1);
... you're later doing:
snowmanArray[j].txtNumber.text = numberArray[j];
I.e. you remove the snowman from the array, but then later on, you try to get the array item you just removed. You need to be sure that snowmanArray[j] still exists before you address it.
Array item types
You're mostly using numberArray as an array of int (or Number). Except here:
snowmanArray[j].hitTestObject(numberArray[k])
You can't hitTestObject against an int/Number. Not sure what the line is supposed to do, but the object you hit test against needs to be a DisplayObject (e.g. a MovieClip).
Erm... after lots of tracing around and stuff,
i figure that the main problem isn't with the array nor the splicing (though my codes is wrong -but it didn't work even if i commented away those codes), but that i place > instead of < to check bosslife, so it keep resetting the level, so snowballArray keeps becoming a new Array, hence the array.length didn't work, and using SBAlength gives some kinda weird error while inside the for loop.

Resources