need some array help in actionscript 3 - arrays

i am very new to concept of array...so i need a bit help understanding and executing it....
so I have 5 buttons...
monday - friday
now when somebody presses one of the buttons I want the program to trace the day that was pressed only.. can somebody please explain me step by step on what to do and why?
I am using flash actionscript 3..
this is pretty much the only thing I know how to do...I've tried some onlint tuts but they weren't very clear
var days: Array ["mon", "tues", "wed", "thurs", "fri"];

Your Array was created wrong in your post. Try this:
var days:Array = ["mon", "tues", "wed", "thurs", "fri"];
or you could also create it like this, using the push() method of the Array class:
var days:Array = new Array();
days.push( 'mon');
days.push( 'tues');
days.push( 'weds');
days.push( 'thurs');
days.push( 'fri');
to trace the values of the array in your post:
trace( days[0] ); // returns "mon"
trace( days[1] ); // returns "tues"
trace( days[2] ); // returns "wed"
trace( days[3] ); // returns "thurs"
trace( days[4] ); // returns "fri"
The array's contents are stored in the array's "indexes". An array's index always starts with 0.
Array's have a length. An empty array's length is 0. If the array has at least one item in it, the length is 1 and increases as you add more items. To loop through your array to get the values do this:
for(var i:int = 0; i < days.length; i++)
{
trace( days[i] );
}
Arrays are a powerful and essential part of any programming language. You can remove items from the array, add items, remove a specific item at a specific index, remove an item by name, combine arrays, and lots more. You'd benefit from looking at this link and studying the properties and methods of the Array class. Once you get the hang of how to manipulate Array's you'll never now how you existed without them!
There are many ways to associate a button with a particular array index. The answer provided by Dr.Denis McCracleJizz is one way, although if you are as new to AS3 as you say, it might seem a little overwhelming as it uses several concepts you may not yet be familiar with. Let me see if I can simplify it a bit, although this will make the code a bit more lengthy:
mondayButton.addEventListener( MouseEvent.CLICK, onClickDayButton );
tuesdayButton.addEventListener( MouseEvent.CLICK, onClickDayButton );
function onClickDayButton( e:MouseEvent ):void
{
if( e.target.name == 'mondayButton')
{
trace( days[0] );
}
else if( e.target.name == 'tuesdayButton')
{
trace( days [1] );
}
// and so on...
}
If you're familiar with objects you could create an object for each button that hold both the button and the button id and store those in an array:
var days:Array = ["mon", "tues", "wed", "thurs", "fri"];
var dayButtonArray:Array = new Array();
var mondayButtonObject:Object = new Object();
mondayButtonObject.button = mondayButton;
mondayButtonObject.id = 0;
dayButtonArray.push( mondayButtonObject );
var tuesdayButtonObject:Object = new Object();
tuesdayButtonObject.button = tuesdayButton;
tuesdayButtonObject.id = 1;
dayButtonArray.push( tuesdayButtonObject );
// and like above, the rest of the days here
// then loop through them and set the mouseEvent
for(var i:int = 0; i < dayButtonArray.length; i++)
{
dayButtonArray[i].button.addEventListener( MoouseEvent.CLICK, onClickDayButton );
}
// and the function each button calls to
function onClickDayButton( e:MouseEvent ):void
{
trace( days[ evt.target.id ] );
}
You could further simplify the object method above by skipping the days array altogether and adding the day associated with the button right into the dayButtonArray instead of an id:
var dayButtonArray:Array = new Array();
var mondayButtonObject:Object = new Object();
mondayButtonObject.button = mondayButton;
mondayButtonObject.day = "monday";
dayButtonArray.push( mondayButtonObject );
var tuesdayButtonObject:Object = new Object();
tuesdayButtonObject.button = tuesdayButton;
tuesdayButtonObject.day = "tuesday";
dayButtonArray.push( tuesdayButtonObject );
// and like above, the rest of the days here
// then loop through them and set the mouseEvent
for(var i:int = 0; i < dayButtonArray.length; i++)
{
dayButtonArray[i].button.addEventListener( MoouseEvent.CLICK, onClickDayButton );
}
// and the function each button calls to
function onClickDayButton( e:MouseEvent ):void
{
trace( evt.target.day );
}
Now were getting as complicated as Dr.Denis McCracleJizz's answer. His is definitely worth looking at as well.

Your array is a list of items, so your array is composed of the days of the week.
You can access them by using an index like so.
trace(days[0])
//Outputs: mon
trace(days[3])
//Outputs: thurs
Now for your buttons there is two way of doing it, the clean one that's more complicated and the other one that works just as well and that is more simple.
Add event listeners on your buttons so that when you click the first one you can
trace the first element of your days array using days[0]
the real way to do it is this.
var days: Array ["mon", "tues", "wed", "thurs", "fri"];
var buttons: Array = [ stage.getChildByName("mondayButton"), stage.getChildByName("tuesdayButton") ];
//you need buttons name 'mondayButton' in your stage or this will crash.
//then somewhere in your program you add event listener to all the buttons in your array like so
for(var i:int =0; i < buttons.Length; i++){
var myButton:Button = buttons[i];
myButton.AddEventListener(onButtonClicked,Event.Mouse_Click);
}
public onButtonClicked(MouseEvent e):void{
var myClickedButton:Button = (e.target as Button);
//e.target is who sends the event, in this case its your buttons
//next you look what position this button takes in your button array and get get
//the day in the array from its index
var index:int = buttons.indexOf(myClickedButton);
trace(days[index]);
}
Take note that this code is written from memory, dont copy paste. This is the more "complicated" method of doing what you want to do. Hope this helps :)

Related

Looping for events in actionscript 3, only get last number

So I want to code faster by making array of all button that I have, and also make array of function which index numbers are connected to the array of each buttons.
For example, buttons[0], handler events for hover is button_over_funcs[0] and for out is button_out_funcs[0].
To make it clearer (since english is not my first language), take a look at my code:
var buttons:Array = [playbtn, tutorialbtn];
var button_over_funcs:Array = new Array();
var button_out_funcs:Array = new Array();
var i = 0;
for each(var j in buttons){
j.buttonMode = true;
button_over_funcs.push(function(e:MouseEvent){
j.gotoAndPlay("hover");
});
button_out_funcs.push(function(e:MouseEvent){
j.gotoAndPlay("out");
});
j.addEventListener(MouseEvent.ROLL_OVER, button_over_funcs[i]);
j.addEventListener(MouseEvent.ROLL_OUT, button_out_funcs[i]);
i++;
}
but the j will always refer to tutorialbtn, regardless which button I hover/out. I tried for-in as well
var buttons:Array = [playbtn, tutorialbtn];
var button_over_funcs:Array = new Array();
var button_out_funcs:Array = new Array();
for(var j in buttons){
buttons[j].buttonMode = true;
button_over_funcs.push(function(e:MouseEvent){
buttons[j].gotoAndPlay("hover");
});
button_out_funcs.push(function(e:MouseEvent){
buttons[j].gotoAndPlay("out");
});
buttons[j].addEventListener(MouseEvent.ROLL_OVER, button_over_funcs[j]);
buttons[j].addEventListener(MouseEvent.ROLL_OUT, button_out_funcs[j]);
}
Both seems the same. It seems like actionscript always refers to the last value of j instead of assigning it. Do you have any idea on how to make this as I expected? Is it impossible to make this quicker and not assigning the button to do same exact stuff?
There's no point in reinventing the wheel. Use SimpleButton and be done with it.
In general: a class is the way to go when you want to define behaviour that several objects have in common.
So I found the way by myself. If you found same problem as me, you can take a look.
var buttons:Array = [playbtn, tutorialbtn];
var button_over_funcs:Array = new Array();
var button_out_funcs:Array = new Array();
function addOver(ob){
button_over_funcs.push(function(e:MouseEvent){
ob.gotoAndPlay("hover");
});
}
function addOut(ob){
button_out_funcs.push(function(e:MouseEvent){
ob.gotoAndPlay("out");
});
}
function addEvent(ob){
addOver(ob);
addOut(ob);
}
for each(var j in buttons){
addEvent(j)
}
for(var i = 0; i<= buttons.length - 1; i++){
buttons[i].buttonMode = true;
buttons[i].addEventListener(MouseEvent.ROLL_OVER, button_over_funcs[i]);
buttons[i].addEventListener(MouseEvent.ROLL_OUT, button_out_funcs[i]);
}

Cannot push past 1 element to basic AS3 Array

I am very new to this and hoping it's something that should have been obvious.
When I run the code below, the Array newHole and newArray both return 1 on the trace. Originally the code was built with only the newHole array, but I created the newArray in the hopes of troubleshooting. It did not help. The class for bulletHole contains no extra code so I didn't post that.
Thank you.
import flash.display.*;
import flash.events.*;
import flash.ui.Mouse;
Mouse.hide();
var myReticle:MovieClip;
var holeArray:Array = new Array();
var randomHole:Number = randomNumber(1, 5);
var newHole:bulletHole = new bulletHole();
var newArray:Array = new Array();
stage.addEventListener(MouseEvent.MOUSE_MOVE, followReticle);
stage.addEventListener(MouseEvent.CLICK, myFire);
stage.addEventListener(MouseEvent.CLICK, checkCount);
function followReticle(event:MouseEvent):void
{
myReticle.x = mouseX;
myReticle.y = mouseY;
}
function myFire(int):void
{
stage.addChild(newHole);
newHole.x = myReticle.x;
newHole.y = myReticle.y;
//holeArray.push(newHole);
newHole.gotoAndStop(randomHole);
//trace(holeArray.length);
}
function checkCount(int):void
{
newArray.push("A");
trace(newArray.length);
}
function randomNumber(low:Number=0, high:Number=1):Number
{
return Math.floor(Math.random() * (1+high-low)) + low;
}
Most likely the issue is that the code you've posted is running over and over again. In other words, you have a looping timeline that eventually goes back to the frame that the code you've shown is on.
Whenever that frame is reached, you have the following:
var holeArray:Array = new Array();
Which creates a new array replacing what used to be in that var.
To solve this, you either need to:
take the code out of the timeline (put it in a class file and attach that as the document class of your project)
re-architect your timeline so the first frame is only reached 1 time
put some checks in so that the code only runs the first time the frame is reached.
Here is an example of the latter option:
//just define the array, don't create it
var holeArray:Array;
//if the array is null, create it (it will only be null the first time this code is run
if(!holeArray){
holeArray = new Array();
}
This line is incorrect:
function myFire(int):void {
Because the function is triggered from a mouse event listener it should read:
function myFire(e:MouseEvent):void {
What you are doing is passing a undefined int to the function. Hope this helps.
EDIT: You should delete the clickCount event listener and function as they're not needed.
Also notice that you should move this line to the top of your myFire function or else you will keep replacing this MovieClip instead of creating it again:
var newHole:bulletHole = new bulletHole();

Actionscript 3 and sorting incoming bytes from an arduino

im new to using action script so i apologies if this wont make sense, the issue iam having is that the incoming bytes from my arduino are not being stored properly in an array. The bytes come in one at a time from my arduino and will be stored in an array in as3.
i have two values SF-F8-001, SF-F8-002 and SF-F8-003 etc... when i trace the incoming bytes i get this:
S
F
-
F
8
-
0
0
1
so when i look at that i realized i needed an array to store the byte as they come in however i have tried many different things but it hasnt worked
however this code below seems to get me close to my desired result
import flash.events.*;
import flash.net.Socket;
import flash.utils.ByteArray;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLVariables;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequestMethod;
var ary:Array = new Array();
var bar_grab:Array = new Array();
var array:Array = new Array();
trace("__AS3 Example__");
var socket:Socket = new Socket("localhost",5331);
socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
function socketDataHandler(event:ProgressEvent):void
{
var str:String = String(socket.readUTFBytes(socket.bytesAvailable));
var b:String;
bar_grab.push(str);
b = bar_grab.join("");
boxtwo.text = b;
}
this code gets me this
SF-F8-001SF-F8-002SF-F8-003 etc...
however the result iam looking for is this
SF-F8-001,SF-F8-002,SF-F8-003 etc....
so if anyone could help me sort this out i will be grateful
thank you
If you know a priori how many characters each item will consist of you could read everything to string and get each individual item like that:
//Main string containing all items
var allString:String = "123456789";
//Number of chars in of item
var charsInItem = 3;
var item:String;
var index:int;
var resultArray:Array = new Array();
for(var i:int = 0; i < allString.length/charsInItem; i++)
{
index= i*charsInItem;
//traces name of one item
item = allString.slice(index, index+charsInItem);
resultArray.push(item);
trace(item);
}
//Output:
//123
//456
//789
If you don't know a number of chars in one item or it varies, I would suggest tweaking Arduino code and putting some sort of a marker in between every item. Like say a comma (,). Then your string would look something like this: "item1,item2,longerItem3". And you could split that string into array like that:
var array:Array = new Array();
var allString:String = "item1,item2,longerItem3";
//This splts string into array items using comma (,) as a seperator
array = allString.split(",");
for(var i:int = 0; i < array.length; i++)
{
//trace every array element
trace(array[i]);
}
//Output:
//item1
//item2
//longerItem3
I should add that even if you know a number of chars in one item I would still suggest using method nr.2.

AS2 push to array outside of clip does nothing

was wondering if someone could show me what I'm doing wrong here.
I have some old AS2 flash code I'm trying to get working.
First I create a few arrays in frame 1 of the main timeline like so-
var typeArr:Array = new Array();
for (var i:Number = 1; i < 5; i++)
{
_root.typeArr[i] = "data goes here";
}
Then I have a movieclip dynamically attached on the main stage that when clicked appends one of the arrays we created by pushing the string 'foo' to it-
stop();
_root.myType=3;//this can be any of our array numbers
this.onPress=function(){
var foo:String="test";
_root.typeArr[_root.myType].push(foo);
trace(_root.typeArr[_root.myType]);
}
Where _root.typeArr[_root.myType] is the array name and number _root.typeArr3, but pushing the data does not work and returns nothing.
However, if I test it directly using-
_root.typeArr[_root.myType]=foo;
It will store the data once (_root.typeArr3=test), so I can't see why it won't push to that array as multiple elements each time like- "test,test,test"
It's driving me crazy.
Thanks! :)
_root.typeArr[_root.myType] is equal to "data goes here" so you are pushing string to a string, which doesn't work.
If you would like to append the new string, you should do something like:
_root.typeArr[_root.myType]+=foo;
and you will get: data goes heretest
If you have different data structure instead of "data goes here" the key may lie in the format of this data.
var typeArr:Array = new Array();
// 'i' must start from 0 because the first element is typeArr[0]
for (var i:Number = 0; i < 5; i++)
{
typeArr[i] = i;
// trace(typeArr[i]); // 0,1,2,3,4
}
// trace(typeArr); // 0,1,2,3,4
myType = 3;
bt.onPress = function()
{
var foo:String = "test";
// push method puts the element at the end of your array
// typeArr.push(foo);
// trace(typeArr); // 0,1,2,3,4,test
// splice method replace the 4e element (index 3) of your array
typeArr.splice(myType, 1, foo);
trace(typeArr); // 0,1,2,test,4
}

flash as3 how to prevent an item from being added to an array if it already exists in the array

I know how to remove duplicates from an array, but what I'm trying to do is prevent an item from ever being added to an array in the first place if it already exists. I'm pulling in data from an xml feed in a loop, and I thought that searching for that values index would work, but no matter what, the index is always -1. Here's my code:
var yearArr:Array = new Array();
for (var i=0;i<numCovers;i++){
var coverRef = xmlObj.cover[i];
var coverClip:MovieClip = new MovieClip();
coverClip.year = coverRef.#year;
if (yearArr.indexOf(coverClip.year === -1)){
yearArr.push (coverClip.year);
}
}
Maybe I'm misunderstanding the indexOf function, but I thought it was supposed to return -1 if a value did not exist in an array. What am I doing wrong?
Here's the solution I came up with:
var yearArr:Array = new Array();
for (var i=0;i<numCovers;i++){
var coverRef = xmlObj.cover[i];
var coverClip:MovieClip = new MovieClip();
coverYear = coverRef.#year;
addCoverYear(coverYear);
}
function addCoverYear(coverYear:int):void {
if (yearArr.indexOf(coverYear) == -1){
yearArr.push(coverYear);
}
}
you can reduce an array by passing everything to a dictionary, which will automatically remove redundancies. then pass the dictionary back as a new array.
//Reduce Array
private function reduceArray(array:Array):Array
{
var dictionary:Dictionary = new Dictionary();
for each (var element:String in array)
dictionary[element] = true;
var result:Array = new Array();
for (var key:String in dictionary)
result.push(key);
dictionary = null;
return result;
}
Your code is almost fine. The problem is that an E4X property .#year is not a literal string (I'm not sure right now, but I believe it's an XMLList object). That's why the indexOf call will keep returning -1, because it is looking for a duplicate of that object, not a string. E4X will convert it to a string as soon as you put it somewhere where only strings can go, but until that time it is something else.
If you rewrite your code like this, it should work right away:
var yearArr:Array = new Array();
for each (var coverRef : XML in xmlObj.cover){
var year : String = coverRef.#year; // force the property to be a string
if (yearArr.indexOf(year) < 0){
yearArr.push (year);
}
}
There were also a few other optimizations you could do to your code. The new MovieClip() part wasn't used, not all variables were strongly typed and by using a for each loop, you can state much clearer what objects you're looping through.
Here is what you could do, if for example, you have an array of strings.
var ItemList:Array = new Array();
for each(var Item:String in UseYourXMLFeed)
{
if(ItemList.indexOf(Item) == -1)
{
ItemList.push(Item);
}
}
Edit:
Anyways, your real answer is in the comment by Sam.

Resources