3

我想在舞台上添加一堆汽车,并将它们作为对象存储在数组中。问题是我讨厌使用外部 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

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

有什么方法可以在不使用外部类文件的情况下做到这一点?

4

4 回答 4

12

虽然您应该使用外部 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);
}

一个更好的、真正的面向对象的解决方案是创建一个名为 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);

事实上,carbeforecarcolorcarscale甚至carpower没有必要,因为当你把它们放在一个名为 的类中时很明显Car

于 2012-04-08T06:28:13.507 回答
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

[更新]

我知道您说过您不想使用“外部类”,但是与对象相比,使用自定义类对象来存储值是有好处的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 方法使值只读。

于 2012-04-07T19:55:52.637 回答
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);
}
于 2012-04-08T05:41:05.150 回答
0

您多次将相同的对象添加到数组中。您需要创建汽车对象的新实例。

编辑:

尽管创建自己的“汽车”类并创建它的新实例是最佳实践,即使它只是一个具有 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;
        }
    }
}
于 2012-04-07T19:43:16.807 回答