AS3 - 更新阵列后自动刷新显示

时间:2015-07-10 21:08:17

标签: arrays actionscript-3 refresh

所以,基本上我通过尝试在flash中制作一种电子表格来重新发明轮子,以跟踪游戏中的成员增长。在这一节中,我将成员名称添加到数组中,然后将名称放入动态创建的图块中,并附加文本字段以显示名称。

我有一个保存按钮,用于保存数组,如果我保存,关闭并重新打开,那么我可以看到我添加的成员。但是,我希望在更改数组后立即刷新阶段以反映所做的更改(更新电子表格)。我还将动态添加和删除其他磁贴,但我可以稍后将解决方案推广到所有这些问题。

这是我必须添加成员并创建显示的代码:

public var mainArray:Array = new Array;
public var i1:Number = 0;
public var memberBox:MovieClip = new MovieClip();
public var MAX_ROWS = 0;
public var MAX_COLS = 0;

public function Tracker() {
    MAX_COLS = mainArray.length - 1;
    addBtn.addEventListener(MouseEvent.CLICK, addFun); //atchaed to button on stage
    public function addFun($e:MouseEvent):void{
        mainArray[i1] = [];
        mainArray[i1][0] = addNameTxt.text //attached to textfield on stage
        i1++;
        loadMembers();

    public function loadMembers():void{

        var multiDimensionalArray:Array = new Array();


        //initalize the arrays
        for (var row = 0; row <= MAX_ROWS; row++)
        {
            var boolArray:Array = new Array();

            for (var col = 0; col <= MAX_COLS; col++){
                boolArray.push(false);
            }

            multiDimensionalArray.push(boolArray);
        }

        //now we can set the values of the array as usual
        for (var row = 0; row <= MAX_ROWS; row++)
        {
            for (var col = 0; col <= MAX_COLS; col++){

                multiDimensionalArray.push(1); ;
            }
        }
        //create a column of tiles based on mainArray length with a textfield attached to each
        buildLevel(multiDimensionalArray);

    }

        public function buildLevel(s:Array){
            var txtArray:Array = new Array();
            memberBox.name = "tileHolder";
            for(var i=0; i  < MAX_ROWS + 1; i++){
                for(var o=0; o < MAX_COLS + 1; o++){
                    var currentTile:MemberBox = new MemberBox();
                    currentTile.x = i*150;
                    currentTile.y = o*25;
                    currentTile.name = "b"+o;
                    memberBox.addChild(currentTile);
                    //currentTile.gotoAndStop(int(s[o][i]));
                    var memberTxt:TextField=new TextField(); 
                    currentTile.addChild(memberTxt);
                    memberTxt.width = 150;
                    memberTxt.height = 25;
                    txtArray[o] = memberTxt;
                    txtArray[o].text = mainArray[o][0];

                    }

                }

                memberBox.x = 60;
                memberBox.y = 170;
                addChild(memberBox);

            }


}

1 个答案:

答案 0 :(得分:0)

理想的解决方案是将事件侦听器附加到Array,但是,Arrays不会触发事件。

解决方案#1:托管更新

不是允许任何代码段直接修改数组,而是编写一个处理更新数组的函数。这样,您就可以知道何时同时更新显示。

public var mainArray:Array = new Array;
public var i1:Number = 0;
public var memberBox:MovieClip = new MovieClip();
public var MAX_ROWS = 0;
public var MAX_COLS = 0;

public function Tracker() {
    MAX_COLS = mainArray.length - 1;
    addBtn.addEventListener(MouseEvent.CLICK, addFun); //attached to button on stage

    public function addFun(e:MouseEvent):void {
        mainArray[i1] = [];
        mainArray[i1][0] = addNameTxt.text //attached to textfield on stage
        i1++;
        loadMembers();
    }

    public function loadMembers():void {
        var multiDimensionalArray:Array = new Array();

        //initalize the arrays
        for (var row = 0; row <= MAX_ROWS; row++) {
            var boolArray:Array = new Array();

            for (var col = 0; col <= MAX_COLS; col++) {
                boolArray.push(false);
            }

            multiDimensionalArray.push(boolArray);
        }

        //now we can set the values of the array as usual
        for (var row = 0; row <= MAX_ROWS; row++) {
            for (var col = 0; col <= MAX_COLS; col++) {
                multiDimensionalArray.push(1); ;
            }
        }
        //create a column of tiles based on mainArray length with a textfield attached to each
        buildLevel(multiDimensionalArray);

    }

    public function buildLevel(s:Array) {
        var txtArray:Array = new Array();
        memberBox.name = "tileHolder";
        for (var i:int = 0; i < MAX_ROWS + 1; i++) {
            for(var o=0; o < MAX_COLS + 1; o++) {
                var currentTile:MemberBox = new MemberBox();
                currentTile.name = i + "_" + o;
                currentTile.x = i*150;
                currentTile.y = o*25;
                memberBox.addChild(currentTile);
                //currentTile.gotoAndStop(int(s[o][i]));
                var memberTxt:TextField=new TextField(); 
                currentTile.addChild(memberTxt);
                memberTxt.width = 150;
                memberTxt.height = 25;
                txtArray[o] = memberTxt;
                txtArray[o].text = mainArray[o][0];
            }
        }

        memberBox.x = 60;
        memberBox.y = 170;
        addChild(memberBox);
    }

    public function modifyArray(row:int, col:int, value:*):void {
        // Update our array.
        mainArray[row][col] = value;

        // Update our tile.
        var tile:MemberBox = memberBox.getChildByName(row + "_" + col);
        tile.getChildAt(0).text = value;
    }
}

当您实际修改数组时,您可以使用函数执行此操作,而不是采用直接mainArray[o][i]方法。

// Instead of this
mainArray[o][i] = "foo";

// You'd do this
modifyArray(o, i, "foo");

更新: 我不确定如何更好地解释这一点,所以我发布了您可以查看的工作示例。它包含类,文档代码,fla和swf以及电子表格的工作更新。如果这样可以解决问题,请告诉我:SpreadSheet Test @ Dropbox

解决方案#2:对变更进行投票

在内存中保存两个版本的数组。第一个是你正在积极编辑的那个,第二个是与第一个相比较的未触及的副本。每隔一段时间(每秒一次?),您遍历整个数据集并寻找差异。找到一个后,更新重复的数组和显示的电子表格。

以下是您如何做到这一点的示例:

import flash.utils.*;

var last:Number = flash.utils.getTimer();
this.addEventListener("enterFrame", checkData);

var foo:Array = ["a", "b", "c"];
var fooBackup:Array = [];

function update():void {
    var txt:TextField;

    for (var i:int = 0; i < foo.length; i++) {
        // If we don't have a representation of this index, create one.
        if (!this.getChildByName("tile"+i)) {
            txt = new TextField();
            txt.name = "tile" + i;
            txt.text = foo[i];
            this[txt.name] = txt;
            addChild(txt);
            txt.y = i * 20;
        }

        // Update the data if inconsistent.
        txt = this.getChildByName("tile"+i) as TextField;
        if (fooBackup.hasOwnProperty(i) == false || foo[i] != fooBackup[i]) {
            fooBackup[i] = foo[i]
            txt.text = foo[i];
            trace("Index " + i + " changed.  Updated backup, and display.");
        }
    }
}

function checkData(e:Event):void {
    var now:Number = flash.utils.getTimer();

    // If the last time we checked is greater than a second, run the check again.
    if (now - last > 1000) {
        // Update last checked index;
        last += 1000;

        // For the sake of argument, let's randomly change an index to a random value.
        foo[random(0, foo.length-1)] = random(-1000, 1000);
        update();
    }
}

 function random(low:Number=0, high:Number=1):Number {
    /* Returns a random number between the low and high values given. */
    return Math.floor(Math.random() * (1+high-low)) + low;
}

解决方案#3:滚动自己的数组

如Adobe Extending the Array class所述,您可以创建子阵列,并在此处添加/删除条目时添加自己的事件派发。这是更具冒险精神的解决方案,并且(以我的拙见)最好,因为它保持代码一致性,同时提供广泛而有效的权力。