2012-04-07 5 views
3

Я хотел бы добавить кучу автомобилей на сцену и сохранить их в массиве как объекты. Проблема в том, что я ненавижу использование внешних AS-файлов и хотел бы сохранить ее максимально простой.AS3 Создание массива объектов

Я попытался сделать:

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

Я предлагаю вам использовать внешние файлы как файлы и особенно создавать класс Car.as для хранения информации. Таким образом, вы можете добавить гибкость в свое приложение и сделать его более легким для отладки/поддержки во времени. –

ответ

0

Вы добавляете один и тот же объект к массиву несколько раз. вам нужно создать новые экземпляры вашего автомобиля.

EDIT:

хотя бы лучшая практика, чтобы создать свой собственный класс «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; 
     } 
    } 
} 
+0

@ TheDarkIn1974 Я был просто посреди написания примера, а затем вы передо мной передо мной. В любом случае, возможно, вы захотите добавить, что он может просто исправить эту проблему со следующим утверждением 'test.push ({carcolor: String, carscale: Number, carpower: Number});' – Taurayi

2

Как TheDarkIn1978 сказал, что вы толкая ссылку вашего car экземпляра в массиве. Когда вы изменяете значение свойства одного экземпляра, это происходит и для каждой ссылки.

Простой ответ заключается в создании нового объекта при каждом Интерактивного из ваших цикл, как в следующем:

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 

Это хороший пример создания объекта с единственной целью хранения значений, которые никогда не изменяются, позволяя лишь свойства объекта, которые будут установлены после инициирования и с помощью методов получения, чтобы значения только для чтения.

+0

задал вопрос, чтобы ответить именно на это) – www0z0k

1

Я чувствую себя тупой, я нашел ответ здесь: http://board.flashkit.com/board/showthread.php?t=792345

Вы толкая ссылку на объект массива, а не уникальный объект каждый раз. Вы должны сделать что-то вроде:

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

точно, что вам сказали все остальные ответы. Зачем искать в другом месте? –

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

Лучше, РЕАЛ объектно-ориентированное решение было бы создать класс под названием 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); 

Фактически, car до carcolor, carscale и carpower даже не требуется, потому что это очевидно, когда вы помещаете их в класс под названием Car.

+1

Довольно универсальное объяснение, которое работает и для Java. –

Смежные вопросы