Make movieclips appear randomly in AS3 - actionscript-3

Right now I have six mice places in spesific places on the stage. These mice move based on adjustments made on the timeline inside the movieclip itself. What I aim to do is to start these six movieclips randomly based on a timer. This task im currently struggeling with..
Here is my code;
var clipArray:Array = new Array();
clipArray[0] = musx0_mc;
clipArray[1] = musx1_mc;
clipArray[2] = musx2_mc;
clipArray[3] = musx3_mc;
clipArray[4] = musx4_mc;
clipArray[5] = musx5_mc;
var i:int = 0;
var musTimer:Timer = new Timer(100);
musTimer.addEventListener(TimerEvent.TIMER, playMus);
function playMus(event:TimerEvent):void
{
for(i=0; i<clipArray.length; i++)
{
var randomMus:Number = Math.floor(Math.random()*100);
clipArray[randomMus].play();
}
}
musTimer.start();

It seems that you want to get 0 to 5 random number.
//var randomMus:Number = Math.floor(Math.random()*100); // returns 0 to 99
var randomMus:int = Math.floor(Math.random()*6); // returns 0 to 5
Maybe this code works.
var clipArray:Array = new Array();
clipArray[0] = musx0_mc;
clipArray[1] = musx1_mc;
clipArray[2] = musx2_mc;
clipArray[3] = musx3_mc;
clipArray[4] = musx4_mc;
clipArray[5] = musx5_mc;
var musTimer:Timer = new Timer(100);
musTimer.addEventListener(TimerEvent.TIMER, playMus);
function playMus(event:TimerEvent):void
{
//for(i=0; i<clipArray.length; i++) // What is this loop??
//{
//var randomMus:Number = Math.floor(Math.random()*100);
var randomMus:int = Math.floor(Math.random()*6);
clipArray[randomMus].play();
//}
}
musTimer.start();

Related

Randomising array coordinates with no duplicates AS3

very new to this kind of thing so please bear with me.
So basically I have 4 buttons that I have put to the stage using the Actions panel. They all have set coordinates so every time I run my game, they are in the same place.
Now here's my issue, I want these buttons to randomise their positions using those coordinates, but I often get duplicates, meaning one button is on top of another.
Here is my code so far
var coordArray : Array = [
new Point(44,420),
new Point(270,420),
new Point(44,550),
new Point(270,550),
];
var pointRange:Number = 4;
var randomPoint:int = Math.random()*pointRange;
answerButtons.x = coordArray[randomPoint].x;
answerButtons.y = coordArray[randomPoint].y;
var pointRange_2:Number = 4;
var randomPoint_2:int = Math.random()*pointRange_2;
answerButtons_2.x = coordArray[randomPoint_2].x;
answerButtons_2.y = coordArray[randomPoint_2].y;
var pointRange_3:Number = 4;
var randomPoint_3:int = Math.random()*pointRange_3;
answerButtons_3.x = coordArray[randomPoint_3].x;
answerButtons_3.y = coordArray[randomPoint_3].y;
var pointRange_4:Number = 4;
var randomPoint_4:int = Math.random()*pointRange_4;
answerButtons_4.x = coordArray[randomPoint_4].x;
answerButtons_4.y = coordArray[randomPoint_4].y;
I have googled this profusely and I keep getting answers to do with the splice and shift methods. Is this the type of thing I need? I'm assuming I need a function that removes a point from the array after it is used.
Cheers.
Just remove the coordinate from the list when you pick it randomly using splice:
var coordinates:Vector.<Point> = new <Point>[
new Point(44, 420),
new Point(270, 420),
new Point(44, 550),
new Point(270, 550)
];
function positionAtRandomCoordinate(object:DisplayObject):void {
var index:int = Math.random() * coordinates.length;
var coordinate:Point = coordinates.splice(index, 1)[0];
object.x = coordinate.x;
object.y = coordinate.y;
}
positionAtRandomCoordinate(answerButtons);
positionAtRandomCoordinate(answerButtons_2);
positionAtRandomCoordinate(answerButtons_3);
positionAtRandomCoordinate(answerButtons_4);

Dynamically adding a 3 tier movieclip to stage then populate it

What I am trying to do is add say 20 jpgs labelled 1-20 individually inside movieClips [ sReel ] , then add the movieClips to movieClip [ aReel ] and duplicate movieClip [ aReel ] into movieClip [ mReel ] so I can have a horizontal scrolling movieClip.
I can do all manually no problem but doing it automatically is not so easy :(
Just need how to stack the mocieClips correctly as know how to do rest oc code Thanks..
var movie_Number:Array = new Array();
var movie_Title: Array = new Array();
var movie_Director: Array = new Array();
var movie_Star: Array = new Array();
var movie_Duration: Array = new Array();
var movie_Genre: Array = new Array();
var movie_Year: Array = new Array();
var movie_Rating: Array = new Array();
var movie_Comment: Array = new Array();
var mReel:MovieClip = new MovieClip;
var aReel:MovieClip = new MovieClip;
var bReel:MovieClip = new MovieClip;
var sReel:MovieClip = new MovieClip;
var ldr:Loader;
newReelMask.cacheAsBitmap = true;
mReel.cacheAsBitmap = true;
mReel.mask = newReelMask;
var xmlLoader:URLLoader = new URLLoader(), xmlData:XML;
var movieNum:Number;
var xReel = 0;
mReel.addEventListener(MouseEvent.MOUSE_OVER, onStop);
mReel.addEventListener(MouseEvent.MOUSE_OUT, onStart);
var myTimer:Timer = new Timer(1);
myTimer.addEventListener(TimerEvent.TIMER, timerListener);
myTimer.start();
init();
makeSmallReel();
aReel.x = 0;
aReel.y = 0;
mReel.addChild(aReel);
addChild(mReel);
function init():void
{
xmlLoader.addEventListener(Event.COMPLETE, LoadXML);
xmlLoader.load(new URLRequest("movieInfo.xml"));
}
function LoadXML(e:Event):void
{
xmlData = new XML(e.target.data);
var movieTitle:XMLList = xmlData..title;
var movieDirector:XMLList = xmlData..director;
var movieStar:XMLList = xmlData..star;
var movieDuration:XMLList = xmlData..duration;
var movieGenre:XMLList = xmlData..genre;
var movieYear:XMLList = xmlData..year;
var movieRating:XMLList = xmlData..rating;
var movieComment:XMLList = xmlData..comment;
var len: int = xmlData.movie.length();
var i:int = 0;
for (i; i < len; i++)
{
movie_Number.push(i);
movie_Title.push(movieTitle[i]);
movie_Director.push(movieDirector[i]);
movie_Star.push(movieStar[i]);
movie_Duration.push(movieDuration[i]);
movie_Genre.push(movieGenre[i]);
movie_Year.push(movieYear[i]);
movie_Rating.push(movieRating[i]);
movie_Comment.push(movieComment[i]);
}
}
function makeSmallReel():void
{
var i:int = 1;
for (i; i < 11; i++)
{
ldr = new Loader();
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, ldr_complete);
ldr.load(new URLRequest("images/thumb/"+i+".jpg"));
}
}
function ldr_complete(e:Event):void
{
sReel.x = xReel;
sReel.addChild(ldr);
xReel = xReel + e.target.width;
aReel.addChild(sReel);
}
function timerListener(e:TimerEvent):void
{
if (mReel.x <= -(aReel.width))
{
mReel.x = 0;
}
mReel.x -= 1;
}
function onStop(e:MouseEvent):void
{
myTimer.stop();
}
function onStart(e:MouseEvent):void
{
myTimer.start();
}
You 're adding always the same loader(ldr is a class-var) to your container.
At loading you have to create a ldr vor each picture. And add this to your container in your complete-handler. (it's e.target in your complete-handler)
BTW: You don't need a MovieCLip. A Sprite is enought, 'cause semms, you never need the timeline of a movieclip, which is the difference between MovieClip and Sprite ( and the overhead).

AS3 Adobe AIR: Return xml string

I'm working in Flash CS6 with Adobe AIR 3.3 (for iOS) and having trouble returning an XML string to a textField.
It is tracing the proper information, and I've tried a few ways to return the trace but can't seem to quite get it... Here is my most recent try. Any suggestions? Thanks in advance.
var myLoader:URLLoader = new URLLoader();
myLoader.load(new URLRequest("http://www.someURL.php"));
//php file that echos xml
myLoader.addEventListener(Event.COMPLETE, init);
var fadedText:TextField;
var touchList:TouchList;
var textOutput:TextField;
var animateLeft:Tween;
var listArray:Array;
var item:TouchListItemRenderer;
var theXML:XML;
var days:Array = new Array("monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday");
var daySelected;
var businessNameArray:Array = new Array();
var businessLogoArray:Array = new Array();
var businessAddress:Array = new Array();
var distanceArrayDisplay:Array = new Array();
var distanceArrayCount = 0;
function init(e:Event = null):void
{
trace(myLoader.data);
theXML = new XML(e.target.data);
theXML.ignoreWhitespace = true;
myLoader.close();
// add our list and listener
var itemSizeCalculator = stage.stageHeight / 6;
touchList = new TouchList(stage.stageWidth, stage.stageHeight-itemSizeCalculator);
touchList.addEventListener(ListItemEvent.ITEM_SELECTED, handlelistItemSelected);
addChild(touchList);
touchList.x = stage.stageWidth;
// Fill our list with item rendreres that extend ITouchListRenderer.
for(var i:int = 0; i < theXML.food.length(); i++) {
if(theXML.food[i].monday != "un")
{
item = new TouchListItemRenderer();
item.index = i;
item.data = theXML.food[i].business;
item.name = theXML.food[i].business;
item.addEventListener(MouseEvent.CLICK, itemWasClicked);
item.itemHeight = itemSizeCalculator;
businessNameArray[i]= theXML.food[i].business;
businessLogoArray[i]=("http://www.logosURL.com/"+theXML.food[i].logo);
businessAddress[i]= theXML.food[i].address;
var fadedTextFormat:TextFormat = new TextFormat();
fadedTextFormat.bold = true;
fadedTextFormat.color = 0x999999;
fadedTextFormat.size = 14;
fadedTextFormat.font = "Helvetica";
fadedText = new TextField();
fadedText.height = 30;
fadedText.mouseEnabled = false;
fadedText.defaultTextFormat = fadedTextFormat;
item.addChild(fadedText);
fadedText.x = 75;
fadedText.y = 10;
distanceArrayDisplay.push(fadedText);
var distanceLoader:URLLoader = new URLLoader();
distanceLoader.load(new URLRequest("http://maps.googleapis.com&origins=someAddress&destinations="+businessAddress[i]+"&mode=walking&language=en-en&sensor=false"));
distanceLoader.addEventListener(Event.COMPLETE, distanceCalculated);
var logoLoader:Loader = new Loader();
item.addChild(logoLoader);
var logoURL:URLRequest = new URLRequest("http://www.myLogos.com/"+theXML.food[i].logo);
logoLoader.load(logoURL);
logoLoader.scaleX = .4;
logoLoader.scaleY = .4;
logoLoader.y = logoLoader.y + 5;
logoLoader.mouseEnabled = false;
var arrowGraphic:rightArrow = new rightArrow();
item.addChild(arrowGraphic);
arrowGraphic.x = stage.stageWidth - 5;
arrowGraphic.y = item.height/2;
touchList.addListItem(item);
}
}
}
function distanceCalculated(e:Event)
{
// trace(e.currentTarget.data);
var distanceXML:XML = new XML(e.target.data);
distanceXML.ignoreWhitespace = true;
var returnVar:String = (distanceXML.row.element.distance.text);
distanceArrayDisplay[distanceArrayCount].text = returnVar;
trace(returnVar);
distanceArrayCount++;
}
I am guessing that you are correctly reading the first XML, and that XML has a list of URLs that you want to load and then display some info from those on TextFields. Without knowing the structure of that XML I can't suggest you any working code, but I can point you on the right direction. For more info on reading/iterating XML on flash as3, please read: http://www.kirupa.com/developer/flashcs3/using_xml_as3_pg1.htm
//iterator var
var xml_read:uint=0;
//array of textfields for reference
var array_textFields:Array;
//config XML complete
function init(e:Event = null):void
{
array_textFields = new Array();
theXML = new XML(e.target.data);
theXML.ignoreWhitespace = true;
//this depends on the XML structure, please look at the article I linked
//for more info on how to iterate an XML
var i:uint=0;
for(someUrl in theXML..url)
{
var fadedText:TextField = new TextField();
//you should place each Textfield on different coord, otherwise
//they will all stack on top of each other and you will only see one
//for example:
fadedText.y = (fadedText.height+10)*i;
item.addChild(fadedText);
array_textFields.push(fadedText);
var distanceLoader:URLLoader = new URLLoader();
distanceLoader.load(new URLRequest(someUrl));
distanceLoader.addEventListener(Event.COMPLETE, distanceCalculated);
i++;
}
}
function distanceCalculated(e:Event):void
{
var distanceXML:XML = new XML(e.target.data);
distanceXML.ignoreWhitespace = true;
//retrieve information
var returnVar:String = (distanceXML.row.element.distance.text);
//set to textfield
TextField(array_textFields[xml_read]) = returnVar;
//increase iterator
xml_read++;
}
Please bear in mind that in ActionScript3, all network I/O is asynchronous. Usually EventListener functions don't return any value because you don't know when the data is ready. What you do is store a reference to where you want the data to go (in your case, a TextField variable) when the EventListener function is called asynchronously.

How to create a series of class instances in a for loop, as3

In my library I have a bunch of classes named tip1, tip2, tip3, tip4...and so on. Is it possible to create one instance of each on the stage using a for loop? I tried this but it didn't seem to work.
var tips:int = 12;
for(var i:int = 1; i<=tips; i++){
var tipName:String = "tip"+i
var tip:MovieClip = new tipName();
tip.name = "tip" + i
tip.x = stage.width;
tip.y = 0;
addChild(tip);
}
Any help would be appreciated. Thanks!
You were missing the "getDefinitionByName" part.
// Up top
import flash.utils.getDefinitionByName;
// Down below
var tips:int = 12;
for (var i:int = 1; i < tips; ++i ) {
var myClass:Class = getDefinitionByName('tip' + i) as Class;
var tip:Object = new myClass();
tip.name = "tip" + i;
....
}
Instead of
var tip:MovieClip = new tipName();
Try (written from memory)
var clazz:Class = getDefinitionByName(tipName) as Class;
var tip:MovieClip = new clazz();
Also, you generally want to use stage.stageWidth instead of stage.width, since the latter will return the stage bounding box width (which might not be the same as the area the swf file covers).

Dynamic vars MovieClips in AS3

Hello I'm trying to do this (in as2 this worked but not in as3) I looked on google for 3 hours, but still don't found a solution (thans for your help) :
import flash.display.MovieClip;
var mcContainer:MovieClip = new MovieClip();
var mcImage0:MovieClip = new MovieClip();
var mcImage1:MovieClip = new MovieClip();
var mcImage2:MovieClip = new MovieClip();
var mcImage3:MovieClip = new MovieClip();
mcImage0.name = "Boy";
mcImage1.name = "Girl";
mcImage2.name = "Woman";
mcImage3.name = "Man";
var ArrayNamesOfMC:Array = new Array();
var i:int = 4;
while(i--) {
ArrayNamesOfMC.push(["mcImage"+i].name);
}
This donsn't work :
ArrayNamesOfMC.push(["mcImage"+i].name);
This is the simple answer to your question:
var mcImage0:MovieClip = new MovieClip();
var mcImage1:MovieClip = new MovieClip();
var mcImage2:MovieClip = new MovieClip();
var mcImage3:MovieClip = new MovieClip();
mcImage0.name = "Boy";
mcImage1.name = "Girl";
mcImage2.name = "Woman";
mcImage3.name = "Man";
var ArrayNamesOfMC:Array = new Array();
var i:int = 3;
while (i >= 0)
{
ArrayNamesOfMC.push(MovieClip(this["mcImage" + i]).name);
i--;
}// end while
The following may not be relevant in your case as I'm not quite sure what the purpose of your application is, but this is probably a better approach:
var sprites:Vector.<Sprite> = new Vector.<Sprite>();
var names:Vector.<String> = new <String>["Boy", "Girl", "Woman", "Man"];
for (var i:uint = 0; i < names.length; i++)
{
var sprite:Sprite = new Sprite();
sprite.name = names[i];
sprites.push(sprite);
}// end for
Disregard this if it is not applicable in your case.
this should do the trick:
var _movieClip:MovieClip = ("mcImage" + i) as MovieClip;
ArrayNamesOfMC.push(_movieClip.name);
Taurayi's answer is an interesting technique that I didn't know about.
Personally I would recommend restructuring your code to put all the movieclips in an array, like so:
var mcImages:Array = new Array();
for (var i = 0; i < 4; i++) {
mcImages.push(new MovieClip);
}
mcImages[0].name = "Boy";
trace(mcImages[0].name);
Incidentally, your while loop was constructed incorrectly. You need a condition in the parentheses and then do the decrement inside the loop. But with all your movieclips in an array then you can use this much simpler approach to loop through all of them:
for each (var mc in mcImages) {
trace(mc.name);
}