as3 change from random element in array to next element - arrays

I have an array of skin tone hex codes. At the moment, when I click a button, it randomly gets an element from the array. I'd like it to just get the next available element and if there are no more, loop back to the 1st element. Here's what I have at the moment.
var skinTones:Array = ["0xebae7f","0x754c24","0xf2ca8d","0xf4d1b7","0x8b6947"];
And the button code:
menuMC.buttFace.addEventListener(MouseEvent.CLICK, clickFace);
function clickFace(event:MouseEvent): void
{
function getSkinTone(source, amount) {
var i = Math.round(Math.random() * (source.length - 1)); //random seed (starting point)
var myTone = new Array(); //the new array
while(myTone.length < amount){
if (i >= source.length) i = 0; //if the current iterator if out of bounds, reset to 0
myTone.push(source[i]);
i++;
}
return myTone;
}
var toneHex = getSkinTone(skinTones,1);
trace(toneHex);
TweenLite.to(faceWrapperMC.faceMC, 0.5, {colorTransform:{tint:toneHex, tintAmount:1}});
TweenLite.to(faceWrapperMC.earsMC, 0.5, {colorTransform:{tint:toneHex, tintAmount:1}});
TweenLite.to(faceWrapperMC.eyesMC.eyes.eyelid, 0.5, {colorTransform:{tint:toneHex, tintAmount:1}});
}
Any help would be great. Also, if it can be simplified, please let me know. This is my 1st AS3 project.

This will take the passed array, and return a new array with a random seed (starting element) and keep the rest of the order the same. I renamed the parameters to better clarify what I interpreted them to be.
function getSkinTone(source:Array,amount:int):Array {
var i:int = Math.round(Math.random() * (source.length - 1)); //random seed (starting point)
var myTone:Array = new Array(); //the new array
while(myTone.length < amount){
if (i >= source.length) i = 0; //if the current iterator if out of bounds, reset to 0
myTone.push(source[i]);
i++;
}
return myTone;
}
EDIT
After some comments, I believe this is what you'd like to do:
var skinTones:Array = ["0xebae7f","0x754c24","0xf2ca8d","0xf4d1b7","0x8b6947"]; //these can be stored as uint instead of strings since TweenLite will just convert them to uint anyway
var skinToneIndex:int = -1; //a global var to hold the current index - starting as -1 to indicate it hasn't been set yet.
function getNextSkinTone():String {
if(skinToneIndex == -1) skinToneIndex = Math.round(Math.random() * (skinTones.length - 1)); //if not set, make it a random starting number
skinToneIndex++; //increment it
if(skinToneIndex >= skinTones.length) skinToneIndex = 0; //if out of bounds reset to 0;
return skinTones[skinToneIndex];
}
menuMC.buttFace.addEventListener(MouseEvent.CLICK, clickFace);
function clickFace(event:MouseEvent): void {
var toneHex:uint = getNextSkinTone();
trace(toneHex);
TweenLite.to(faceWrapperMC.faceMC, 0.5, {colorTransform:{tint:toneHex, tintAmount:1}});
TweenLite.to(faceWrapperMC.earsMC, 0.5, {colorTransform:{tint:toneHex, tintAmount:1}});
TweenLite.to(faceWrapperMC.eyesMC.eyes.eyelid, 0.5, {colorTransform:{tint:toneHex, tintAmount:1}});
}

Related

What are the methods to trace an array to the following criteria?

The array:
var numberArray:Array= new Array(34,53,2,3,34,26,26,85,3,4,98,2,12);
How do I trace it so the output-panel will show every other item: "34,2,34,26,3,98,12"
How do I trace the numbers that have a lower value than 10
How do I trace the even numbers in the array?
For the reference and general education: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Vector.html#map()
// You can init Arrays with [] operator.
var numberArray:Array = [34,53,2,3,34,26,26,85,3,4,98,2,12];
trace(filter(numberArray, evenIndices));
trace(filter(numberArray, belowTen));
trace(filter(numberArray, evenValues));
// In AS3 you can pass method references as function arguments.
// That allows to compose a filtering method, just like Vector.map(...)
// This method will filter the original array
// by the given criteria and return the filtered result.
// Criteria method must accept 2 arguments: element index and value.
function filter(source:Array, criteria:Function):Array
{
var result:Array = new Array;
for (var i:int = 0; i < source.length; i++)
if (criteria(i, source[i]))
result.push(source[i]);
return result;
}
// Returns true if index is an even number.
function evenIndices(index:int, value:int):Boolean
{
return index % 2 == 0;
}
// Returns true if value is less than 10.
function belowTen(index:int, value:int):Boolean
{
return value < 10;
}
// Returns true if value is an even number.
function evenValues(index:int, value:int):Boolean
{
return value % 2 == 0;
}
var numberArray:Array = [34, 53, 2, 3, 34, 26, 26, 85];
1.How do I trace it so the output-panel will show every-other item: "34,2,34,26,3,98,12"
getEventIndexiesOfArray(numberArray);
2.How do I trace the numbers that have a lower value than 10
lenghtLessthanTen(numberArray);
3.How do I trace the even numbers in the array?
checkArrayHasEventLenght(numberArray);
1. getEventIndexiesOfArray() method for get event indexies elements from array.
private function getEventIndexiesOfArray(source:Array):void
{
var resultArr:Array = [];
for (var i:int = 0; i < source.length; i++)
{
if (i % 2 == 0)
resultArr.push(source[i]);
}
trace("Even Indexies Array : " + resultArr.toString());
}
2. lenghtLessthanTen() method for check that array lenght is lessthan 10 or not.
private function lenghtLessthanTen(source:Array):void
{
if (source.length < 10)
trace("Array containt lessthan Ten elements");
}
3. checkArrayHasEventLenght() method check that array containt even lenght or not.
private function checkArrayHasEventLenght(source:Array):void
{
if (source.length % 2 == 0)
trace("Array has even number of elenter code hereements");
}

Have object rotate another object in array?

Hey everyone so I have an object character that initially rotates around the first Movie Clip called planet which isn't apart of the array. So the user can tap the screen and the character shoots in direction it is rotating. The objective is to have the character hit the other planets in a array and when it does have it start rotating around it just like the original. Everything works fine except when I shoot the character and it lands on one of the outerplanets in aPlanetArray it doesn't start rotating around that new planet but rather just disappears.
Here is how I set it up:
character Orbits first planet that is not in the array just have it as intial orbit then remove it once leaves to other outerPlanets:
private function startOrbit():void
{
//add Planet
planet.x = (stage.stageWidth / 2);
planet.y = (stage.stageHeight / 2) + 100;
stage.addChild(planet);
//radnom number set up in main class
if (randomOrbit == 1) //If equals to one then clock wise
{
clockWiseOrbiter();
}else
if (randomOrbit == 2) //If equals to one then counter clock wise
{
counterClockWiseOrbiter();
}
}
I add outer Planets in array:
private function addOuterPlanets():void
{
for (var i:int = 0; i < nPlanets; i++)
{
outerPlanets = new mcOuterPlanets();
outerPlanets.x = startPoint.x + (xSpacing * i);
outerPlanets.y = startPoint.y - (ySpacing * i);
stage.addChild(outerPlanets);
aPlanetArray.push(outerPlanets);
}
}
In my Enter Frame Handler:
private function logicHandler(e:Event):void
{
if (!tap && !nextlevel)
{
startOrbit(); //start player orbit around planet
}
if (nextlevel)
{
startNewOrbit();
trace("Starting new Orbit");
}
//When tapped have outher planets move down
if (tap)
{
characterTap(); //Character shoots from position
}
collisionPlanetHandler();
}
When the collision happens with Outer Planets:
**** EDIT*****
private function collisionPlanetHandler():void
{
for (var i:int = 0; i < aPlanetArray.length; i++)
{
var currentPlanet:mcOuterPlanets = aPlanetArray[i];
if (character.hitTestObject(currentPlanet[i]) && !nextlevel)
{
trace("HIT");
//Have charcter orbit that planet
//startNewOrbit();
//tap back to false
tap = false;
nextlevel = true;
character.destroy();
planet.destroy();
planetHit = currentPlanet[i];
}
}
}
When the character collides with the outerPlanets in array I have the New orbit happen around the OuterPlanet it lands on. Or I at least try:
private function startNewOrbit():void
{
newClockWise();
}
private function newClockWise():void
{
for (var i:int = 0; i < aPlanetArray.length; i++)
{
var currentPlanet:mcOuterPlanets = aPlanetArray[i];
stage.addChild(character);
character.rotation = (Math.atan2(character.y - currentPlanet.y, character.x - currentPlanet.x) * 180 / Math.PI);
var rad:Number = angle * (Math.PI / 180); // Converting Degrees To Radians
character.x = currentPlanet.x + radius * Math.cos(rad); // Position The Orbiter Along x-axis
character.y = currentPlanet.y + radius * Math.sin(rad); // Position The Orbiter Along y-axis
angle += speed; // Object will orbit clockwise
}
}
I know I am doing something wrong in the startNewOrbit and newClockWise functions. I have a for loop and I am trying to target the object in array it touches. I use this var currentPlanet:mcOuterPlanets = aPlanetArray[i]; But not sure if I need to use currentObject or something equivalent. Does anyone have any idea what i am doing wrong why its not orbiting the new planet it touches but rather just disappears completely?
var planetHit:MovieClip;
function collisionTest():void{
for (loop through planets){
if (planet[i].hitTestObject(character)){
planetHit = planet[i];
}
}
}
See now the planet at that location in the array is (==) planetHit so then you can do
character.x = planetHit.x;
or
planetHit.addChild(character);
etc.

Detecting and using collision detection between two different arrays to remove instances of them

I'm currently creating a small flash game using ActionScript and after receiving help for another issue I had on here, I've encountered another one when moving onto a different part of it.
This is the code I currently have:
var asteroidSpeed = 5;
var soundExplosion:Sound = new ExplosionSound();
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKDown);
var newLaser:Array = new Array();
function onKDown(e:KeyboardEvent):void {
keys[e.keyCode] = true;
if (e.keyCode == 32) {
/*laser.x = player.x + player.width/2 - laser.width/2;
laser.y = player.y;
addChild(laser);*/
for (var count=0; count < 4; count++) {
newLaser[count] = new shipLaser();
newLaser[count].x = player.x + player.width/2 - newLaser.width/2;
newLaser[count].y = player.y;
addChild(newLaser[count]);
}
}
}
var spawnTimer:Timer = new Timer(3000); //timer will tick every 3 seconds
spawnTimer.addEventListener(TimerEvent.TIMER, spawn, false, 0, true); //let's run the spawn function every timer tick
spawnTimer.start();
var spawnPoints:Array = [0,100,200,300,400,500,550]; //your list of spawn x locations
var spawnAmount:int = 4; //how many asteroids to have on the screen at once (you could increase this over time to make it more difficult)
var asteroids:Vector.<asteroidOne> = new Vector.<asteroidOne>(); //the array for your asteroids - changed to vector for possible performance and code hint improvement (basically the same as Array but every object has to be of the specified type)
spawn(); // calling it immediately
//calling this will spawn as many new asteroids as are needed to reach the given amount
function spawn(e:Event = null):void {
if(asteroids.length >= spawnAmount) return; //let's not bother running any of the code below if no new asteroids are needed
spawnPoints.sort(randomizeArray); //lets randomize the spwanPoints
var spawnIndex:int = 0;
var a:asteroidOne; //var to hold the asteroid every loop
while (asteroids.length < spawnAmount) {
a = new asteroidOne();
a.x = spawnPoints[spawnIndex];
spawnIndex++; //incriment the spawn index
if (spawnIndex >= spawnPoints.length) spawnIndex = 0; //if the index is out of range of the amount of items in the array, go back to the start
a.y = -50;
asteroids.push(a); //add it to the array/vector
addChild(a); //add it to the display
}
}
player.addEventListener(Event.ENTER_FRAME, obstacleMove);
function obstacleMove(evt:Event):void {
for (var i:int = 0; i < asteroids.length;i++) {
asteroids[i].y += asteroidSpeed;
if (asteroids[i].y > stage.stageHeight || asteroids[i].x > stage.stageWidth || asteroids[i].x < -asteroids[i].width || asteroids[i].y < -asteroids[i].height) {
//object is out of the bounds of the stage, let's remove it
removeChild(asteroids[i]); //remove it from the display
asteroids.splice(i, 1); //remove it from the array/vector
continue; //move on to the next iteration in the for loop
}
if (player.hitTestObject(asteroids[i])) {
trace("HIT");
removeChild(asteroids[i]);
asteroids.splice(i,1);
removeChild(player);
// will add end-game trigger here soon.
}
}
}
function randomizeArray(a:*, b:*):int {
return (Math.random() < .5 ) ? 1 : -1;
}
player.addEventListener(Event.ENTER_FRAME, laserCollision);
function laserCollision(evt:Event):void {
for (var i in newLaser) {
for (var a in asteroids) {
if (asteroids[a].hitTestObject(newLaser[i])) {
trace("BOOM!");
var soundExplosion:Sound = new ExplosionSound();
var channel1:SoundChannel = soundExplosion.play();
removeChild(newLaser[i]);
removeChild(asteroids[a]);
}
}
}
}
addEventListener(Event.ENTER_FRAME, laserEnter);
function laserEnter(event:Event):void {
for (var i in newLaser) {
newLaser[i].y -= laserSpeed;
// Moves the laser up the screen
if(newLaser[i].y == 0) {
removeChild(newLaser[i]);
}
}
}
What I want to do is when an instance from the newLaser array collides with an instance of the asteroids array, to remove both from the scene / indexes (but only the two that collided and not all of the ones on the scene).
Currently, when a laser hits an asteroid, it removes the asteroid but not the laser and one of the asteroids on the current row stops moving and then the next row of asteroids spawns but does not move down.
I get this error too:
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at _8_fla::MainTimeline/obstacleMove()
Any help would be greatly appreciated.
You error, is likely because you are running 3 separate enter frame handlers in the same scope, and removing items from arrays and display lists (that are referenced in multiple enter frame handlers). So you asteroid is removed from the display list in one, and then you try to remove it again in another.
There are also a whole lot of other issues with your code that will cause errors and undesired results. Things like for(var i in newLasers) - in that kind of loop, i will refer to the actual laser object not the index of the array. I've re-factored your code and added lots of code comments to hopefully give you an idea of where you were going wrong:
var spawnTimer:Timer = new Timer(3000); //timer will tick every 3 seconds
var spawnPoints:Array = [0, 100, 200, 300, 400, 500, 550]; //your list of spawn x locations
var spawnAmount:int = 4; //how many asteroids to have on the screen at once (you could increase this over time to make it more difficult)
var asteroidSpeed = 5;
var asteroids:Vector.<asteroidOne> = new Vector.<asteroidOne>(); //the array for your asteroids - changed to vector for possible performance and code hint improvement (basically the same as Array but every object has to be of the specified type)
var lasers:Vector.<shipLaser> = new shipLaser(); //the array of lasers
var maxLasers:int = 4; //the maximum amount lasers allowed at any given time
var soundExplosion:Sound = new ExplosionSound();
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKDown);
player.addEventListener(Event.ENTER_FRAME, gameLoop);
spawnTimer.addEventListener(TimerEvent.TIMER, spawn, false, 0, true); //let's run the spawn function every timer tick
spawnTimer.start(); //start the spawn timer
spawn(); // calling it immediately
function onKDown(e:KeyboardEvent):void{
if (e.keyCode == 32) {
//create ONE laser per button push (instead of 4 identical lasers)
if(lasers.length < maxLasers){ //if player hasn't reached the maximum amount of lasers available
var tmpLaser:shipLaser = new shipLaser();
tmpLaser.x = player.x + player.width / 2 - tmpLaser.width / 2;
tmpLaser.y = player.y;
addChild(tmpLaser);
lasers.push(tmpLaser);
}
}
}
//calling this will spawn as many new asteroids as are needed to reach the given amount
function spawn(e:Event = null):void {
if (asteroids.length >= spawnAmount)
return; //let's not bother running any of the code below if no new asteroids are needed
spawnPoints.sort(randomizeArray); //lets randomize the spwanPoints
var spawnIndex:int = 0;
var a:asteroidOne; //var to hold the asteroid every loop
while (asteroids.length < spawnAmount)
{
a = new asteroidOne();
a.x = spawnPoints[spawnIndex];
spawnIndex++; //incriment the spawn index
if (spawnIndex >= spawnPoints.length)
spawnIndex = 0; //if the index is out of range of the amount of items in the array, go back to the start
a.y = -50;
asteroids.push(a); //add it to the array/vector
addChild(a); //add it to the display
}
}
function gameLoop(e:Event):void {
//LOOP through all the asteroids, give it a label (asteroidLoop) so we can break/continue it inside other loops
asteroidLoop: for (var i:int = 0; i < asteroids.length; i++) {
//check if asteroid is out of bounds
if (asteroids[i].y > stage.stageHeight || asteroids[i].x > stage.stageWidth || asteroids[i].x < -asteroids[i].width || asteroids[i].y < -asteroids[i].height) {
//object is out of the bounds of the stage, let's remove it
removeChild(asteroids[i]); //remove it from the display
asteroids.splice(i, 1); //remove it from the array/vector
continue; //forget the rest of the code below and move on to the next iteration in the for loop since the asteroid is gone
}
//check if any lasers are colliding with this asteroid
for (var j:int = lasers.length-1; j >= 0;j--) { //iterate over all lasers backwards
if (asteroids[i].hitTestObject(lasers[j])){
trace("BOOM!");
var soundExplosion:Sound = new ExplosionSound();
var channel1:SoundChannel = soundExplosion.play();
//remove the asteroid
removeChild(asteroids[i]); //remove it from the display
asteroids.splice(i, 1); //remove it from the array/vector
//remove the laser
removeChild(lasers[j]);
lasers.splice(j, 1);
continue asteroidLoop; //break completely out of this inner for-loop (lasers) since the asteroid in the outer loop was removed, and move on to the next asteroid
}
}
//check if this asteroid collides with the player
if (player.hitTestObject(asteroids[i])){
trace("HIT");
//remove the asteroid
removeChild(asteroids[i]); //remove it from the display
asteroids.splice(i, 1); //remove it from the array/vector
removeChild(player);
spawnTimer.stop(); //stop spawning new asteroids
//will add end-game trigger here soon.
break; //break completely out of the asteroid loop if it's game over (as there's no point in checking the rest of the asteroids)
}
//we've made it this far, so let's just move this asteroid
asteroids[i].y += asteroidSpeed;
}
for (var i:int = lasers.length-1; i >= 0;i--) { //iterate backwards
lasers[i].y -= laserSpeed;
// Moves the laser up the screen
if (lasers[i].y <= 0){ //make this less than or equal to 0
removeChild(lasers[i]); //remove the laser from the display list
lasers.splice(i, 1); //remove the laser from the array
}
}
}
function randomizeArray(a:*, b:*):int {
return (Math.random() < .5) ? 1 : -1;
}

Storing multiple numbers in an array (As3)

private var hitArray:Array = new Array [ 10, 20, 30, 40, 50, 60];
Hello.
I have stored multiple numbers in an array and it appears flash does not like this, I am guessing that I am telling the array that it will either have 10 spaces, 20 spaces, etc...or the array needs to understand what variable it is datatyped to.
so my next idea was to store a hundred numbers into the array by using this
private var hitArray:Array = new Array;
public function Main()
{
for (var i:int = 0; 0 < 100; i++)
{
hitArray.push(i);
}
//iniaite health
hitCounter = 0;
resetPos = new Point(x, y);
//iniation players
_character = new player();
timmy = new SirTimmy();
caroline = new princess();
goblinCanMove = true;
stage.addEventListener(Event.ENTER_FRAME, mainGameLoop)
}
By doing this, I would be able to achieve a greater method of hitTestPoint!
private function enemyCollisionGoblin():void
{
//trace(aKnifeArray.length);
//knive proccess
for (var o:int = 0; o < aKnifeArray.length; o++)
{
var currentKnife:Knife= aKnifeArray[o];
if (currentKnife.x < 0)
{
//trace ('backmissile gone lol');
aKnifeArray.splice(o, 1);
currentKnife.removeKnife();
}
//if (_character.x < redGoblin.x && _character.x > redGoblin.x - 600)
for (var p:int = 0; p < hitArray.length; p++)
{
var number:Number = hitArray[p];
if (currentKnife.hitTestPoint(_character.x + number, _character.y - number, true)) //|| currentKnife.hitTestPoint(_character.x - 50, _character.y - 60, true))
{
trace("hit");
}
}
}
}
The problem I am facing is that flash does not like the for loop in the main constructor, despite it being initiated one.
It should break out of the for Loop if variable i is more than 100, but does not.
My question it, how can I store numbers in an array, so I can use that array in my hit Test Point.
Sorry, I know this is simple, but I'm currently developing and learning!
Advice will be appreciate very much!
You're getting an infinite loop because your loop condition is 0 < 100 instead of i < 100.
for (var i:int = 0; 0 < 100; i++)
Your first method of initializing an array is incorrect. It should instead be
private var hitArray:Array = new Array (10, 20, 30, 40, 50, 60);
You got the brackets wrong. You have to be careful when creating arrays using the Array constructor because:
var awd:Array = new Array (10);
The above will create an empty array with a capacity of 10.
var awd:Array = [10];
The above will create an array with a single element of the number 10. This is usually the way to create an array because it's quick and easy.
var awd:Array = [10, 1, 2, 3, 4, 5];

as3 random array - randomize array - actionscript 3

How do you randomize an array using actionscript 3?
There is a short version using Array.sort() function:
var arr : Array = [0,1,2,3,4,5,6,7,8,9];
function randomize ( a : *, b : * ) : int {
return ( Math.random() > .5 ) ? 1 : -1;
}
trace( arr.sort( randomize ) );
If you don't get "enough" randomness you can sort twice :)
EDIT - explanation line by line:
For Array class method sort() you can pass not only sort options like Array.CASEINSENSITIVE, Array.DESCENDING and so on but also your own custom compare function reference (a callback) that accepts two parameters (two elements from array to compare). From AS3 documentation:
A comparison function should take two arguments to compare. Given the elements A and B, the result of compareFunction can have a negative, 0, or positive value:
A negative return value specifies that A appears before B in the sorted sequence.
A return value of 0 specifies that A and B have the same sort order.
A positive return value specifies that A appears after B in the sorted sequence.
Note: compare function parameters might be typed (if your array is typed) and have any name you want eg.:
function compareElements ( elementA : SomeClass, elementB : SomeClass ) : int;
This method is very useful when you need to sort array elements by their special properties. In randomization case compareFunction randomly returns -1, 0 or 1 and makes array elements to switch their places (indices). I have found that better randomization (in my subjective and mathematically untested opinion) is when method returns only -1 and 1. Also have in mind that sorting function with custom compare function doesn't compare elements sequentially so in some special cases randomization results may differ from what you might expect.
There's a better way that will also allow you to randomize the array in place, if you need that, and it will not make you create more then a single copy of your original array.
package
{
import flash.display.Sprite;
public class RandomizeArrayExample extends Sprite
{
public function RandomizeArrayExample()
{
super();
testDistribution();
}
private function testDistribution():void
{
var hash:Object = { };
var tester:Array = [1, 2, 3, 4];
var key:String;
for (var i:int; i < 1e5; i++)
{
randomize(tester);
key = tester.join("");
if (key in hash) hash[key]++;
else hash[key] = 1;
}
for (var p:String in hash) trace(p, "=>", hash[p]);
}
private function randomize(array:Array):Array
{
var temp:Object;
var tempOffset:int;
for (var i:int = array.length - 1; i >= 0; i--)
{
tempOffset = Math.random() * i;
temp = array[i];
array[i] = array[tempOffset];
array[tempOffset] = temp;
}
return array;
}
}
}
I had an alternative requirement where i wanted to randomly insert lots of source arrays into a target array randomly. Like Rytis i'm a big fan of the forEach, map and sort functions on Arrays.
var randomInsert:Function = function callback(item:*, index:int, array:Vector.<MyItem>):void
{
var j:Number = Math.floor(Math.random() * targetArray.length);
targetArray.splice(j,0,item);
}
targetArray = new Vector.<MyItem>();
sourceArray1.forEach(randomInsert, this);
sourceArray2.forEach(randomInsert, this);
here's an easier function. Works also on multidimensional arrays
function randomizeArray(array:Array):Array
{
var newArray:Array = new Array();
while (array.length > 0)
{
var mn=Math.floor(Math.random()*array.length)
newArray[newArray.length]=array[mn]
array.splice(mn,1)
}
return newArray;
}
I found this very helpful. I hope it can help you too.
// Array to Randomize
var firstArray:Array = ["One","Two","Three","Four","Five","six","seven","eight","nine","ten"];
trace(firstArray); // Prints in order
var newArray:Array = new Array();
function randomizeArray(array:Array):Array
{
var newArray:Array = new Array();
while (array.length > 0)
{
newArray.push(array.splice(Math.floor(Math.random()*array.length), 1));
}
return newArray;
}
var randomArray:Array = randomizeArray(firstArray);
trace(randomArray); // Prints out randomized :)
If you need your array to be shuffled (your elements can not repeat). You could use this function:
/**
* Shuffles array into new array with no repeating elements. Simple swap algorithm is used.
*/
public function shuffleArray(original:Array):Array
{
// How many swaps we will do
// Increase this number for better results (more shuffled array, but slower performance)
const runs:int = original.length * 3;
var shuffled:Array = new Array(original.length);
var i:int;
var a:int;
var b:int;
var temp:Object;
// Copy original array to shuffled
for(i=0; i<shuffled.length; i++){
shuffled[i] = original[i];
}
// Run random swap cycle 'runs' times
for(i=0; i<runs; i++){
// There is a chance that array element will swap with itself,
// and there is always small probability it will make your shuffle
// results not that good, hence try to experiment with
// different runs count as stated above
a = Math.floor(Math.random() * original.length);
b = Math.floor(Math.random() * original.length);
// Swap messages
temp = shuffled[a];
shuffled[a] = shuffled[b];
shuffled[b] = temp;
}
return shuffled;
}
Usage:
var testArray:Array = ["Water", "Fire", "Air", "Earth"];
trace(shuffleArray(testArray).concat());
this is how I randomize my array of 36 cards for a memory game
const QUANT_CARTAS: int = 36;
//get the 36 numbers into the array
for (var i: int = 0; i < QUANT_CARTAS; i++)
{
cartas.push(i);
}
//shuffles them =)
for (var moeda: int = QUANT_CARTAS - 1; moeda > 0; moeda--)
{
var pos: int = Math.floor(Math.random() * moeda);
var carta: int = cartas[moeda];
cartas[moeda] = cartas[pos];
cartas[pos] = carta;
}
// and add them using the random order...
for (i = 0; i < QUANT_CARTAS; i++)
{
var novaCarta: Carta = new Carta();
novaCarta.tipoCarta = cartas[i];
etcetcetc.............
}
choose random string from array
function keyGenerator(len:Number):String
{
function randomRange(minNum:Number, maxNum:Number):Number
{
return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);
}
var hexArray = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'];
var key = "";
for (var i=0; i<len; i++)
{
key += hexArray[randomRange(0,hexArray.length-1)];
}
return key;
}
usage:
trace(keyGenerator(16));

Resources