使用对象而不是数组

时间:2015-01-21 16:49:43

标签: actionscript-3 flash flash-cc

我花了将近一周的时间来学习使用对象而不是数组。我以为它很容易调用它们并创建一些对象并设置它们的属性。但是我现在无法访问它们,我试过这个:

function onBoxClick(event:MouseEvent):void {
    var str:String = event.currentTarget.name;
    trace(str);
    str = str.substring(str.indexOf("_") + 1);
    trace(getChildByName("copy_" + str)); // trying to trace an object by name
}

我的问题是,是否有一种处理物体的实用方法,否则使用它们的目的是什么。

编辑:这是我用来创建动画片段和其他内容的功能:

function addBoxes(isUpdate:Boolean):void {
    var copyOne:Object = getReadOnlyValues();
    copyOne.name = "copy_" + num;

    // Set default mc1 settings
    var settings1:Object = copyOne.mc1Settings;
    for(var num2:String in settings1) {
        copyOne.mc1[num2] = settings1[num2];
    }

    // Set default mc1text settings
    var settings2:Object = copyOne.mc1TextSettings;
    for(var num3:String in settings2) {
        copyOne.mc1Text[num3] = settings2[num3];
    }

    copyOne.mc1.x = nextXpos;
    copyOne.mc1.name = "captionBox_" + num;

    addChild(copyOne.mc1);
    copyOne.mc1.addEventListener(MouseEvent.CLICK, onCaptionClick);

    copyOne.mc1Text.name = "captionBoxText_" + num;
    copyOne.mc1.addChild(copyOne.mc1Text);

    // ---------------------------------------------------------------  
    // Set default mc2 settings
    var settings4:Object = copyOne.mc2Settings;
    for(var num4:String in settings4) {
        copyOne.mc2[num4] = settings4[num4];
    }

    // Set default mc2text settings
    var settings5:Object = copyOne.mc2TextSettings;
    for(var num5:String in settings5) {
        copyOne.mc2Text[num5] = settings5[num5];
    }

    copyOne.mc2.x = nextXpos;
    copyOne.mc2.y = copyOne.mc1.height;
    copyOne.mc2.name = "box2_" + num;

    addChild(copyOne.mc2);

    copyOne.mc2Text.name = "box2BoxText_" + num;
    copyOne.mc2.addChild(copyOne.mc2Text);

    copyOne.mc2.addEventListener(MouseEvent.CLICK, onBoxClick);

    if (num / subunits is int) {
        trace (num);

        // createMc("normalBox", true);
    }

    nextXpos = nextXpos + copyOne.mc2.width;

    // traceObj(copyOne);
    // traceObj(getReadOnlyValues());
}

我在一个循环中调用了这个函数,因此我创建了许多动画片段。现在我无法访问对象'属性和他们的孩子(例如textfield)。

我在舞台上的对象:Movieclips和textfields

他们来自哪里:上述功能

我试图用它们做什么:跟踪动画片段和文本字段(由对象保持)以更改其子(文本字段)文本

会发生什么而不是我期望的:跟踪代码输出undefined而不是给我对象类型trace(getChildByName("copy_" + str)); // trying to trace an object by name

是否有一种实用的方法来访问名称为" copy_1"及其名称为" box2_1" (动画片段)?

3 个答案:

答案 0 :(得分:1)

我看到的一个问题是" copyOne"对象已在" addBoxes"的范围内创建,因此它将不再存在于此函数之外。

另一个是你试图通过getChildByName访问一个Object,它只解决你正在调用的displayObjectContainer的displayObjects。

如果你想通过对象或MovieClip(它们都是动态样式的对象,可以让你根据需要添加属性)来松散地跟踪变量,只需使用MovieClip来存放你的值。在舞台上的movieClip将保留在内存中,直到从displayList(舞台)中删除。

另外,查看词典,这是一种基于键/值的方式来存储对象集合。

更好的是,如果您使用强类型自定义对象(创建自己的类来扩展MC,并添加自己的公共或私有方法和值),那么有一些好处,例如使用Vector(兼容的花式,快速数组)您选择的任何对象类型。)

答案 1 :(得分:0)

我真的不知道我是否理解你的问题,但正如@ozmachine在他的answer中说的那样,你不能使用getChildByName,而是我认为你可以看看这可能会有所帮助:

var container:DisplayObjectContainer = this;

function getReadOnlyValues():Object {
    return {
        mc1: new box(),
        mc1: {
            name: 'mc1_',
            alpha: 1,
            x: 0,
            y: 0,
            width: 30,
            height: 25
        },
        mc1Text: new TextField(),
        mc1Text: {
            text: 'test',
            x: 0,
            y: 0,
            selectable: false,
            multiline: false,
            wordWrap: false
        }
    }
};

// create 5 objects
for(var i=0; i<5; i++){

    container['copy_'+i] = getReadOnlyValues();

    var obj:Object = getObjectByName('copy_'+i);
        obj.mc1.alpha = 1;
        obj.mc1.x = 0;
        obj.mc1.y = 50 * i;
        obj.mc1.width = 100;   

        obj.mc1.addChild(obj.mc1Text);
        obj.mc1Text.text = 'test_' + i;

    addChild(obj.mc1);
}
// get object by name
function getObjectByName(name:String):Object {
    return container[name];
}

// change the text of the 4th button
stage.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void { 
    var obj:Object = getObjectByName('copy_3');
        obj.mc1Text.text = 'new text';
})

答案 2 :(得分:0)

Array和Object都是数据结构。 数据意味着某种形式的信息。 数据结构意味着以某种方式存储某种形式的信息。

数组和对象是存储信息的两种不同方式。

数组使用整数来标识数据。 用于标识数组中单个元素的整数称为索引

数组非常适合表示彼此相似的类似内容列表。

var names:Array = ["John", "Paul", "George", "Ringo"];

这通常意味着数组的元素属于同一类型,如上例所示。 但他们不必:

var numbers:Array = [42, "twenty-five", "XIIV"];

对于上面的例子,很容易回答这些问题&#34;四个披头士乐队的名字是什么?&#34;,&#34;你在发现期间偶然发现了什么不同的数字表示?穿过历史悠久的小镇?&#34;。其他问题更难或无法回答。 &#34;你在历史悠久的小镇偶然发现了什么罗马数字?&#34;

对象用名称标识数据。 用于标识对象的单个元素的名称称为属性

对象非常适合表示彼此属于的不同内容列表。

var paula:Object = {age:37, name:"Paula", hairColor:0x123456};

这通常意味着对象的元素具有不同的类型,如上例所示。 但他们不必:

var car:Object = {manufacturer:"Porsche", color:"red", sound:"wroooooom", soundOfDriver:"weeeeeeeeeeee"};

考虑到这一点,让我们看看您的代码,看看它是如何应用的。 大局是您有一个多次调用的函数addBoxes。由于一个函数应该有一个目的,每次执行时,此函数都会执行类似的操作。呃哦:&#34;类似&#34;。无论这个函数的结果是什么,它都应该进入一个数组。对该函数的每次调用都是数组的一个元素。您可以清楚地看到使用&#34; num&#34;识别当前运行的函数中发生的任何事情。

您的功能中包含哪些数据?

  • copyOne
  • MC1
  • mc1Text
  • MC2
  • mc2Text

copyOne在这里是一个麻烦制造者,是什么导致你的困惑。它试图一次完成所有事情,因此你无法清楚地思考何时使用数组和何时使用Object。人们会称它为上帝对象。这不是一个好的对象。

您对变量名的选择非常糟糕。 你选择超级通用名称,如&#34; mcX&#34;只是为了以后添加一个名称属性来描述它的真实含义。 但即便如此,对于任何&#34; Box2&#34;应该是。 选择名称,以便您可以轻松了解代码中的内容。 看起来您为此问题创建了此结构jsut的全部或部分,因此缺少有意义的名称。 我强烈建议你不要通过这样的组合项目来学习。但是来自现实世界。

因此,我将强加以下目标: mc1和mc1Text代表一个标题 mc2和mc2Text代表内容

有了这一切,我再问一遍:

您的功能中包含哪些数据?

  • captionBox
  • captionText
  • contentBox
  • contentText

标题和内容都包含一个框和一个文本。 这些是不同的东西,因此标题和内容都是具有属性的对象&#34; box&#34;和&#34;文字&#34; 人们可以认为,由于这种相似性,它们都应该进入阵列。 但我不同意。标题和文字不是一回事。您以不同方式处理字幕和文本。走在街上你可能很快就会在新闻中看到一个很大的标题,但不是冗长的文字。这就是为什么它们中的每一个都应该是在函数中创建的对象的属性。

这里有点结论

var allBoxes:Array = [];  // array to store the similar results of every function call

function createBoxes():void 
{
    var boxes:Object = {};

    //the box consists of caption & content, both bying of the same type, but are containing different data

    boxes.caption = {box:{}, text:{}}; //caption
    boxes.content = {box:{}, text:{}}; //content

    allBoxes.push(boxes);
}

就是这样。这就是我用对象和数组建模数据的方式和原因。

但它并没有在这里结束。我的结论缺少你发布的很多代码。 虽然上述内容主要与语言无关,但缺少的代码特定于Actionscript,而不仅仅是如何建模数据。它如下......

As3是面向对象的。 这很好,因为上面的结论中有很多对象。 要定义某个对象是如何/做/移动/放屁/等,可以创建类。

发生以下变化(出于本答案范围之外的原因):

  • createBoxes(以前称为addBoxes)调用的构造函数 一个班级&#34; CaptionAndContent&#34;扩展了Sprite。
  • 不再需要明确地创建一个对象&#34; box&#34;正如构造函数那样。
  • captioncontent将没有属性&#34;框&#34;,因为 他们可以成为自己的盒子。这正是它在这方面所做的 问题的代码。默认设置在其类的构造函数中设置。

这里减少了代码片段,希望能够说明 类的外观。 每个类都应该在自己的文件中,包含必要的导入,包块以及您未在问题中指定的其他功能。

public class CaptionAndContent extends Sprite
{
    private var caption:Caption;
    private var content:Content;

    public function CaptionAndContent(captionText:String = "", contentText:String = "")
    {
        caption = new Caption(captionText);
        addChild(caption);

        content = new Content(contentText);
        content.y = caption.height;
        addChild(content);
    }
}

public class ClickableBoxWithText extends Sprite
{
    protected var textField:TextField;
    public function ClickableBoxWithText(text:String = "")
    {
        textField = new TextField();
        textField.text = text;
        addChild(textField);

        addEventListener(MouseEvent.CLICK, onClick);
    }

    protected function onClick(mouseEvent:MouseEvent):void
    {
        //override this in a sublclass
    }
}

public class Caption extends ClickableBoxWithText
{
    public function Caption(text:String = "")
    {
        super(text);

        // apply all the default settings of caption here.
    }
}

public class Content extends ClickableBoxWithText
{
    public function Content(text:String = "")
    {
        super(text);

        // apply all the default settings of content here.
    }
}

使用它们看起来像这样:

var allBoxes:Array = [];  // array to store the similar results of every function call

function createBoxes():void
{
    var captionAndContent:CaptionAndContent = new CaptionAndContent("This is the caption...", "...for this content");
    captionAndContent.x = nextXpos;
    addChild(captionAndContent);

    allBoxes.push(captionAndContent);
}

最后但并非最不重要的是,点击处理程序中的识别问题。 您的问题已包含答案:

event.currentTarget

这是对点击对象的引用。 在我的代码中它将是

mouseEvent.currentTarget

这标识了已经的对象。查找其中一个属性(例如其名称)以查找该名称的所有对象,只是为了识别您必须识别的相同对象(没有名称)以便得到名字。

无论如何,您还无法通过名称识别对象。名称与所谓的独特之处有什么不同,最后是一个数字。正如在这个答案中指出的那样,这就是所谓的索引,你试图用它来识别它应该进入一个数组。在我的示例代码中,这是allBoxes