Actionscript 3.0: making an array of button instance names - arrays

In Flash, I created a grid of 400 buttons with instance names c0 through c399.
In Actionscript, I'd like to create an array like this:
var myArray:Array = [c0,c1,c2,c3,c4,c5,c6];
all the way up to c399.
I wrote a for-loop to do the trick, but it doesn't seem to be working:
import flash.events.MouseEvent;
//create the array
var myArray:Array = [];
for (var i:int=0;i<399;i++){
var cletter:String = 'c';
var p:String = i.toString();
var newvalue:String = cletter + p;
var shizzle:Object = new SimpleButton();
myArray[i] = shizzle;
}
for each(var btn in myArray){
btn.addEventListener(MouseEvent.CLICK, onBtnClick);
}
function onBtnClick(event:MouseEvent):void{
cellinfo.gotoAndStop(event.target.name);
}
When I publish it, no errors show up and nothing happens when I click the buttons. However, if I use
var myArray:Array = [c0,c1,c2,c3,c4,c5,c6];
it does work! (for the first 7 buttons at least).
Also, when I put:
for (var i:int=1;i<6;i++){
var cletter:String = 'c';
var p:String = i.toString();
var newvalue:Object = cletter + p;
myArray[i] = newvalue;
}
it says:
TypeError: Error #1006: value is not a function. at
PVproject1_fla::MainTimeline/frame1()
I just started working with AS3 + Flash and spent hours looking for a solution. Please help!

Your code is broken in more than one way.
for (var i:int=0;i<399;i++){
var cletter:String = 'c';
var p:String = i.toString();
var newvalue:String = cletter + p; // => this is never used
var shizzle:Object = new SimpleButton(); // => this creates a new (!) button
myArray[i] = shizzle;
}
Each of the 400 newly created buttons is never added to the stage, therefore you can't see it. And since it has no skin or other visual properties, you wouldn't be able to see it if it were.
The second for-loop puts only the names into the array - which causes the "value is not a function" error when you try to access the array values as buttons, because the value is really a string:
for (var i:int=1;i<6;i++){
var cletter:String = 'c';
var p:String = i.toString();
var newvalue:Object = cletter + p; // <= this is a String!
myArray[i] = newvalue;
}
Now apart from a fundamental doubt whether you'd really want to create 400 button instances by hand (I'd think about doing it in ActionScript and using this actual creation to fill the array), you can do the following - but remember: only if the button instances are already on the stage, and the loop is located in a frame script!
for (var i:int=0;i<399;i++){
myArray[i] = this["c"+i]; // no need for all the p and .toString() stuff, btw
}

Another solution is to just watch for them to be added to the stage and capture them at that point, similar to one of the examples you can download here http://flexdiary.blogspot.com/2010/04/sample-code-for-oop-timeline-insideria.html

Related

How to take instance name which numbering by array and the number can be operated?

The intention of the following ActionScript script is to allow a player to move by clicking a button, wherein myarray represents places they are allowed to move to.
I'm having trouble making my click event handler work properly. For example, how can I extract the (x, y) coordinates of the click from the MouseEvent event in order to perform further processing?
a.addEventListener(MouseEvent.CLICK, bergerak);
b.addEventListener(MouseEvent.CLICK, bergerak);
c.addEventListener(MouseEvent.CLICK, bergerak);
d.addEventListener(MouseEvent.CLICK, bergerak);
function bergerak (Event:MouseEvent) {
var namatombol:String = Event.currentTarget.name;
var myarray:Array = [];
for (var i:int = 0; i < 3; i++) {
myarray[i] = this["kotak" + i];
if (namatombol == "a") {
MovieClip(root).pemain.x = MovieClip(root).myarray[i].x;
MovieClip(root).pemain.y = MovieClip(root).myarray[i].y;
}
}
}
I understood that you're willing to move a player display object (like a MovieClip) to the clicked button position on stage. In this case, your function will be as follows:
function bergerak(event:MouseEvent):void
{
MovieClip(root).pemain.x = event.target.x;
MovieClip(root).pemain.y = event.target.y;
}

How to re add elements in array to their same position on stage?

Hey everyone so in my game I am creating I add all my interactive objects to the stage by simply dragging from the library and placing them on the stage. Then in Flash Develop in my Engine Class I place them inside an array like so:
private var aZebraArray:Array;
In my constructor I add the elements on the stage through their instance names I gave them Like so:
aZebraArray = [startScreen.zebra_Front, startScreen.zebra_Middle, startScreen.zebra_Back, startScreen.zebra_Far];
Then in my Enter_Frame Listener I loop through the objects on stage like so for the Hit Test:
private function Round_1Controls():void
{
trace(aZebraArray.length);
for (var i:int = 0; i < aZebraArray.length; i++)
{
var currentZebra = aZebraArray[i];
if (crosshair.bullet.hitTestObject(currentZebra) && shotGun)
{
trace("HIT");
aZebraArray.splice(i, 1);
currentZebra.gotoAndPlay("DIE");
shotGun = false;
//Add points
nPoints += 50;
updatePointsText();
//Animals hit for stars
animalsHit ++;
}
}
Now in my game if the player doesn't get 3 stars he is able to Retry and restart that round over. The PROBLEM That I have run into is that I don't quite know how I would go about having the objects that are on stage placed back where they first started from because when the round starts the "Zebras" run across the stage through a custom tween I made in each of them. Also I believe I could just create a new array like so:
aZebraArray = new Array();
aZebraArray = [startScreen.zebra_Front, startScreen.zebra_Middle, startScreen.zebra_Back, startScreen.zebra_Far];
but then how could i restart all their animations so they can run across the stage again? I know I can just create their own class and add them in array then control them through a timer object but I add them manually on stage because their are a lot of bushes that they need to hide behind or be in front of and to code that would be exhausting. If anyone can help I would Appreciate it thanks!
Here is what I have in my retry Function but it is only adding 1 or 2 of the objects in the array back to the stage.
private function replayRound_1(e:MouseEvent):void
{
continueScreen.mcRetry.removeEventListener(MouseEvent.CLICK, replayRound_1);
continueScreen.destroyContinueScreen();
round1 = true;
nAmmo = 0;
nAmmo += 5;
updateAmmoText();
animalsHit = 0;
hasAmmo = true;
gameChannel = gameSound.play(0, 999);
//aZebraArray = [];
aZebraArray = new Array();
aZebraArray = [startScreen.zebra_Front, startScreen.zebra_Middle, startScreen.zebra_Back, startScreen.zebra_Far];
for (var i:int = 0; i < aZebraArray.length; i++)
{
var currentZebra = aZebraArray[i];
currentZebra.gotoAndStop("RUN");
}
}

Use value from array to set addeventListner to multiple buttons

I'm making a game that have multiple instance of a MC in stage (a1,b1,c1....a2,b2,c2,d2,etc)
Every time to make a listener i have to write
Object(this).sopa.c1.btn.addEventListener(MouseEvent.CLICK, c1Click);
and create a function like this
function c1Click(event:MouseEvent):void
{
checkString += "c1";
var TFc1:TextFormat = Object(this).sopa.c1.letra.getTextFormat(0,1);
TFc1.color = 0xff0022;
Object(this).sopa.c1.letra.setTextFormat(TFc1);
check();
}
but whit that many buttons (more than 100) is to long writing them one by one.
So i think put the values (instance names) of the buttons in an array. Something like this
var casillas:Array = [a1, b1,c1];
for (var i:uint = 0; i < casillas.length; i++)
{
casillas[i].addEventListener(MouseEvent.CLICK, a1presion);
trace(casillas[i])
}
but i cant get the value of the array element just a [object SimpleButton].Have anyone any ideas how to do this: I'm new in as3 i worked all my life in as2 and this is way to hard to understand for me.
This is where Object Oriented Programming shines. You encapsulate all properties and methods into a single object. You can then create as many of these objects, and watch as they function individually with the behavior specified inside.
Here's a simple button class I sometimes use myself:
package buttons {
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class SimpleButton extends MovieClip {
public function SimpleButton() {
addEventListener(MouseEvent.MOUSE_OVER, mOver);
addEventListener(MouseEvent.MOUSE_OUT, mOut);
addEventListener(MouseEvent.MOUSE_DOWN, mDown);
buttonMode = true;
}
protected function mOver(e:MouseEvent):void {
gotoAndStop(2);
}
protected function mOut(e:MouseEvent):void {
gotoAndStop(1);
}
protected function mDown(e:MouseEvent):void {}
}
}
Then create as many instances as you like, and store them in some container so that you can get rid of them at some point in the destruction of the program.
var buttons:Vector.<SimpleButton> = new Vector.<SimpleButton>();
buttons.push(new SimpleButton());
buttons.push(new SimpleButton());
buttons.push(new SimpleButton());
Firstly, I have to agree with Iggy, what you are trying to do will ultimately be more re-usable and easy to understand if it were written using Object Oriented code.
However, from what you have already written, I think you are saying is that you are struggling to create an event handler that is generic to all your buttons? So if you need to get the string name of the MovieClip as well as the actual clip reference maybe you could do something like this:
var casillas:Array = ["a1", "b1", "c1"]; //Have an array of the names of the buttons
for (var i:uint = 0; i < casillas.length; i++)
{
var mcReference:MovieClip = this.sopa[ casillasNames[i] ]; //Use the string reference to get hold of the button
mcReference.btn.addEventListener(MouseEvent.CLICK, _handleButtonClick); //Add a listener to the same "btn" child of the casilla as you did before.
}
you need a listener
function _handleButtonClick(e:Event)
{
var buttonReference:* = e.target;
So e.target in this instance should be the same object that you added to the array earlier (a1 or b1 or c1 depending on which one is clicked)
Now I'm going to make some leaps about how those MovieClips (a1,b1,c1) are structured (I'm guessing they are all the same just with different data in?)
function _handleButtonClick(event:MouseEvent):void
{
var clickedButtonReference:* = e.target;
for(var i:int = 0; i< casillas.length; i++)
{
if(this.sopa[ casillasNames[i] ].btn == clickedButtonReference) //Check each button on the stage to see if it is the one that has been clicked.
{
checkString += casillasNames[i];
//To find this bit "this.sopa.c1.letra" there are two options either
var selectedLetra = this.sopa[ casillasNames[i] ].letra; //Using the string name of the MC to find it.
//or
var selectedLetra = clickedButtonReference.parent.letra; //Or using the fact that we know that the original MC contains both the btn and the letra as children.
//Once we have it though the rest of your function should work ok.
var TFc1:TextFormat= selectedLetra.getTextFormat(0,1)
TFc1.color = 0xff0022;
selectedLetra.setTextFormat(TFc1);
check();
//Just add a break to stop searching for the button since we have found it.
break;
}
}
}

AS3 Button reference in an array

I have two buttons that are in a movieclip, how can I reference them like I have done with the 2 buttons below so that they can be added into an array?
container.anotherButton and container.anotherButton2 are the buttons I want to add to the array.
var agreeButton:SimpleButton;
var disagreeButton:SimpleButton;
var buttonArray:Array = new Array(agreeButton, disagreeButton);
for (var i:int = 0; i < buttonArray.length; i++) {
buttonArray[i].addEventListener(MouseEvent.CLICK, mouseClick);
}
I am not sure what the question is, I think this is what you need.
var buttonArray:Array = new Array(container.anotherButton, container.anotherButton2);
The reference will hold even if you move the container/buttons.

Flex - Objects within Objects

So I'm still trying to get my head around Flex and OOP and I am stuck right now. Here is the code I'm currently working with.
var labs:ArrayCollection = new ArrayCollection();
var sets:ArrayCollection = new ArrayCollection();
var labsArray:Array = ["ProDPI","WHCC","Tin"];
var setsArray:Array = [ ["Set01","Set02","Set03","Set04"],["Set11","Set12","Set13","Set14"], ["Set21","Set22","Set23","Set24"] ];
var objLab:Object = new Object;
objLab.labName = labsArray[0];
objLab.setFolders = undefined;
labs.addItem(objLab);
for (var i:int = 0; i < setsArray.length; i++) {
var objSets:Object = new Object;
objSets.setName = setsArray[i];
sets.addItem(objSets);
objLab.setFolders = objSets;
}
labFolderList.labelField="labName";
labFolderList.dataProvider=labs;
setFolderList.labelField="setFolders";
setFolderList.dataProvider=sets;
The objLab object is returning as I wish it to. The objSets is displaying in my ComboBox as object, Object. The application is ComboBox #1 will be populated by labsArray, which is working. Depending on the selection of [0,1,2] from the array this will call from the sets array the array in the matching position.
Finally, with the selection of the ComboBox#1, the second ComboBox#2 will change to the matching selection.
Any help on how to get the object Objects to rendering correctly would be of great help. Also if my execution is not the best way to do this any direction (links/documentation) I will take as well. Thanks in advance.
I edited your original code based on assumptions for what you were trying to accomplish, I added the Array objects directly to the collection being assigned the dataprovider, in this case you should see the output of the .toString() method called on the Array instead of the Object class, the Object class .toString() will output the [object Object] you were seeing in the display. The Array .toString() method will call .toString() on each element in the array and separate them with commas and surround them with curly braces, very similar to what you have when defining the array. Alternatively you could create your own class that extends Object and make your own toString method to override the default behavior, using Object is generally not a great practice (there are exceptions to this it's not a hard rule but it tends to be better to use a specific class type, or even better an interface when possible).
var labs:ArrayCollection = new ArrayCollection();
var sets:ArrayCollection = new ArrayCollection();
var labsArray:Array = ["ProDPI","WHCC","Tin"];
var setsArray:Array = [ ["Set01","Set02","Set03","Set04"],["Set11","Set12","Set13","Set14"], ["Set21","Set22","Set23","Set24"] ];
var objLab:Object = new Object;
objLab.labName = labsArray[0];
objLab.setFolders = undefined;
labs.addItem(objLab);
for (var i:int = 0; i < setsArray.length; i++) {
sets.addItem(setsArray[i]);
objLab.setFolders = setsArray[i];
}
labFolderList.labelField="labName";
labFolderList.dataProvider=labs;
setFolderList.labelField="setFolders";
setFolderList.dataProvider=sets;
Another alternative aside from making a Class as I explained above is to use the labelFunction instead of the labelField, using a labelFunction each item:Object in the dataProvider will be passed into your custom labelFunction and you can return a string based on whatever logic you see fit. It would be something along these lines:
setFolderList.labelFunction = myLabelFunction;
private function myLabelFunction(item:Object):String
{
var retString:String = "";
for(var i:int=0; i<item.setName.length; i++)
{
if(i>0)
retString += ", ";
retString += item.setName[i];
}
return retString;
}

Resources