AS3 Create array of objects

I would like to add a bunch of cars to the scene and store them in an array as objects. The problem is, I hate using external AS files and want to keep it as simple as possible.

I've tried doing:

var car:Object = {carcolor:String,carscale:Number,carpower:Number};
var test:Array = new Array()
for (var i:Number=0; i<10; i++) {
    test.push(car)
}

      

The problem is I am trying to set the value of one object in a similar test[1].carscale = 5

Each object in the array receives a carcale attribute set to 5.

Is there a way to do this without using external class files?

+3


source to share


4 answers


While you should be using external AS files (this is good practice), this is why you have a problem and I will explain in turn

var car:Object = {carcolor:String,carscale:Number,carpower:Number};
//This creates an object called car. Suppose it saves it in memory at "location" 0x12345

var test:Array = new Array();
//This creates an empty array

for (var i:Number=0; i<10; i++) {
    test.push(car);
    //This adds the object "car" to the array
    //Since Object is a reference type, its memory location is actually added to the array
    //This means you added 0x12345 to the array (10 times over the loop)
}

//The array now contains 
[0x12345, 0x12345, 0x12345, .......];

//So now
test[1]; //returns the object at 0x12345

test[1].carscale=5;  //sets the carscale property of the object at 0x12345

      

Since all objects in the array point to the same location, getting any of them will actually return the same object. This means that they will all show carscale

as 5

The solution to this would be:

var test:Array = new Array();
for (var i:Number=0; i<10; i++) {
    var car:Object = {carcolor:String,carscale:Number,carpower:Number};
    test.push(car);
}

      

Better, REAL Object oriented solution would be to create a Car class and then instead of

var car:Object = {carcolor:String,carscale:Number,carpower:Number};

      

you're using



var car:Car = new Car();

      

The class Car.as

will be like this:

public class Car {
    public function Car() {
        //this is the constructor, initialize the object here
        //Suppose the default values of the car are as follows:
        carcolor="red";
        carscale=5;
        carpower=1000;
    }

    public var carcolor:String;
    public var carscale:Number, carpower:Number;
}

      

In fact, you could even use a different constructor that automatically sets properties based on arguments:

    public function Car(_color:String, _scale:Number, _power:Number) {
        carcolor=_color;
        carscale=_scale;
        carpower=_power;
    }

      

and call it

var car:Car=new Car("red", 5, 1000);

      

In fact, car

before carcolor

, carscale

and carpower

not even required, because it's obvious when you put them in a named class car

.

+11


source


Like TheDarkIn1978, you click your instance link car

into your array. When you change the value of a property on one instance, this happens for every reference.

The simple answer is to create a new object every time the for loop interacts, as in the following:

var test:Array = [];

for (var i:Number = 0; i < 10; i++) 
{
    var car:Object = {carcolor:String, carscale:Number, carpower:Number};    
    test.push(car);

}// end for

      

[UPDATE]



I know you said you didn't want to use "external classes", but there are advantages to using a custom class object to store values ​​rather than an object Object

. Here's an example:

package 
{
    import flash.display.Sprite;
    import flash.events.Event;

    public class Main extends Sprite 
    {
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);

        }// end function

        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);

            var cars:Vector.<Car> = new Vector.<Car>();

            cars.push(new Car("red", 1, 1));
            cars.push(new Car("blue", 2, 2));
            cars.push(new Car("green", 3, 3));

            trace(cars[2].color); // output: green

        }// end function

    }// class

}// end package

internal class Car
{
    private var _color:String;
    private var _scale:Number;
    private var _power:Number;

    public function get color():String { return color; }
    public function get scale():String { return scale; }
    public function get power():String { return power; }

    public function Car(color:String, scale:Number, power:Number)
    {
        _color = color;
        _scale = scale;
        _power = power;

    }// end function

}// end class

      

This is a good example of creating an object for the sole purpose of storing values ​​that never change, only allowing the properties of the object to be set on initialization, and using getter methods to make the values ​​read-only.

+2


source


I feel dumb, I found the answer here: http://board.flashkit.com/board/showthread.php?t=792345

You are clicking an Object reference to an array, not a unique object each time. You should do something like:

for(var temp=0;temp<100;temp++){
    var roomData:Object=new Object;
    roomData.first_time=true;
    rooms.push(roomData);
}

      

+1


source


you are adding the same object to the array multiple times. you need to create new instances of your car object.

EDIT:

While it would be better to create your own Car class and create new instances of it, even if it's just a small object with 3 properties, here's a quick example to get you started.

package 
{
    //Imports
    import flash.display.Sprite;

    //Class
    public class Main extends Sprite 
    {
        //Constants
        private static const DEFAULT_CAR_COLOR:Number = 0x000000;
        private static const DEFAULT_CAR_SCALE:Number = 1.0;
        private static const DEFAULT_CAR_POWER:int = 50;

        //Properties
        private var carsArray:Array;

        //Constructor
        public function Main():void 
        {
            init();

            outputCarColors();
        }

        //Initialize
        private function init():void
        {
            carsArray = new Array();

            for (var i:int = 0; i < 10; i++)
            {
                carsArray.push(CreateCar(Math.random() * 0xFFFFFF));
            }
        }

        //Output Car Colors
        private function outputCarColors():void
        {
            for (var i:int = 0; i < carsArray.length; i++)
            {
                trace("Color of car " + i + " : " + carsArray[i].carColor);
            }
        }

        //Create Car Object
        private function CreateCar(carColor:Number = DEFAULT_CAR_COLOR, carScale:Number = DEFAULT_CAR_SCALE, carPower:int = DEFAULT_CAR_POWER):Object
        {
            var result:Object = new Object();
            result.carColor = carColor;
            result.carScale = carScale;
            result.carPower = carPower;

            return result;
        }
    }
}

      

0


source







All Articles