trouble separating loader array and array for grid of images - actionscript-3

My problem is that I can't figure out how to decouple the loader from this loadNewRow function. Ideally, I'd like to figure out how to load all the swf's give them dynamic names... like thmb1loaded, thmb2loaded, thmb3loaded.. push into an a ("loaded") array and then have that be used to build the grid.
Right now, its loading them every time the loadnewrow function fires. I'm sure its a simple matter of iterating a .name within a contentloaderinfo .onComplete when each swf is loaded... anyhelp would be appreciated this has been driving me crazy last couple of days..
var filePaths:Array=["thmb1.swf","thmb2.swf","thmb3.swf","thmb4.swf", "thmb5.swf", "thmb6.swf",
"thmb7.swf","thmb8.swf", "thmb9.swf", "thmb10.swf", "thmb11.swf" ];
function loadImages3(event:MouseEvent):void {
TweenLite.to(pic, 8, {alpha:0, ease:Expo.easeInOut});// dim image container
trace("loadImages3 fired ---------------------------------------------------------")
unloadImages3resize(); loadImages3Flag=true;
var randomScale:Number = .3 + Math.random();trace("in loadimages3 function randomScale is now.. " + randomScale);
var stage_w=stage.stageWidth;trace("in loadimages3 function stage_w is = " + stage_w);
var stage_h=stage.stageHeight;trace("in loadimages3 function stage_h is = " + stage_h);
var thumbWidth:Number=240;var thumbHeight:Number=155;//var randomScale:Number=.45;
var scaleThumbs:Number=randomScale;
var finalRandomScaledWidth:Number=thumbWidth*scaleThumbs;
var finalRandomScaledHeight:Number=thumbHeight*scaleThumbs;
var clipsFitX=Math.floor(stage_w/finalRandomScaledWidth);
trace("in loadimages3 function finalRandomScaledWidth is = " + finalRandomScaledWidth);
var clipsFitY=Math.floor(stage_h/finalRandomScaledHeight);
trace("in loadimages3 function finalRandomScaledHeight is = " + finalRandomScaledHeight);
var clipsFitXTotal:Number = clipsFitX+1; // add extra one on the horizontal
var clipsFitYTotal:Number = clipsFitY+2; // add extra two on the vertical
trace ("ClipsFitXtotal) = " +clipsFitXTotal, "(clipsFitYTotal) = " + clipsFitYTotal);
loadnewRow(clipsFitXTotal, clipsFitYTotal,randomScale,finalRandomScaledHeight, finalRandomScaledWidth );
}
function loadnewRow(clipsFitXTotal:Number, clipsFitYTotal:Number, randomScale:Number,
finalRandomScaledHeight:Number, finalRandomScaledWidth:Number):void {
trace("loadnewRow fired ---------------------------------------------------------");
trace("randomScale out of loop but in loadnewRow function loop =" + randomScale);
for (var z:Number =0; z < clipsFitYTotal; z++) {
for (var b:Number = 0; b < clipsFitXTotal; b++) {
var ldr:Loader = new Loader();
var randomSelection = Math.floor( (Math.random()*filePaths.length) );
ldr.load(new URLRequest (filePaths[randomSelection]));
ldr.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
ldr.scaleX=ldr.scaleY=randomScale;//trace("randomScale in the loop is =" + randomScale);
ldr.y=finalRandomScaledHeight*z;//trace("finalRandomScaledHeight*z =" + ldr.y);
ldr.x=finalRandomScaledWidth*b;//trace("finalRandomScaledWidth*b =" + ldr.x);
ldr.alpha=.8;
//trace("[ldr] = number of children = " + ldr.numChildren);
//trace("[THIS] = number of children = " + this.numChildren);
//trace("[THIS] name is = " +this.name);
ldr.cacheAsBitmap = true;
//thumbholder.addChild(ldr);
addChildAt(ldr,1);
filePaths.splice(randomSelection, 1);
if (filePaths.length==0) {
filePaths.push("thmb1.swf","thmb2.swf","thmb3.swf","thmb4.swf","thmb5.swf",
"thmb6.swf","thmb7.swf","thmb8.swf", "thmb9.swf",
"thmb10.swf", "thmb11.swf");
}
}
}
}

I suggest you to use some library/framework to simplifiy things. As I use splinklibrary here is some exemplary code to solve your problem with the aid of splinklibrary:
public function Test() {
var filePaths : Array = ["thmb1.swf","thmb2.swf","thmb3.swf"];
var q : IQ = new Q();
q.register(QCompleteEvent.COMPLETE, onComplete);
for each (var path : String in filePaths) {
q.add(new QLoader(new URLRequest(path)));
}
q.start();
}
private function onComplete(e : QCompleteEvent) : void {
var displays : Array = new Array();
var q : IQ = IQ(e.getSource());
for each (var loader : QLoader in q.getItems()) {
displays.push(addChild(loader.getContent()));
}
arrange(displays);
show(displays);
}
private function arrange(displays : Array) : void {
// put in your code to arrange the loaded displayobjects
}
private function show(displays : Array) : void {
// put in your code to tween the loaded displayobjects
}
Of course you can reach your goal without a library too, but the point is that a library often helps to keep your code simple and concise.

Related

AS3. MouseEvent click in (for) loop function

am need here onClick one of the movieclip loop_Task.addChild(tee) trace the tee.task_id.text which one is clicked from the list for ex. this
output be like
(List Clicked : 100)
(List Clicked : 101)
or onClick passed the item data it's already clicked to new class screen
here is my code
public function resultHandlerList_items(event:SQLEvent):void
{
// TODO Auto-generated method stub
var result:SQLResult = selectStmt1.getResult();
var numResults:int = result.data.length;
for (var i:int = 0; i < numResults; i++)
{
var row:Object = result.data[i];
var tee:listview_mc = new listview_mc
loop_Task.addChild(tee)
tee.y = 270*i
tee.task_id.text = row.Tid
tee.task_tit.text = row.Ttitles
tee.task_stime.text = row.Stime
tee.task_subject.text = row.Subject
tee.addEventListener(MouseEvent.CLICK, onClickList)
}
function onClickList(e:MouseEvent):void{
trace("List Clicked : " + e.currentTarget)
}
}
in the first thanks to #Organis He give me the way to fix my code and he give me info about how to talk with the compiler with exactly how to make the compiler understand your code this code the fix (e.currentTarget as listview_mc) and now this my code after fixing and i do take a public var String and pass it to other Class
public function resultHandlerList_items(event:SQLEvent):void
{
// TODO Auto-generated method stub
var result:SQLResult = selectStmt1.getResult();
var numResults:int = result.data.length;
for (var i:int = 0; i < numResults; i++)
{
var row:Object = result.data[i];
var tee:listview_mc = new listview_mc
loop_Task.addChild(tee)
tee.y = 270*i
tee.task_id.text = row.Tid
tee.task_tit.text = row.Ttitles
tee.task_stime.text = row.Stime
tee.task_subject.text = row.Subject
tee.addEventListener(MouseEvent.CLICK, onClickList)
}
function onClickList(e:MouseEvent):void{
trace("List Clicked : " + (e.currentTarget as listview_mc).task_id.text)
ts_id = (e.currentTarget as listview_mc).task_id.text;
sport._sport.Remove_Home_Sc(e);
trace("done")
}
}

Displaying multipe Array-type attributes of sharedObject.data property in a single list

I have various food category pages (such as "Carbohyrates", "Meat", "Vegetables" etc) that have 3 comboboxes on each page where a user can select 3 different ingredients from each category (i.e. on the "Meat" page, a user can select 3 different types of meat). I write these 3 meats to a sharedObject as an Array like so:
Here is my saveMeat() function as an example so you can understand how I am forming my arrays:
function saveMeat(event:MouseEvent):void
{
_categoryMeat.btn_goback.removeEventListener(MouseEvent.CLICK, saveMeat);
removeChild(_categoryMeat);
if (meatDisableCheckBox.selected == true)
{
stop();
}
if (myComboBoxMeat.selectedLabel != null)
{
so.data.meat1 = myComboBoxMeat.selectedLabel;
trace(so.data.meat1);
}
if (myComboBoxMeat2.selectedLabel != null)
{
so.data.meat2 = myComboBoxMeat2.selectedLabel;
trace(so.data.meat2);
}
if (myComboBoxMeat3.selectedLabel != null)
{
so.data.meat3 = myComboBoxMeat3.selectedLabel;
trace(so.data.meat3);
}
var meat_items_array:Array = new Array(so.data.meat1, so.data.meat2, so.data.meat3);
so.data.meatItems = meat_items_array;
so.flush();
trace(so.data.meatItems);
}
There are several of these functions for each of the category pages (in all 6 different functions). They are all pretty similiar except for the fact the checkboxes and comboboxes differ.
I have a list function called dataLoaded that loads items from the sharedObject into the scrolling list:
private function dataLoaded():void
{
var i:Number;
for (i=0; i < so.data.meatItems.length; i++) {
_item = new Item();
// creates the var itemTextField //
_itemTextField = new TextField();
_itemTextField.text += '' + so.data.meatItems[i].toString();
//adds textfield to displaylist//
_item.addChild(_itemTextField);
}
}
As you can see, the for loop inputs the toString() representation of one of my attributes of my sharedObject (so.data.meatItems) into the TextField but I want to input all instances inside of my sharedObject no matter what sub-attribute they have. Also notice that I'm evaluating the length of the meatItems array in the for loop conditional, when I would want to be evaluating all items in the sharedObject
How can I do this?
EDIT: I implemented the below solution but am receiving this error:
TypeError: Error #1010: A term is undefined and has no properties.
at RecipeMatcher/dataLoaded()[/Users/adambull/Desktop/RecipeMatcherSO/RecipeMatcher.as:893]
at RecipeMatcher/displayList()[/Users/adambull/Desktop/RecipeMatcherSO/RecipeMatcher.as:212]
at RecipeMatcher/hideSplashScreen()[/Users/adambull/Desktop/RecipeMatcherSO/RecipeMatcher.as:192]
at Function/http://adobe.com/AS3/2006/builtin::apply()
at SetIntervalTimer/onTimer()
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
Here is my attempt at implementing the below (I have included my full function this time just in case there is something else in my function causing problems)
private function dataLoaded():void
{
// parsing of each ingredient//
// instantiation of mcItem (the stage for each item)
for (var item:* in so.data)
{
if (so.data[item] !=null)
{
if (so.data[item] is Array)
{
var a:Array = so.data[item];
for (var i:uint = 0 ; i < a.length;i++ )
{
_item = new Item();
// sets //over// layer to invisible / transparent //
_item.item_btn_over.alpha = 0;
// creates the var itemTextField //
_itemTextField = new TextField();
// _itemTextField visual attributes //
_itemTextField.x = _textFieldXPosition + _textFieldPaddingLeft;
_itemTextField.y = _textFieldYPosition;
_itemTextField.selectable = true;
_itemTextField.wordWrap = true;
itemTextField.width = _textFieldWidth;
_itemTextField.height = _textFieldHeight;
_itemTextField.embedFonts = true;
_defaultFormat.color = 0x111112;
_defaultFormat.font = _arialRounded.fontName;
_defaultFormat.size = 18;
_itemTextField.defaultTextFormat = _defaultFormat;
_itemTextField.appendText( so.data[item][i].toString() );
//adds textfield to displaylist//
_item.addChild(_itemTextField);
//vertical positioning//
_item.y = i * _itemPosition;
_item.btn_delete.visible = false;
_item.buttonMode = true;
_item.mouseChildren = false;
//adds items to container displaylist//
_container.addChild(_item);
}
}
}
}
// Input Mask//
_mask = new Shape();
_mask.graphics.beginFill(0xFF0000);
_mask.graphics.drawRect(0, 0, _maskWidth, _maskHeight);
_mask.graphics.endFill();
// Positioning of input mask//
// horizontal centering of input mask//
_mask.x = stage.stageWidth / 2 - _container.width / 2;
_mask.y = _paddingTop;
// adds the mask onto the stage//
addChild(_mask);
// assigns the above mask to the container //
_container.mask = _mask;
// Positioning of container with the mask//
// horizontal centering of container //
_container.x = stage.stageWidth / 2 - _container.width / 2;
// vertical position of container //
_container.y = _paddingTop;
//Container background stylings//
_background = new Shape();
_background.graphics.drawRect(0, 0, _container.width, _container.height);
_container.addChildAt(_background, 0);
//End of container background stylings//
_item.parent.addEventListener( MouseEvent.CLICK, itemClicked );
_container.addEventListener(MouseEvent.MOUSE_OVER, movingOver);
_container.addEventListener(MouseEvent.MOUSE_OUT, movingOut);
}
(I have tried adding an extra if to evaluate whether the content of each shared object attribute is empty or not - because I believe that if an array is empty this may cause another error?)
If I understood well you question, here is an example. It browse so.data, looks for arrays and then iterates on each one.
import flash.net.SharedObject;
var my_so = SharedObject.getLocal("superfoo");
// fill some fake values
var ar:Array = [1, 2, 3, 4, 5]
var ar2:Array = ['a1', 'a2', 'a3', 'a4']
my_so.data.array1 = ar;
my_so.data.array2 = ar2;
my_so.data.notarray = 'I m not an array';
my_so.flush();
// browse the so and find arrays
var my_so2 = SharedObject.getLocal("superfoo");
for (var item:* in my_so2.data) {
if (my_so2.data[item] is Array) {
var a:Array = my_so2.data[item];
for(var i:uint = 0 ; i<a.length;i++ ) {
trace('my_so2.data[' + item + '][' + i + ']=' + a[i])
}
}
}
Ouput (it skips items that are not Arrays in so.data)
my_so2.data[array2][0]=a1
my_so2.data[array2][1]=a2
my_so2.data[array2][2]=a3
my_so2.data[array2][3]=a4
my_so2.data[array1][0]=1
my_so2.data[array1][1]=2
my_so2.data[array1][2]=3
my_so2.data[array1][3]=4
my_so2.data[array1][4]=5

Error joining AS2 with AS3

I have problems joining two scripts into one.
This is main part of the script: AS3.
And this is already joined script.
And here is part of the code that I need to import (AS2) :
stop();
var banners:Array = new Array();
var imagePaths:Array = new Array();
var links:Array = new Array();
var bodyTexts:Array = new Array();
var imageTime:Number;
var numberOfBanners:Number;
var isRandom:String;
var showHeader:String;
var bannersXML:XML = new XML();
bannersXML.ignoreWhite = true;
bannersXML.load("banners.xml");
bannersXML.onLoad = function(success) {
if (success) {
trace("XML LOADED");
imageTime = parseInt(this.firstChild.firstChild.firstChild)*1000;
numberOfBanners = parseInt(this.firstChild.childNodes[1].firstChild);
isRandom = this.firstChild.attributes["isRandom"];
showHeader = this.firstChild.childNodes[2].attributes["showHeader"];
var bannerSequence:Array = new Array();
if (isRandom == "true") {
//Make a random sequence
while (bannerSequence.length<numberOfBanners) {
newRandomNumber = random(numberOfBanners);
//Make sure that the random one chosen is not already chosen
for (var i = 0; i<=bannerSequence.length; i++) {
if (newRandomNumber != bannerSequence[i]) {
alreadyThere = false;
} else {
alreadyThere = true;
break;
}
}
//Add only random values that aren't in the array
if (!alreadyThere) {
bannerSequence.push(newRandomNumber);
}
}
} else {
for (var i = 0; i<numberOfBanners; i++) {
bannerSequence.push(i);
}
}
}
//Read XML in the Random Order Chosen
for (var i = 0; i<numberOfBanners; i++) {
banners.push(this.firstChild.childNodes[2].childNodes[bannerSequence[i]].firstChild.firstChild.toString());
bodyTexts.push(this.firstChild.childNodes[2].childNodes[bannerSequence[i]].childNodes[1].firstChild.nodeValue);
imagePaths.push(this.firstChild.childNodes[2].childNodes[bannerSequence[i]].childNodes[2].firstChild.nodeValue);
links.push(this.firstChild.childNodes[2].childNodes[bannerSequence[i]].childNodes[3].firstChild.nodeValue);
}
play();
};
//Start the image counter at 0
var imageCounter = 0;
I get erorr in this part of the code
function doRandArray(a:Array):Array {//make random array
var nLen:Number = a.length;
var aRand:Array = a.slice();
var nRand:Number;
var oTemp:Object;
for (var i:Number = 0; i < nLen; i++) {
oTemp = aRand[i];
nRand = i + (random(nLen – i));
aRand[i] = aRand[nRand];
aRand[nRand] = oTemp;
}
return aRand;
}
When I run it, I get an error in this place:
nRand = i + (random(nLen – i));
Scene 1, Layer 'Layer 1', Frame 1, Line 265 1084: Syntax error: expecting rightparen before i.
as2 random(random(nLen – i)); is generate 0,1,...nLen-i-1. not floating only int value.
correct as3 code is int(Math.random()*(nLen-i)); or Math.floor(Math.random()*(nLen-i));
as2: random()
as3: Math.random()
In ActionScript 3 the random function is a little bit different from what it was in as2 code, just change the offending line to:
nRand = i + Math.random()*(nLen-1);
This should fix all errors and work just the same.
EDIT: as #bitmapdata.com indicated, for this to run the same as in as2 the random value must be truncated (stripped of its decimal values). Besides the couple of possibilities he suggested, I would personally just change nRand's type to uint on declaration:
var nRand:uint;
You can also change the iterator type to var i:uint. Less memory usage is always good ;)

I cant remove child of this movie clip upon clicking the back button to go function goHomePage (evt:Event):void{

Help. I need to remove the newContainer(this is a movie clip) after clicking the back button to go back to homepage.
But it just loads the homepage and the newContainer is still there. :( where did i go wrong?
import flash.events.MouseEvent;
import flash.events.Event;
import fl.motion.MotionEvent;
import flash.net.URLVariables;
import flash.display.MovieClip;
import flashx.textLayout.elements.Configuration;
var ctr:int = 0;
var now:Date = new Date();
var myurl:String = "http://localhost:8888/eventspictures/getdata.php";
var scriptLoader:URLLoader = new URLLoader();
var scriptRequest:URLRequest = new URLRequest();
var newContainer:MovieClip;
scriptRequest.url = myurl + "?ck=" + now.getTime();
scriptLoader.addEventListener(Event.COMPLETE, handleLoadSuccess);
scriptLoader.addEventListener(IOErrorEvent.IO_ERROR, handleError);
scriptRequest.method = URLRequestMethod.POST;
scriptLoader.load(scriptRequest);
function handleLoadSuccess(evt:Event):void
{
for (var j:Number = 0; j <4; j++)
{
var newContainer:MovieClip = new con();
newContainer.name = String(ctr);
newContainer.y = j*80 +65;
newContainer.x= 16;
stage.addChild(newContainer);
var variables:URLVariables = new URLVariables(evt.target.data);
trace(variables.output);
var parse:String = variables.output;
var parsed:Array = parse.split("<|>");
var tab:String = ' ';
var eventname:String = '';
var date:String='';
var slotsleft:String='';
// different variable names to assign to different column names(etc; eventname, date, slotsleft)
// loop through.. start from O
for (var i:Number = 0; i<parsed.length-1; i++)
{
trace(parsed[i]);
var item:String = parsed[i];
var itemarray:Array = item.split(",");
eventname += itemarray[2] + tab + "<br>";
date += itemarray[3] + tab;
slotsleft += itemarray[4] + tab;
trace(eventname);
newContainer.eventname_txt.htmlText = eventname;
newContainer.date_txt.htmlText= date;
newContainer.slotsleft_txt.htmlText=slotsleft;
}
}
//slotsleft_txt.x = 270;
}
function handleError(evt:IOErrorEvent):void
{
}
backbutton_mc.addEventListener(MouseEvent.CLICK, goHomePage);
function goHomePage (evt:Event):void{
gotoAndPlay("dashboard");
removeChild(newContainer);
}
stop();
In your function handleLoadSuccess() you have a loop that creates 4 MovieClip's and adds them to the stage.
But in your goHomePage() function you only try to remove one object from the stage. It turns out this object is probably null in your example (trying to remove an object that is null should generate an error if you are using the debug Flash player).
The reason it is probably null is because you have defined two variables named newContainer in your code: one is declared at the beginning of the script, and the second one inside the function handleLoadSuccess() (because you are using the keyword var on each line).
The variable created inside the function only exists while that function is executing. The variable created outside the function never seems to receive a value.
Two approaches you can use:
Keep track of the things you add to the stage, by putting them in an Array:
Replace the newContainer variable that is outside the function with an Array called containers:
var containers:Array = [];
In the function handleLoadSuccess(), when you add each MovieClip to the stage, also add them to the containers array:
stage.addChild(newContainer);
containers.push(newContainer);
Finally in the function goHomePage() iterate over the containers array to remove each MovieClip:
for (var j:int = 0; j < containers.length; j++)
{
stage.removeChild( containers[j] );
}
// reset the containers array so it's empty for the next time
// and to remove the references to the MovieClips (to prevent a memory leak)
containers=[];
Blindly remove everything from the stage
If this is accetpable, it is much easier. Just iterate backwards over the children of the stage in your goHomePage() function:
for (var j:int = stage.numChildren; j >= 1; j--)
{
stage.removeChildAt(j - 1);
}

How can I get the background color of a loaded swf file?

I'm loading an swf file into my main application using URLLoader, I want to get the background color of the loaded swf file. ( I heard that one solution wold be reading the byte code of the loaded swf )
Yes, You need to look into binary swf data. Here is brief description of swf format. And this is a little detail about different kind of tags. Your requirement is to find out SetBackgroundColor tag(tag type = 9), which commonly is either first or second tag of the swf. Bytes in swf file follows little endian order, so you need to be careful while reading the data. And mostly they will be compressed(first three bytes will be "CWS") so from 9th bytes onwards (including 9th), all data needs to be decompressed (ByteArray.decompress) before processing.SomeExample code :) package {
import flash.display.*;
import flash.events.*;
import flash.net.*;
import flash.utils.*;
public class Test1 extends Sprite{
private var stream:URLStream;
public function Test1():void {
stream = new URLStream();
stream.load(new URLRequest("some.swf"));
stream.addEventListener(Event.COMPLETE, onComplete);
}
private function onComplete(e:Event):void {
var bytes:ByteArray = new ByteArray();
bytes.endian = Endian.LITTLE_ENDIAN;
stream.readBytes(bytes, 0, 8);
var sig:String = bytes.readUTFBytes(3);
trace("SIG = " + sig);
trace("ver = " + bytes.readByte());
trace("size = " + bytes.readUnsignedInt());
var compBytes:ByteArray = new ByteArray();
compBytes.endian = Endian.LITTLE_ENDIAN;
stream.readBytes(compBytes);
if (sig == "CWS") {
compBytes.uncompress();
}
var fbyte = compBytes.readUnsignedByte();
var rect_bitlength = fbyte >> 3;
var total_bits = rect_bitlength * 4;
var next_bytes = Math.ceil((total_bits - 3)/ 8);
for(var i=0; i<next_bytes; i++) {
compBytes.readUnsignedByte();
}
trace("frameRate = " + compBytes.readUnsignedShort());
trace("frameCount = " + compBytes.readUnsignedShort());
while(true) {
var tagcodelen:Number = compBytes.readUnsignedShort();
var tagcode:Number = tagcodelen >> 6;
var taglen:Number = tagcodelen & 0x3F;
trace("tag code = " + tagcode + "\tlen = " + taglen);
if (taglen >=63) {
taglen = compBytes.readUnsignedInt();
}
if(tagcode == 9) {
trace("found background color");
trace("color is: RED=" + compBytes.readUnsignedByte() +", GREEN = " + compBytes.readUnsignedByte() + ", BLUE = " + compBytes.readUnsignedByte());
break;
}
compBytes.readBytes(new ByteArray(), 0, taglen);
//break;
}
}
}
}
You SWF file has to pass it to a web page with JS.
getURL("javascript:setColour(" + DESIRED COLOUR + ")");
The "setColour" function of course must do what you want it to do.