使用“文件”保存场景对象的位置,以便在AS3后重建场景、对象、位置、文件

2023-09-08 11:22:10 作者:爱你者永爱=

我在尝试使用文件功能在ActionScript 3保存下列信息:

I am attempting to use the 'File' function in ActionScript 3 to save the following information:

我有不同场景中的拖动显示对象,数量和类型可以变化。我想保存的数量和它们的位置,然后加载回在未来的会话。

I have varying draggable display objects in the scene, the amount and type can vary. I want to save the amount and their position and then load them back in a future session.

我在努力用文件来保存任何东西,我已经搜查了的Adobe文件,不能让我的头一轮如何使用它。

I am struggling to use File to save anything, I have searched the Adobe documentation and cannot get my head round how to use it.

我还没有使用它开发的任何code。

I have not yet developed any code using it.

任何帮助将是AP preciated。

Any help would be appreciated.

感谢你。

推荐答案

正在尝试写的DisplayObject 成直接文件,这是由Flash pvented $ P $发动机由于闪存的方式处理任何对象的默认序列化。为了节省的DisplayObject 到外部资源,你需要使用 [IExternalizable] [1] 在该对象的类和任何类的对象,你会打算存储为好。 的writeExternal 的实施应保存从头开始重建该对象所需要的数据,而的readExternal 也应该采用的方法通过执行恢复说的DisplayObject 的完整性的addChild()嵌套显示对象,或将它们添加到其他的内部结构的对象可能包含的内容。

You are trying to write a DisplayObject into the file directly, this is prevented by Flash engine due to the way Flash handles default serialization of any object. In order to save a DisplayObject into the external resource, you need to employ [IExternalizable][1] on that object's class and any class of objects you will plan to store as well. The implementation of writeExternal should save all data required to rebuild the said object from scratch, and readExternal should also employ methods to restore the integrity of said DisplayObject by performing addChild() on nested display objects, or adding them into other internal structures that object might contain.

请注意,其他的答案包含有效的点做一个自定义序列化XML或JSON,也包含指向需要进口,特别是 flash.utils.registerClassAlias​​ flash.utils.getDefinitionByName 被严重需要从一个序列化的数据块重新构造。

Note, other answers contain valid points for doing a custom serialization with XML or JSON, and also contain links to requires import, in particular, flash.utils.registerClassAlias and flash.utils.getDefinitionByName are gravely needed to recreate the structure from a serialized data chunk.

举个例子:假设你有一个图板在主板类,以及一组矩形,您可以用鼠标拖动,相差大小和颜色。矩形定制影片剪辑和没有一个自己的类,但每个影片剪辑也被分配了颜色属性来简化他们的区别。这意味着你需要实现 IExternalizable 仅类的董事会。让我们假设主板类有一个数组,包含嵌套矩形的各个环节,以及一种方法来创建一个新的适当尺寸的矩形基于宽度,高度和提供作为参数的颜色。 (可能有更多的要求,以主板的数据结构,你的情况,以满足,所以密切关注)因此,序列化主板将收集来自嵌套的MC之类的东西它为了所有的数据到为IDataOutput 供应,并恢复主板应检索存储的数据,分析它找一下就是,创建嵌套司仪就像他们已经存储是一样的,他们正确地定位,的addChild()自我和重建 pieces`阵列。

An example: Let's say you have a drawing board in a Board class, and a set of rectangles that you can drag by using mouse, that differ by size and color. Rectangles are custom made MovieClips and don't have a class of their own, but each MovieClip is also assigned a color property to simplify their distinction. This means you need to implement IExternalizable on Board class only. Let's also assume Board class has a pieces array that contains all links to nested rectangles, and a method to create a new properly sized rectangle based on width, height and color supplied as parameters. (There might be more requirements to the data structure of Board to meet in your case, so watch closely) So, the process of serializing Board will be to collect all the data from nested MCs and stuff it in order into IDataOutput supplied, and the process of restoring an instance of Board should retrieve stored data, parse it to find what is where, create the nested MCs to be the same like they've been stored, position them properly, addChild() to self and rebuild thepieces` array.

public class Board extends Sprite implements IExternalizable {
    private var pieces:Array;
    public function createRectangle(_width:Number,_height:Number,color:uint):MovieClip {
        var mc:MovieClip=new MovieClip();
        mc.graphics.beginFill(color);
        mc.graphics.drawRect(0,0,_width,_height);
        mc.graphics.endFill();
        mc.color=color;
        pieces.push(mc);
        return mc;
    }

一个精细化的数据结构已经看到 - 你需要存储通过 _width _height 在MC某个地方,因为实际的宽度三菱商事将不同于什么通过了默认的行厚度(1,两侧0.5)。 X 已正确MC的属性检索,虽然。所以,增加两条线成 createRectangle 是必要的。

A refinement to data structure is already visible - you need to store the passed _width and _height in the MC somewhere, because the actual width of that MC will differ from what's passed by the default line thickness (1, 0.5 on either side). x and y are properly retrieved from MC's properties, though. So, adding both lines into createRectangle is necessary.

mc._width=_width;
mc._height=_height;

通过这个,序列化主板变得更容易了。

With this, serializing the Board becomes more easy.

public function writeExternal(output:IDataOutput):void {
    var pl:int=pieces.length; // cache
    output.writeInt(pl); // assuming we keep this array in integral state
    for (var i:int=0;i<pl;i++) {
        var _mc:MovieClip=pieces[i];
        output.writeDouble(_mc.x); // this is usually not rounded when dragging, so saving as double
        output.writeDouble(_mc.y);
        output.writeDouble(_mc._width);
        output.writeDouble(_mc._height);
        output.writeInt(_mc._color);
    }
    // if anything is left about the "Board" itself, write it here
    // I'm assuming nothing is required to save
}

要恢复,需要读取数据了的IDataInput 的的非常相同的顺序,因为它是写在的writeExternal ,然后流程重建,我们已经存储的显示列表中。

To restore, you need to read the data out of IDataInput in the very same order as it was written in writeExternal and then process to rebuilding the display list we've stored.

public function readExternal(input:IDataInput):void {
    // by the time this is called, the constructor has been processed
    // so "pieces" should already be an instantiated variable (empty array)
    var l:int;
    var _x:Number;
    var _y:Number;
    var _width:Number;
    var _height:Number;
    var _color:uint;
    // ^ these are buffers to read data to. We don't yet have objects to read these into
    input.readInt(l); // get pieces length
    for (var i:int=0;i<l;i++) {
        input.readDouble(_x);
        input.readDouble(_y);
        input.readDouble(_width);
        input.readDouble(_height);
        input.readInt(_color);
        // okay we got all the data representing the rectangle, now make one
        var mc:MovieClip=createRectangle(_width,_height,_color);
        mc.x=_x;
        mc.y=_y;
        addChild(mc); // createRectangle does NOT have addchild call
        // probably because there are layers for the parts to be added to
        // I'm assuming there are no layers here, but you might have some!
        // pieces array is populated inside createRectangle, so we leave it alone
    }
    // read all the data you have stored after storing pieces
}

如果您嵌套管委会有一个类也实现 IExternalizable ,您可以保存整个阵列在一个单一的指令,的writeObject(件) ,这将使整个数组闪存走,发现它含有和呼叫的writeObject 上的任何嵌套对象中的所有数据,实质​​上调用这个类的的writeExternal 函数的每个阵列中的实例。恢复这样一个数组应包括通过遍历数组,并调用的addChild()在每个实例恢复重建的显示列表。

In case your nested MCs have a class that also implements IExternalizable, you can save the entire array in a single instruction, writeObject(pieces), this will make Flash walk through the array, find all data it contains and call writeObject on any nested object, essentially calling that class's writeExternal function for each of the instance in the array. Restoring such an array should include rebuilding the display list by walking the array and calling addChild() on each of the restored instances.

最后但并非最不重要的, registerClassAlias​​()前应做的自定义对象的任何序列化和反序列化调用。调用这些最好的地方可能是你的主要对象的构造函数,因为这肯定会被称为前的C应用程序的任何其他$ C $包含的内容。

And last but not the least, registerClassAlias() should be called prior to doing any serialization or deserialization of custom objects. Best place to call these is probably your main object's constructor, as this will surely be called before any other code your application contains.

 
精彩推荐