AS3创建对象数组

时间:2012-04-07 19:19:42

标签: actionscript-3 flash object

我想在舞台上添加一堆汽车,并将它们作为对象存储在一个数组中。问题是我讨厌使用外部AS文件,并希望尽可能简单。

我尝试过:

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)
}

问题是我是否尝试设置一个对象的值 test[1].carscale = 5

数组中的每个对象都将其属性carcale设置为5。

有没有办法在不使用外部类文件的情况下执行此操作?

4 个答案:

答案 0 :(得分:11)

虽然您应该使用外部AS文件(这是一个很好的做法),但这就是您遇到问题的原因,我将逐行解释

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

由于数组中的所有对象都指向同一位置,因此获取它们中的任何一个实际上都会返回相同的对象。这意味着所有这些都会将carscale显示为5

解决方法是:

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);
}

更好的, REAL 面向对象的解决方案是创建一个名为Car的类,然后代替

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

你使用

var car:Car = new Car();

Car.as类就是这样:

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;
}

实际上,您甚至可以使用另一个基于参数自动设置属性的构造函数:

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

并将其命名为

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

事实上,carcarcolorcarscale之前的carpower甚至不是必需的,因为当您将它们放在名为{{1}的类中时,显而易见}。

答案 1 :(得分:2)

就像TheDarkIn1978所说,你正在将你的car实例的引用推送到你的数组中。当您更改一个实例的属性的值时,每个引用都会发生相同的情况。

简单的答案是在for循环的每次交互时创建一个新对象,如下所示:

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]

我知道你说你不想使用“外部类”,但使用自定义类对象来存储值而不是Object对象是有好处的。这是一个例子:

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

这是创建一个对象的一个​​很好的例子,其唯一目的是存储永远不会改变的值,只允许在启动时设置对象的属性,并使用getter方法使值只读。

答案 2 :(得分:1)

我觉得愚蠢,我在这里找到答案: http://board.flashkit.com/board/showthread.php?t=792345

您每次都将Object引用推送到数组,而不是唯一的Object。你必须做类似的事情:

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

答案 3 :(得分:0)

您要多次向阵列添加相同的对象。你需要创建汽车对象的新实例。

编辑:

尽管最好的做法是创建自己的“Car”类并创建它的新实例,即使它只是一个具有3个属性的小对象,这里有一个简单的示例,可以帮助您入门。

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;
        }
    }
}