script programar para escena con como comandos codigos cambios botones animate acciones actionscript-3 flash actionscript air state

actionscript 3 - programar - Usando ''Archivo'' para guardar las ubicaciones de objetos de escenas para reconstruir más tarde en AS3



comandos de actionscript (5)

Está intentando escribir un objeto DisplayObject en el archivo directamente, esto es impedido por el motor Flash debido a la forma en que Flash maneja la serialización predeterminada de cualquier objeto. Para guardar un DisplayObject en el recurso externo, necesita emplear IExternalizable en la clase de ese objeto y cualquier clase de objetos que planee almacenar también. La implementación de writeExternal debe guardar todos los datos necesarios para reconstruir dicho objeto desde cero, y readExternal también debe emplear métodos para restaurar la integridad de dicho DisplayObject al realizar addChild() en objetos de visualización anidados, o agregarlos a otras estructuras internas que el objeto podría Contiene.

Tenga en cuenta que otras respuestas contienen puntos válidos para realizar una serialización personalizada con XML o JSON, y también contienen enlaces que requieren importación, en particular, flash.utils.registerClassAlias y flash.utils.getDefinitionByName son muy necesarios para recrear la estructura a partir de datos serializados. pedazo.

Un ejemplo: digamos que tiene un tablero de dibujo en una clase de Board y un conjunto de rectángulos que puede arrastrar con el mouse, que difieren en tamaño y color. Los rectángulos son MovieClip personalizados y no tienen una clase propia, pero a cada MovieClip también se le asigna una propiedad de color para simplificar su distinción. Esto significa que debe implementar IExternalizable en la clase Board solamente. Supongamos también que la clase Board tiene una matriz de pieces que contiene todos los enlaces a rectángulos anidados, y un método para crear un nuevo rectángulo de tamaño adecuado en función del ancho, la altura y el color proporcionados como parámetros. (Puede haber más requisitos para que la estructura de datos de la Board reúna en su caso, así que tenga cuidado). Por lo tanto, el proceso de serialización de la Board consistirá en recopilar todos los datos de los MC anidados y IDataOutput en orden en IDataOutput suministrado, y el El proceso de restauración de una instancia de la Board debería recuperar los datos almacenados, analizarlos para encontrar qué es lo que está, crear los MC anidados para que sean los mismos que se almacenaron, colocarlos correctamente, addChild() to self and rebuild the matriz de piezas. .

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

Ya está visible un refinamiento de la estructura de datos: necesita almacenar el _width y la _height _width _height en el MC en alguna parte, porque el width real de ese MC diferirá de lo que pasa con el espesor de línea predeterminado (1, 0.5 en cada lado). y se recuperan correctamente de las propiedades de MC, sin embargo. Por lo tanto, es necesario agregar ambas líneas en createRectangle .

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

Con esto, serializar la Board vuelve más fácil.

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 }

Para restaurar, necesita leer los datos de IDataInput en el mismo orden en que fue escrito en writeExternal y luego procesar para reconstruir la lista de visualización que hemos almacenado.

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 }

En caso de que sus MC anidados tengan una clase que también implemente IExternalizable , puede guardar toda la matriz en una sola instrucción, writeObject(pieces) , esto hará que Flash recorra la matriz, encuentre todos los datos que contiene y llame a writeObject en cualquier objeto anidado , llamando esencialmente a la función writeExternal esa clase para cada una de las instancias de la matriz. La restauración de dicha matriz debe incluir la reconstrucción de la lista de visualización recorriendo la matriz y llamando a addChild() en cada una de las instancias restauradas.

Y por último pero no menos importante, se debe llamar a registerClassAlias() antes de hacer cualquier serialización o deserialización de objetos personalizados. El mejor lugar para llamar a estos es probablemente el constructor de su objeto principal, ya que seguramente se llamará antes que cualquier otro código que contenga su aplicación.

Estoy intentando usar la función ''Archivo'' en ActionScript 3 para guardar la siguiente información:

Tengo diferentes objetos de visualización arrastrables en la escena, la cantidad y el tipo pueden variar. Quiero guardar la cantidad y su posición y luego volver a cargarlos en una sesión futura.

Estoy luchando por usar File para guardar cualquier cosa, he buscado en la documentación de Adobe y no puedo entender cómo usarlo.

Todavía no he desarrollado ningún código que lo use.

Cualquier ayuda sería apreciada.

Gracias.


Suponiendo que todos sus objetos para guardar pertenecen al mismo padre, podría hacer algo en esta línea:

Primero, cree un archivo de clase (llamemos a SaveData.as y póngalo en la raíz del directorio de su proyecto). Esto describirá los datos que quiere guardar:

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() { } } }

A continuación, en su función de guardar, haga algo como esto:

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

Ahora, para volver a cargarlo:

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

Si no está seguro de las importaciones, aquí están:

import flash.filesystem.File; import flash.filesystem.FileMode; import flash.filesystem.FileStream; import flash.net.registerClassAlias; import flash.utils.getDefinitionByName; import flash.utils.getQualifiedClassName;


Usualmente uso SharedObject, al guardar el número de objetos con sus ubicaciones, escala, rotación, etc., como una matriz (generalmente una matriz multidimensional).

este ejemplo está probado:

primero haga un clip de película dándole "mc" como nombre en el Enlace de ActionScript agregue los gráficos que desee (este MovieClip será los objetos que se guardarán más adelante) y luego agregue el siguiente script

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

en la etapa raíz del proyecto, agregue:

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


Ya tiene algunas respuestas aquí, pero a partir de su pregunta, tal vez le falta el contexto más amplio.

Entonces la clase File representa una ruta a un archivo en el disco y la clase FileStream permite leer y escribir datos en ese archivo. Estos son fáciles de usar y hay muchos ejemplos en la web. Aquí hay un tutorial de Adobe: Lectura y escritura de archivos

Pero, ¿qué datos escribir y cuál es el formato y el tipo de datos? Esas son las preguntas más importantes y más interesantes.

El enfoque más simple es usar un formato basado en text como XML o JSON donde usted lee y escribe las propiedades de Sprites (u otros objetos) que desee. Una ventaja de esto es que el archivo resultante es un archivo de texto legible / editable humano. Una desventaja menor es que debe especificar qué propiedades guardar y restaurar, y tratar con las conversiones simples de tipo de datos (cadena a int, etc.).

Un enfoque más robusto es usar lo que se llama Serialization donde se guarda y restaura el estado de un objeto completo. Esto es más complicado y, aunque no es difícil, es probablemente excesivo para las necesidades de su proyecto. Hay buenos ejemplos y discusiones aquí , aquí y aquí .

Para su proyecto actual y nivel de habilidad, le sugiero usar XML o JSON Aquí hay un tutorial usando XML: carga y procesamiento de archivos XML externos


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();