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;
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
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
Siehe Update oben. – vossiewulf