使用 'File' 保存场景对象位置以便稍后在 AS3 中重建
Using 'File' to save scene object locations to rebuild later in AS3
我正在尝试使用 ActionScript 3 中的 'File' 函数来保存以下信息:
我在场景中有不同的可拖动显示对象,数量和类型可能会有所不同。我想保存数量和他们的位置,然后在以后的会话中加载它们。
我正在努力使用 File 来保存任何东西,我已经搜索了 Adobe 文档但不知道如何使用它。
我还没有使用它开发任何代码。
如有任何帮助,我们将不胜感激。
谢谢。
var bytes:ByteStream;
var filename:String = "mySaveFile.sav";
//[...] //initialize byte stream with your data
//get a reference to where you want to save the file
//(in this example, in the application storage directory,
//which is fine if you don't need to move the save file between computers
var outFile:File = File.applicationStorageDirectory;
outFile = outFile.resolvePath(fileName);
//create a file output stream, which writes the byte stream to the file
var outStream:FileStream = new FileStream();
outStream.open(outFile, FileMode.WRITE);
outStream.writeBytes(bytes, 0, bytes.length);
outStream.close();
//to load the file:
var inFile:File = File.applicationStorageDirectory;
inFile = inFile.resolvePath(fileName);
bytes = new ByteArray();
var inStream:FileStream = new FileStream();
inStream.open(inFile, FileMode.READ);
inStream.readBytes(bytes);
inStream.close();
我通常使用 SharedObject,通过将对象的数量及其位置、比例、旋转等保存为数组(通常是多维数组)。
这个例子已经过测试:
首先制作一个影片剪辑,在 ActionScript 链接中将其命名为 "mc"
添加任何你喜欢的图形
(这个MovieClip就是后面要保存的对象)
然后添加以下脚本
////////// get random values for each object
var speed:Number ;
var yPosition:Number ;
var size:Number ;
this.width = size;
this.height = size;
this.y = yPosition ;
//// Moving the MovieClip from Left to right
function moving(e:Event):void
{
this.x += speed ;
if(this.x > 550)
{
this.removeEventListener(Event.ENTER_FRAME,moving);
MovieClip(parent).removeChild(this);
}
}
this.addEventListener(Event.ENTER_FRAME,moving);
在项目的根阶段添加:
import flash.events.MouseEvent;
import flash.display.MovieClip;
var num:int = 0 ;
var mmc:MovieClip ;
var mySharedObj:SharedObject = SharedObject.getLocal("SavingStatus"); //// SharedObject to save info
function init()
{
if (!mySharedObj.data.savedArray)
{
///// first run No datat saved
this.addEventListener(Event.ENTER_FRAME,addingmcs)
}else {
///// Laoding previusly saved data
loading();
}
}
init() ;
/////////////// adding MovieClips to stage /////
function addingmcs(e:Event):void
{
num +=1 ;
if(num > 20){
num = 0 ;
mmc = new mc ;
mmc.speed = 2 + (5 * Math.random()) ;
mmc.yPosition = 500 * Math.random() ;
mmc.size = 50 + 10 * Math.random() ;
this.addChild(mmc);
}
}
///////////////////////////////////////////
///////////////////////////////////////////////
var obj:* ; //// to hold children MovieClips of the stage
var savingArr:Array = new Array ; //// the array to be saved , Contains all info of the children
////////////// Save all MovieClips with their parameters ////////////
function saving(e:MouseEvent):void
{
this.removeEventListener(Event.ENTER_FRAME,addingmcs)
for (var i:int=0;i<this.numChildren;i++)
{
if (this.getChildAt(i)is MovieClip) { ///// add all MovieClips of the stage to the array with their info (position - size - speed ... etc)
obj = this.getChildAt(i);
savingArr.push([obj , obj.x , obj.y , obj.speed , obj.size]); //// add the info in 3 dimentional array
obj.speed = 0 ;
}
}
////////////////saving array externally
mySharedObj.data.savedArray = savingArr ;
mySharedObj.flush ();
}
save_btn.addEventListener(MouseEvent.CLICK,saving)
////////////// Load all saved parameters ////////////
load_btn.addEventListener(MouseEvent.CLICK,loading)
function loading(e:MouseEvent =null):void
{
savingArr = mySharedObj.data.savedArray ;
for (var i:int=0;i<savingArr.length ; i++)
{
mmc = new mc ;
mmc.x = savingArr[i][1] ; ///// Get saved x
mmc.yPosition = savingArr[i][2] ; ///// Get saved y
mmc.speed = savingArr[i][3] ; ///// Get saved speed
mmc.size = savingArr[i][4] ; ///// Get saved size
addChild(mmc);
}
this.addEventListener(Event.ENTER_FRAME,addingmcs) ;
}
假设您要保存的所有对象都属于同一个父对象,您可以按照以下方式做一些事情:
首先,创建一个 class 文件(我们称之为 SaveData.as
并将其放在项目目录的根目录中)。这将描述您要保存的数据:
package
{
import flash.geom.Rectangle;
public class SaveData
{
public var bounds:Rectangle; //to save where an object is on the stage
public var classType:Class; //to save what kind of object it is
//you could add in more proterties, like rotation etc
public function SaveData() {
}
}
}
接下来,在您的保存功能上,执行如下操作:
//this will hold all your data
//a vector is the same as an array only all members must be of the specified type
var itemList:Vector.<SaveData> = new Vector.<SaveData>();
//populate the array/vector with all the children of itemContainer
var tmpItem:SaveData;
//loop through all children of item container
for (var i:int = 0; i < itemContainer.numChildren; i++) {
tmpItem = new SaveData(); //create a new save record for this object
tmpItem.bounds = itemContainer.getChildAt(i).getBounds(itemContainer); //save it's bounds
tmpItem.classType = getDefinitionByName(itemContainer.getChildAt(i)) as Class; //save it's type
itemList.push(tmpItem); //add it to the array
}
//Now you have an array describing all the item on screen
//to automatically serialize/unserialize, you need this line (and you need to register every class nested in SaveData that isn't a primitive type - which would just be Rectangle in this case
registerClassAlias("SaveData", SaveData);
registerClassAlias("flash.geom.Rectangle", Rectangle);
//create a new File to work with
var file:File = File.applicationStorageDirectory; //or whatever directory you want
file.resolvePath("saveData.data"); //or whatever you want to call it
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
fileStream.writeObject(itemList); //write the array to this file
fileStream.close();
现在,将其重新载入:
var itemContainer:Sprite = new Sprite(); //however you initialize this
addChild(itemContainer);
var file:File = File.applicationStorageDirectory;
file.resolvePath("saveData.data");
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);
var itemList:Vector.<SaveData> = fileStream.readObject() as Vector.<SaveData>;
fileStream.close();
//now that you've read in the array of all items from before, you need to recreate them:
var tmpItem:DisplayObject;
var tmpClass:Class;
//loop through all items in the array, and create a object
for (var i:int = 0; i < itemList.length; i++) {
tmpClass = itemList[i].classType; //The type of item
tmpItem = new tmpClass() as DisplayObject; //create the item
//now move the item to it's former position and scale
tmpItem.x = itemList[i].x;
tmpItem.y = itemList[i].y;
tmpItem.width = itemList[i].width;
tmpItem.height = itemList[i].height;
//add the item back to the parent
itemContainer.addChild(tmpItem);
}
如果您不确定导入的内容,它们是:
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.registerClassAlias;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
你在这里已经有了一些答案,但从你的问题来看,你可能错过了更大的背景。
所以 File
class represents a path to a file on disk and the FileStream
class enables reading and writing data to that file. These are easy to use and there are many examples on the web. Here is one tutorial from Adobe: Reading and writing files
但是写入什么数据,格式和数据类型是什么?这些才是更重要、更有趣的问题。
最简单的方法是使用基于 text
的格式,例如 XML
或 JSON
,您可以在其中读取和写入 Sprites
(或其他对象)的任何属性想。这样做的一个优点是生成的文件是一个人类 readable/editable 文本文件。一个小缺点是您需要指定要保存和恢复的属性以及处理简单的数据类型转换(字符串到 int 等)。
更稳健的方法是使用所谓的 Serialization
where the state of an entire object is saved and restored. This is more complicated and while not hard, is probably overkill for your project needs. There are good examples and discussion here , here and here.
对于您当前的项目和技能水平,我建议使用 XML
orJSON
Here's a tutorial using XML: Loading and Processing External XML Files
您正在尝试将 DisplayObject
直接写入文件,由于 Flash 处理任何对象的默认序列化的方式,Flash 引擎阻止了这种情况。为了将 DisplayObject
保存到外部资源中,您需要对该对象的 class 以及您计划存储的任何 class 对象使用 IExternalizable
。 writeExternal
的实现应保存从头开始重建所述对象所需的所有数据,并且 readExternal
还应使用方法通过执行 addChild()
来恢复所述 DisplayObject
的完整性嵌套显示对象,或将它们添加到对象可能包含的其他内部结构中。
请注意,其他答案包含使用 XML 或 JSON 进行自定义序列化的有效要点,还包含需要导入的链接,特别是 flash.utils.registerClassAlias
和 [=22] =] 迫切需要从序列化数据块中重新创建结构。
例如:假设您在 Board
class 中有一个绘图板,以及一组可以使用鼠标拖动的矩形,它们的大小和颜色各不相同。矩形是定制的 MovieClip
,没有自己的 class,但每个 MovieClip
也分配了 color
属性 以简化它们的区别.这意味着您只需要在 Board
class 上实施 IExternalizable
。我们还假设 Board
class 有一个 pieces
数组,其中包含嵌套矩形的所有链接,以及一种根据作为参数提供的宽度、高度和颜色创建大小合适的新矩形的方法。 (您的情况可能对 Board
的数据结构有更多要求,因此请仔细观察)因此,序列化 Board
的过程将是从嵌套的 MC 中收集所有数据并将其填充为了进入 IDataOutput
提供,并且恢复 Board
实例的过程应该检索存储的数据,解析它以找到它在哪里,创建嵌套的 MCs 就像它们被存储一样, 正确放置它们,addChild() to self and rebuild the
pieces` 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 的某个地方,因为该 MC 的实际 width
将不同于默认线宽(1、0.5 两侧)传递了什么。不过,x
和 y
是从 MC 的属性中正确检索的。因此,将这两行添加到 createRectangle
是必要的。
mc._width=_width;
mc._height=_height;
有了这个,序列化 Board
变得更容易了。
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
}
要恢复,您需要按照在 writeExternal
中写入 的相同顺序从 IDataInput
中读取数据,然后处理到重建我们存储的显示列表。
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
}
如果您的嵌套 MC 有一个 class 也实现了 IExternalizable
,您可以在一条指令 writeObject(pieces)
中保存整个数组,这将使 Flash 遍历数组,找到它包含的所有数据并在任何嵌套对象上调用 writeObject
,实质上是为数组中的每个实例调用 class 的 writeExternal
函数。恢复这样的数组应该包括通过遍历数组并在每个恢复的实例上调用 addChild()
来重建显示列表。
最后但并非最不重要的一点是,应该在对自定义对象进行任何序列化或反序列化之前调用 registerClassAlias()
。调用它们的最佳位置可能是您的主对象的构造函数,因为它肯定会在您的应用程序包含的任何其他代码之前被调用。
我正在尝试使用 ActionScript 3 中的 'File' 函数来保存以下信息:
我在场景中有不同的可拖动显示对象,数量和类型可能会有所不同。我想保存数量和他们的位置,然后在以后的会话中加载它们。
我正在努力使用 File 来保存任何东西,我已经搜索了 Adobe 文档但不知道如何使用它。
我还没有使用它开发任何代码。
如有任何帮助,我们将不胜感激。
谢谢。
var bytes:ByteStream;
var filename:String = "mySaveFile.sav";
//[...] //initialize byte stream with your data
//get a reference to where you want to save the file
//(in this example, in the application storage directory,
//which is fine if you don't need to move the save file between computers
var outFile:File = File.applicationStorageDirectory;
outFile = outFile.resolvePath(fileName);
//create a file output stream, which writes the byte stream to the file
var outStream:FileStream = new FileStream();
outStream.open(outFile, FileMode.WRITE);
outStream.writeBytes(bytes, 0, bytes.length);
outStream.close();
//to load the file:
var inFile:File = File.applicationStorageDirectory;
inFile = inFile.resolvePath(fileName);
bytes = new ByteArray();
var inStream:FileStream = new FileStream();
inStream.open(inFile, FileMode.READ);
inStream.readBytes(bytes);
inStream.close();
我通常使用 SharedObject,通过将对象的数量及其位置、比例、旋转等保存为数组(通常是多维数组)。
这个例子已经过测试:
首先制作一个影片剪辑,在 ActionScript 链接中将其命名为 "mc" 添加任何你喜欢的图形 (这个MovieClip就是后面要保存的对象) 然后添加以下脚本
////////// get random values for each object
var speed:Number ;
var yPosition:Number ;
var size:Number ;
this.width = size;
this.height = size;
this.y = yPosition ;
//// Moving the MovieClip from Left to right
function moving(e:Event):void
{
this.x += speed ;
if(this.x > 550)
{
this.removeEventListener(Event.ENTER_FRAME,moving);
MovieClip(parent).removeChild(this);
}
}
this.addEventListener(Event.ENTER_FRAME,moving);
在项目的根阶段添加:
import flash.events.MouseEvent;
import flash.display.MovieClip;
var num:int = 0 ;
var mmc:MovieClip ;
var mySharedObj:SharedObject = SharedObject.getLocal("SavingStatus"); //// SharedObject to save info
function init()
{
if (!mySharedObj.data.savedArray)
{
///// first run No datat saved
this.addEventListener(Event.ENTER_FRAME,addingmcs)
}else {
///// Laoding previusly saved data
loading();
}
}
init() ;
/////////////// adding MovieClips to stage /////
function addingmcs(e:Event):void
{
num +=1 ;
if(num > 20){
num = 0 ;
mmc = new mc ;
mmc.speed = 2 + (5 * Math.random()) ;
mmc.yPosition = 500 * Math.random() ;
mmc.size = 50 + 10 * Math.random() ;
this.addChild(mmc);
}
}
///////////////////////////////////////////
///////////////////////////////////////////////
var obj:* ; //// to hold children MovieClips of the stage
var savingArr:Array = new Array ; //// the array to be saved , Contains all info of the children
////////////// Save all MovieClips with their parameters ////////////
function saving(e:MouseEvent):void
{
this.removeEventListener(Event.ENTER_FRAME,addingmcs)
for (var i:int=0;i<this.numChildren;i++)
{
if (this.getChildAt(i)is MovieClip) { ///// add all MovieClips of the stage to the array with their info (position - size - speed ... etc)
obj = this.getChildAt(i);
savingArr.push([obj , obj.x , obj.y , obj.speed , obj.size]); //// add the info in 3 dimentional array
obj.speed = 0 ;
}
}
////////////////saving array externally
mySharedObj.data.savedArray = savingArr ;
mySharedObj.flush ();
}
save_btn.addEventListener(MouseEvent.CLICK,saving)
////////////// Load all saved parameters ////////////
load_btn.addEventListener(MouseEvent.CLICK,loading)
function loading(e:MouseEvent =null):void
{
savingArr = mySharedObj.data.savedArray ;
for (var i:int=0;i<savingArr.length ; i++)
{
mmc = new mc ;
mmc.x = savingArr[i][1] ; ///// Get saved x
mmc.yPosition = savingArr[i][2] ; ///// Get saved y
mmc.speed = savingArr[i][3] ; ///// Get saved speed
mmc.size = savingArr[i][4] ; ///// Get saved size
addChild(mmc);
}
this.addEventListener(Event.ENTER_FRAME,addingmcs) ;
}
假设您要保存的所有对象都属于同一个父对象,您可以按照以下方式做一些事情:
首先,创建一个 class 文件(我们称之为 SaveData.as
并将其放在项目目录的根目录中)。这将描述您要保存的数据:
package
{
import flash.geom.Rectangle;
public class SaveData
{
public var bounds:Rectangle; //to save where an object is on the stage
public var classType:Class; //to save what kind of object it is
//you could add in more proterties, like rotation etc
public function SaveData() {
}
}
}
接下来,在您的保存功能上,执行如下操作:
//this will hold all your data
//a vector is the same as an array only all members must be of the specified type
var itemList:Vector.<SaveData> = new Vector.<SaveData>();
//populate the array/vector with all the children of itemContainer
var tmpItem:SaveData;
//loop through all children of item container
for (var i:int = 0; i < itemContainer.numChildren; i++) {
tmpItem = new SaveData(); //create a new save record for this object
tmpItem.bounds = itemContainer.getChildAt(i).getBounds(itemContainer); //save it's bounds
tmpItem.classType = getDefinitionByName(itemContainer.getChildAt(i)) as Class; //save it's type
itemList.push(tmpItem); //add it to the array
}
//Now you have an array describing all the item on screen
//to automatically serialize/unserialize, you need this line (and you need to register every class nested in SaveData that isn't a primitive type - which would just be Rectangle in this case
registerClassAlias("SaveData", SaveData);
registerClassAlias("flash.geom.Rectangle", Rectangle);
//create a new File to work with
var file:File = File.applicationStorageDirectory; //or whatever directory you want
file.resolvePath("saveData.data"); //or whatever you want to call it
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
fileStream.writeObject(itemList); //write the array to this file
fileStream.close();
现在,将其重新载入:
var itemContainer:Sprite = new Sprite(); //however you initialize this
addChild(itemContainer);
var file:File = File.applicationStorageDirectory;
file.resolvePath("saveData.data");
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);
var itemList:Vector.<SaveData> = fileStream.readObject() as Vector.<SaveData>;
fileStream.close();
//now that you've read in the array of all items from before, you need to recreate them:
var tmpItem:DisplayObject;
var tmpClass:Class;
//loop through all items in the array, and create a object
for (var i:int = 0; i < itemList.length; i++) {
tmpClass = itemList[i].classType; //The type of item
tmpItem = new tmpClass() as DisplayObject; //create the item
//now move the item to it's former position and scale
tmpItem.x = itemList[i].x;
tmpItem.y = itemList[i].y;
tmpItem.width = itemList[i].width;
tmpItem.height = itemList[i].height;
//add the item back to the parent
itemContainer.addChild(tmpItem);
}
如果您不确定导入的内容,它们是:
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.registerClassAlias;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
你在这里已经有了一些答案,但从你的问题来看,你可能错过了更大的背景。
所以 File
class represents a path to a file on disk and the FileStream
class enables reading and writing data to that file. These are easy to use and there are many examples on the web. Here is one tutorial from Adobe: Reading and writing files
但是写入什么数据,格式和数据类型是什么?这些才是更重要、更有趣的问题。
最简单的方法是使用基于 text
的格式,例如 XML
或 JSON
,您可以在其中读取和写入 Sprites
(或其他对象)的任何属性想。这样做的一个优点是生成的文件是一个人类 readable/editable 文本文件。一个小缺点是您需要指定要保存和恢复的属性以及处理简单的数据类型转换(字符串到 int 等)。
更稳健的方法是使用所谓的 Serialization
where the state of an entire object is saved and restored. This is more complicated and while not hard, is probably overkill for your project needs. There are good examples and discussion here , here and here.
对于您当前的项目和技能水平,我建议使用 XML
orJSON
Here's a tutorial using XML: Loading and Processing External XML Files
您正在尝试将 DisplayObject
直接写入文件,由于 Flash 处理任何对象的默认序列化的方式,Flash 引擎阻止了这种情况。为了将 DisplayObject
保存到外部资源中,您需要对该对象的 class 以及您计划存储的任何 class 对象使用 IExternalizable
。 writeExternal
的实现应保存从头开始重建所述对象所需的所有数据,并且 readExternal
还应使用方法通过执行 addChild()
来恢复所述 DisplayObject
的完整性嵌套显示对象,或将它们添加到对象可能包含的其他内部结构中。
请注意,其他答案包含使用 XML 或 JSON 进行自定义序列化的有效要点,还包含需要导入的链接,特别是 flash.utils.registerClassAlias
和 [=22] =] 迫切需要从序列化数据块中重新创建结构。
例如:假设您在 Board
class 中有一个绘图板,以及一组可以使用鼠标拖动的矩形,它们的大小和颜色各不相同。矩形是定制的 MovieClip
,没有自己的 class,但每个 MovieClip
也分配了 color
属性 以简化它们的区别.这意味着您只需要在 Board
class 上实施 IExternalizable
。我们还假设 Board
class 有一个 pieces
数组,其中包含嵌套矩形的所有链接,以及一种根据作为参数提供的宽度、高度和颜色创建大小合适的新矩形的方法。 (您的情况可能对 Board
的数据结构有更多要求,因此请仔细观察)因此,序列化 Board
的过程将是从嵌套的 MC 中收集所有数据并将其填充为了进入 IDataOutput
提供,并且恢复 Board
实例的过程应该检索存储的数据,解析它以找到它在哪里,创建嵌套的 MCs 就像它们被存储一样, 正确放置它们,addChild() to self and rebuild the
pieces` 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 的某个地方,因为该 MC 的实际 width
将不同于默认线宽(1、0.5 两侧)传递了什么。不过,x
和 y
是从 MC 的属性中正确检索的。因此,将这两行添加到 createRectangle
是必要的。
mc._width=_width;
mc._height=_height;
有了这个,序列化 Board
变得更容易了。
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
}
要恢复,您需要按照在 writeExternal
中写入 的相同顺序从 IDataInput
中读取数据,然后处理到重建我们存储的显示列表。
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
}
如果您的嵌套 MC 有一个 class 也实现了 IExternalizable
,您可以在一条指令 writeObject(pieces)
中保存整个数组,这将使 Flash 遍历数组,找到它包含的所有数据并在任何嵌套对象上调用 writeObject
,实质上是为数组中的每个实例调用 class 的 writeExternal
函数。恢复这样的数组应该包括通过遍历数组并在每个恢复的实例上调用 addChild()
来重建显示列表。
最后但并非最不重要的一点是,应该在对自定义对象进行任何序列化或反序列化之前调用 registerClassAlias()
。调用它们的最佳位置可能是您的主对象的构造函数,因为它肯定会在您的应用程序包含的任何其他代码之前被调用。