AS3

时间:2016-07-04 06:58:55

标签: actionscript-3

希望我能够合理地解释这一点。我遇到了一个问题,我在迭代一个对象并根据每个子对象的参数调用一个函数,然后覆盖返回对象的一些值,然后将它填充到一个自己的主数组中将迭代以创建屏幕上的对象。

这是一个场景基础架构,我在这里实例化一个场景交换机类,然后调用它的方法来确定这个场景需要哪些船只,然后我拉出所需的每个船类的“空白”示例,设置它们的一些这个场景的值是正确的,然后将它们提供给创建真实游戏对象的过程。

这是基本场景加载过程:

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

currentOOB对象如下所示:

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

这是拉动“空白”船的调用 - 一个对象已经设置了该给定船舶类的绝大多数属性,并且OOB对象包含我们将添加到的特定于场景的值空白的船。看起来像是:

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

所以我首先在国家/地区上切换,然后在传入的shipClass字符串上切换以返回特定的“空白”船舶对象。

问题在于:

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

如果您在OOB对象中注意到,则有多个具有相同shipClass值的船舶。有两个类“GB_74A_N”和两个类“GB_18_N”。第二次使用完全相同的参数调用上述函数(例如,shipCountry ==“GB”和shipClass ==“GB_74A_N”),返回的内容不是新的空白船只,而是对前一个示例的引用。

当我执行覆盖以将此船只示例设置为正确的值时,shipDataSide1或shipDataSide2中的上一个示例也会被覆盖:

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

因此,如果OOB对象具有相同shipClass的两个ship对象,那么shipDataSide1或shipDataSide2数组最终会丢失其中一个并且另一个副本丢失,这会在以后尝试绘制它们时混淆代码在屏幕上。

那我在这里做错了什么?我如何确保每次调用scenarioMasterObj.getShip(currentOOBShip.shipClass,currentOOBShip.country)时返回是一个“新鲜”对象而不是对现有对象的引用?经过一段时间的调试才弄明白发生了什么,我花了几个小时尝试试图绕过这个没有荒谬的蛮力方法,但没有运气。非常感谢帮助。

===========================更新=================== =========

我已经解决了这个问题,但是正如所指出的那样,这似乎是非常强大的力量,并且必须有一种更优雅的方式才能使其发挥作用。基本上我正在重新使用我们拉动“空白”船只的物体,因此每艘返回的船只与以前返回的任何船舶无关。

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

2 个答案:

答案 0 :(得分:0)

这很容易。您可以在getScenarioSideOOB()输出中为每艘船添加“已安装”服务参数,并最初将其分配给false。然后,当您调用scenarioMasterObj.getShip()时,它应该在OOB中的船上将installed设置为true,如果已经“安装”为真,则跳过匹配的船。

答案 1 :(得分:0)

如果没有人有更好的处理此类情况的建议,那么上述OP的更新中提供的答案必须有效。它的工作原理,当我知道某处有一个精确的工具时,就像使用大锤一样。