2016-07-04 5 views
0

Ich hoffe, ich kann das ziemlich gut erklären. Ich habe ein Problem, bei dem ich durch ein Objekt iteriere und eine Funktion auf der Grundlage der Parameter jedes der Unterobjekte aufruft, dann einige der Werte des zurückgegebenen Objekts überschreibt und es dann in ein Master-Array stopft, das selbst ist wird durchlaufen, um Bildschirmobjekte zu erstellen.Referenz Ausgabe in AS3

Es ist eine Szenario-Infrastruktur, wo ich eine Szenario-Vermittlungsstelle Klasse und dann rufen Sie ihre Methoden, um herauszufinden, welche Schiffe ich für dieses Szenario brauche, dann ziehe ich "leere" Beispiele für jede der erforderlichen Schiffsklassen, setzen Sie einige ihre Werte stimmen für dieses Szenario überein und führen sie dann in den Prozess ein, der die echten Spielobjekte erzeugt.

Dies ist der Basisszenario Ladevorgang:

//instance scenario loader class 
     var scenarioMasterObj:LOB_Scenario_Data = new LOB_Scenario_Data(); 

     //first grab the scenario settings object which has all of the data like short description, long description, date battle occured, balance, basically everything but the ship OOBs 
     //this data will be used to render the scenario selection screen and post-battle results screen. We just pass the scenario number 
     var scenarioSettigs:Object = scenarioMasterObj.getScenarioSettings(1); 

     //there are two side-specific OOBs (Orders of Battle, lists of ships for the scenario) to load 
     for (var OOBToggle:int = 1; OOBToggle < 3; OOBToggle++) { 

      var currentOOB:Object = new Object(); 

      if (1 == OOBToggle) { 

       currentOOB = scenarioMasterObj.getScenarioSideOOB(1, 1); 
      } 

      else { 

       currentOOB = scenarioMasterObj.getScenarioSideOOB(1, 2); 
      } 

      //specific ship objects we'll need 
      var currentOOBShip:Object = new Object(); 
      var finalOOBShip:Object = new Object(); 

      //iterate through the current OOB to create the list of ships used in ship creation for side 1 or 2 
      for each (var currentOOBShip:Object in currentOOB) { 

       //pull final ship data based on shipClass and country properties of the OOB ships 
       finalOOBShip = scenarioMasterObj.getShip(currentOOBShip.shipClass, currentOOBShip.country); 

       //set scenario-specific values copying from the ship in the scenario OOB object 
       finalOOBShip.name = currentOOBShip.name; 
       finalOOBShip.sailState = currentOOBShip.sailState; 
       finalOOBShip.shotType = currentOOBShip.shotType; 
       finalOOBShip.crewQuality = currentOOBShip.crewQuality; 
       finalOOBShip.column = currentOOBShip.column; 
       finalOOBShip.row = currentOOBShip.row; 
       finalOOBShip.column2 = currentOOBShip.column2; 
       finalOOBShip.row2 = currentOOBShip.row2; 
       finalOOBShip.direction = currentOOBShip.direction; 

       //push to the array that will be iterated through to create the on-screen ship objects 
       if (1 == OOBToggle) { 

        shipDataSide1.push(finalOOBShip); 
       } 

       else { 

        shipDataSide2.push(finalOOBShip); 
       } 
      } 
     } 

Das currentOOB Objekt wie folgt aussieht:

public function getOOB(side:int):Object { 

     var return_Scen_OOB:Object = new Object(); 

     if (1 == side) { 

      return_Scen_OOB = { 

       Ship1: {shipClass: "GB_90_N", name: "London", country: "GB", column: 7, row: 7, column2: 7, row2: 8, direction: 4, sailState: "battle", shotType: "round", crewQuality: "Crack"}, 
       Ship2: {shipClass: "GB_74A_N", name: "Impetueux", country: "GB", column: 7, row: 9, column2: 7, row2: 10, direction: 4, sailState: "battle", shotType: "round", crewQuality: "Crack"}, 
       Ship3: {shipClass: "GB_74A_N", name: "Courageux", country: "GB", column: 7, row: 11, column2: 7, row2: 12, direction: 4, sailState: "battle", shotType: "round", crewQuality: "Average"}, 
       Ship4: {shipClass: "GB_74B_N", name: "Captain", country: "GB", column: 1, row: 1, column2: 1, row2: 1, direction: 1, sailState: "battle", shotType: "round", crewQuality: "Elite"}, 
       Ship5: {shipClass: "GB_38_N", name: "Indefatigable", country: "GB", column: 7, row: 15, column2: 7, row2: 16, direction: 4, sailState: "battle", shotType: "round", crewQuality: "Crack"}, 
       Ship2: {shipClass: "GB_38_N", name: "Amelia", country: "GB", column: 1, row: 1, column2: 1, row2: 1, direction: 1, sailState: "battle", shotType: "round", crewQuality: "Average"}, 

       Ship6: {shipClass: "GB_36A_N", name: "Amethyst", country: "GB", column: 1, row: 1, column2: 1, row2: 1, direction: 1, sailState: "battle", shotType: "round", crewQuality: "Crack"}, 
       Ship7: {shipClass: "GB_32B_N", name: "Stag", country: "GB", column: 1, row: 1, column2: 1, row2: 1, direction: 1, sailState: "battle", shotType: "round", crewQuality: "Crack"}, 
       Ship8: {shipClass: "GB_28_N", name: "Brilliant", country: "GB", column: 1, row: 1, column2: 1, row2: 1, direction: 1, sailState: "battle", shotType: "round", crewQuality: "Average"}, 

       Ship9: {shipClass: "GB_18_N", name: "Cynthia", country: "GB", column: 7, row: 7, column2: 7, row2: 8, direction: 4, sailState: "battle", shotType: "round", crewQuality: "Crack"}, 
       Ship10: {shipClass: "GB_18_N", name: "Saint Vincent", country: "GB", column: 25, row: 30, column2: 25, row2: 31, direction: 4, sailState: "battle", shotType: "round", crewQuality: "Crack"} 
      }     
     } 

Dies ist der Anruf, wo er das „leere“ Schiff zieht - ein Objekt, das die hat Die meisten Eigenschaften für die angegebene Schiffsklasse sind bereits festgelegt, und das OOB-Objekt enthält die szenariospezifischen Werte, die wir dem leeren Schiff hinzufügen. Das sieht aus wie:

//After receiving the list of ships from getScenarioSideOOB(), game iterates through those lists calling this function to set up the game's master ship side arrays 
    public function getShip(shipClass:String, shipCountry:String) { 

     var returnShip:Object = new Object(); 

     //bummer here is we have to know what classes exist, so if any are added code must change here as well 
     switch(shipCountry) { 
      case "GB": 

       switch(shipClass) { 

        case "GB_120_N": 

         returnShip = shipList_GB.GB_120_N; 
         break; 

        case "GB_110_N": 

         returnShip = shipList_GB.GB_110_N; 
         break; 

        case "GB_100_N": 

         returnShip = shipList_GB.GB_100_N; 
         break; 

        case "GB_98_N": 

         returnShip = shipList_GB.GB_98_N; 
         break; 

        case "GB_90_N": 

         returnShip = shipList_GB.GB_90_N; 
         break; 

        case "GB_80_N": 

         returnShip = shipList_GB.GB_80_N; 
         break; 

        case "GB_74A_N": 

         returnShip = shipList_GB.GB_74A_N; 
         break; 

        case "GB_74B_N": 

         returnShip = shipList_GB.GB_74B_N; 
         break; 

Also ich zum ersten Mal auf Land wechsle und dann auf der übergebenen in Schiffsklasse String ein bestimmtes „blank“ Schiff Objekt zurückzukehren.

Das Problem ist hier:

//pull final ship data based on shipClass and country properties of the OOB ships 
       finalOOBShip = scenarioMasterObj.getShip(currentOOBShip.shipClass, currentOOBShip.country); 

Wenn Sie in dem OOB Objekt auffallen werden, mehr als ein Schiff von identischer Schiffsklasse Wert ist. Es gibt zwei mit der Klasse "GB_74A_N" und zwei mit der Klasse "GB_18_N". Wenn die obige Funktion zum zweiten Mal mit genau denselben Parametern aufgerufen wird (z. B. shipCountry == "GB" und shipClass == "GB_74A_N"), wird nicht ein neues leeres Schiff zurückgegeben, sondern ein Verweis auf das vorherige Beispiel.

Und wenn ich die Überschreibungen tun, um dieses Schiffs Beispiel auf die korrekten Werte zu setzen, wird das vorherige Beispiel in shipDataSide1 oder shipDataSide2 auch überschreibt:

//set scenario-specific values copying from the ship in the scenario OOB object 
       finalOOBShip.name = currentOOBShip.name; 
       finalOOBShip.sailState = currentOOBShip.sailState; 
       finalOOBShip.shotType = currentOOBShip.shotType; 
       finalOOBShip.crewQuality = currentOOBShip.crewQuality; 
       finalOOBShip.column = currentOOBShip.column; 
       finalOOBShip.row = currentOOBShip.row; 
       finalOOBShip.column2 = currentOOBShip.column2; 
       finalOOBShip.row2 = currentOOBShip.row2; 
       finalOOBShip.direction = currentOOBShip.direction; 

Also, wenn die OOB Objekt hat zwei Schiff Objekte mit demselben shipClass, schließlich enden die shipDataSide1- oder shipDataSide2-Arrays mit einem fehlenden und zwei Kopien des anderen, was den Code später beim Versuch, sie auf dem Bildschirm zu zeichnen, verwirrt.

Also, was mache ich hier falsch? Wie stelle ich bei jedem Aufruf von scenarioMasterObj.getShip (currentOOBShip.shipClass, currentOOBShip.country) sicher, dass die Rückgabe ein "frisches" Objekt und keine Referenz auf ein vorhandenes Objekt ist? Es dauerte ziemlich lange, bis ich entschlüsselt hatte, was vor sich ging, und ich habe ein paar Stunden damit verbracht, zu experimentieren, um das ohne lächerliche Brute-Force-Methoden zu umgehen, aber ich hatte kein Glück. Hilfe wäre sehr willkommen.

=========================== UPDATE ================== ==========

Ich habe das Problem behoben, aber wie bereits erwähnt, scheint es sehr rohe Gewalt und es muss eine elegantere Möglichkeit, um es funktionieren zu lassen. Im Grunde stelle ich das Objekt wieder her, von dem wir die "leeren" Schiffe ziehen, also hat jedes zurückgeschickte Schiff nichts Bezug zu einem zuvor zurückgeschickten Schiff.

//After receiving the list of ships from getScenarioSideOOB(), game iterates through those lists calling this function to set up the game's master ship side arrays 
    public function getShip(shipClass:String, shipCountry:String) { 

     var returnShip:Object = new Object(); 

     //bummer here is we have to know what classes exist, so if any are added code must change here as well 
     switch(shipCountry) { 
      case "GB": 

       switch(shipClass) { 

        case "GB_120_N": 

         var shipList_GB_Source:LOB_Ships_GB = new LOB_Ships_GB; 
         var shipList_GB = shipList_GB_Source.shipClasses_GB; 

         returnShip = shipList_GB.GB_120_N; 
         break; 

        case "GB_110_N": 

         var shipList_GB_Source:LOB_Ships_GB = new LOB_Ships_GB; 
         var shipList_GB = shipList_GB_Source.shipClasses_GB; 

         returnShip = shipList_GB.GB_110_N; 
         break; 

        case "GB_100_N": 

         var shipList_GB_Source:LOB_Ships_GB = new LOB_Ships_GB; 
         var shipList_GB = shipList_GB_Source.shipClasses_GB; 

         returnShip = shipList_GB.GB_100_N; 
         break; 

        case "GB_98_N": 

         var shipList_GB_Source:LOB_Ships_GB = new LOB_Ships_GB; 
         var shipList_GB = shipList_GB_Source.shipClasses_GB; 

         returnShip = shipList_GB.GB_98_N; 
         break; 

Antwort

0

Das ist einfach.Sie fügen jedem Schiff unter einen Service-Parameter "installiert" hinzu und weisen ihn zunächst false zu. Dann, wenn Ihr scenarioMasterObj.getShip() aufgerufen wird, sollte es installed zu True auf dem Schiff in OOB setzen und das entsprechende Schiff überspringen, wenn es bereits als "True" installiert hat.

+0

Danke, aber das funktioniert nicht - wir brauchen jedes Schiff in der OOB, unabhängig davon, ob seine Klasse mit einer anderen übereinstimmt. Denken Sie an vier Fregatten der Royal Navy der gleichen Klasse, die alle bis auf den Namen identisch sind. Und es handelt sich nicht um ein Problem, bei dem es versehentlich wiederholt wird. Wenn es ein zweites Beispiel einer shipClass + Country-Kombination zieht, erstellt es einen neuen Eintrag in shipDataSide1 oder 2, ändert jedoch gleichzeitig die Werte des vorherigen Eintrags mit dieser Kombination, um mit der neuesten übereinzustimmen - klar, dass beide Einträge im Array das exakt gleiche Objekt sind. – vossiewulf

+0

Dann müssen Sie switch-case von 'getShip()' ablegen, da Ihre Klassen nicht eindeutig den Schiffsinstanzen entsprechen. Stattdessen tust du einen für jeden Zyklus und überprüfst alle Länder, Klassen und "installierten" Eigenschaften, um gültig zu sein, sobald alle gültig sind, ändere die Installation auf "Wahr" und gib das Schiff zurück. – Vesper

+0

Siehe Update oben. – vossiewulf

0

Wenn niemand einen besseren Vorschlag für den Umgang mit dieser Art von Situation hat, als die oben im Update zu meinem OP angegebene Antwort muss stehen. Es funktioniert, es fühlt sich an, als würde man einen Vorschlaghammer benutzen, wenn ich weiß, dass es da draußen ein präzises Werkzeug dafür gibt.