Introducción:
SharedObject es implementado con el plug-in de MX de
flash, es una forma de guardar información
en la computadora del usuario. Pensemos en ellos como
si fueran "cookies", con esto podemos guardar
información que nos intereza que sea recordada
la siguiente vez que el usuario accede a nuestro proyecto,
como por ejemplo:
- El nombre y el correo del usuario si llena nuestro
formulario, para que así la siguiente vez
no tenga que digitarlo de nuevo.
- El marcador del último score que hizo en
el juego en nuestro proyecto.
- Las prefencias para navegar en nuestro site, ya
sea que tengamos varios fondos a escoger o varios
tipos de música.
- Ultima sección o página visitada,
vamos no sería bonito que cuando una entre
a un site le salga un mensaje que diga: "Hola
de nuevo!, deseas seguir viendo el site donde
quedaste la última vez, o verlo desde el
inicio?"
- La forma en que acomodó nuestro menú
la última vez que nos visitó.
entre otras muchas.
Cómo funciona:
SharedObject tiene tres métodos:
SharedObject.getLocal();
SharedObject.getSize();
SharedObject.flush();
SharedObject.getLocal(): devuelve un objeto guardado
en la computadora local.
SharedObject.getSize(): devuelve el tamaño
del objeto en bytes.
SharedObject.flush(): graba inmendiatamente la información.
Lo primero que tenemos que hacer es ver si hay datos
guardados, para esto debemos recordar obviamente el
nombre que le pusimos a nuestro sharedObject ( el
nombre con que guardamos la información en
la computadora del usuario, no el objeto que usamos
en flash ).
ej.
so = sharedObject.getLocal("misDatos");
misDatos, es el nombre del sharedObject, en este caso
lo que estoy es asignándole el valor de lo
que tenga guardado en misDatos, al la variable/objeto
so ( de sharedObject).
De ser la primera vez, este objeto no contendrá
dato alguno, pero al no existir y preguntar por él,
Flash se encargará de crearlo, sin dato alguno
pero lo crea.
De haber datos estos se guardan en un objeto especial
llamado "data", en nuestro caso podemos
accesar a los valores de so de la siguiente forma
( recuerda que so, es la variable en flash donde hemos
asignado el valor de nuestro sharedObject "misDatos"
)
so.data.miVariable
Para saber si hay datos hay una forma muy fácil
de hacerlo : preguntado; es decir, si el fla va a
guardar información de usuario en una variable
"userName" podemos preguntar haciendo lo
siguiente.
if (so.data.userName != undefined ){
....
}
Es decir, si el dato userName es distinto a indefinido,
i.e.: si existe. lo utilizamos. De no existir la información
la podemos grabar.
else{
so.data.userName = miCampoDeTexto.text;
}
suponiendo que el usuario ya haya digitado su nombre
en nuestro campo de texto.
Al salir de flash el sharedObject guardará
la información que este contenga, pero para
estar seguros le podemos decir al SharedObject que
la guarde.
else{
so.data.userName = miCampoDeTexto.text;
so.flush();
}
Ejemplo práctico: Recordar la
posición de 4 botones.
Vamos a suponer que tenemos 4 botones en el escenario
que el usuario puede mover ( drag ) y colocar donde
el guste, y cuando vuelva a acceder la página
los botones van a estar donde el los dejó.
Para esto vamos a crear un sharedObject que nos guarde
dentro de un array las posiciones x,y de cada boton.
A.- Simplifiquemonos la vida:
Vamos a tener 4 botones que va a hacer las mismas acciones.
En este caso on Press startDrag, onRelease/on DragOut
stopDrag, (en mi caso aparte de ponerle las acciones
le voy a poner el texto dinámicamente); no
sería genial tener una función que nos
"instalara" estos botones?, algo como
setBtn = function(miBoton) {
miBoton.onPress = function(){}
miBoton.onRelease = function (){}
miBoton.onReleaseOutside = function (){}
}
Así sólo tendríamos que pasar
los nombre de las instancias de los botones
setBtn(boton1);
para que este ya quedara listo. =)
Los botones que tengo no son más que un movieClip
con 3 frames con labels _up, _over,_down los cuales
representarán los estados del "botón"
más un campo de texto con nombre de instancia
"campo", agregando el autoSize más
la asignación de texto, como que queda mucha
gente en la función.
setBtn = function(miBoton,texto) {
miBoton.campo.autoSize = "center";
miBoton.campo.text = texto;
miBoton.onPress = function(){
....
}
miBoton.onRelease = function (){
....
}
miBoton.onReleaseOutside = function (){
....
}
}
Talvez no lo veas muy complejo por ahora, pero una
vez que tengamos las funciones, será mucho
más difícil de leer. para que no suceda
esto vamos a partir el código en pequeños
pedacitos.
customPress = function (){
...
}
customRelease = function(){
...
}
setActions = function (btn){
btn.onPress = customPress;
btn.onRelease = customRelease;
btn.onReleaseOutside = customRelease;
}
setBtn= function(btn, texto){
btn.campo.autoSize = "center";
btn.campo.text = texto;
setActions(btn)
}
De esta forma queda más entendible, es decir
cuando llamemos a la función setBtn pasándole
el botón y el texto como parámetros,
esta asignará el texto, y luego llamará
a la función setActions, que asigna las funciones
para onPress, onRelease y onReleaseOutside, las cuales
fueron previamente declaradas.
Si te fijaste bien, verás que onReleaseOutside
y onRelease apuntan a la misma función, pero
porqué le ponemos customRelease??..., mejor
le cambiamos el nombre para que nos indique mejor
lo que hace, digamos "reset", asi ni release
ni releaseOutside se recienten.
B. Funciones para los Botones.
Las funciones a como las entendemos por el momento
estás asi: onPress => startDragg, onRelease,
releaseOutside => reset ( stopDrag ).
B.1. CustomPress.
customPress = function (){
this.startDrag(false);
}
B.2. reset.
reset = function (){
stopDrag();
this._x = Math.round(this._x);
this._y = Math.round (this._y);
}
Lo de Math.round es para que quede en píxeles
enteros cuando lo suelten, esto es útil cuando
se trabaja con gráficos o fuentes píxel.
C. El SharedObject.
Este es el héroe de la película. Lo primero
que hacemos en pensar como vamos a guardar la información.
Tenemos 4 botones y de estos queremos guardar las
posiciones x,y. podemos guardar un dato por variable:
boton1x=valor;boto1y=valor...
pero luego tendríamos que asignar todas estas
variable casi que a mano.
btn1._x = so.data.boton1._x;
btn1._y = sp.data.boton1._y;
....
Ahora imagínate esto si queremos guardar la
posición de 50 objetos!.
C.1. Arrays, Objetos, Arrays de Objetos, y
referencias.
Una forma útil de mantener la información
ordenada es el uso de Array u Objetos, y una forma
sencilla de manejar objetos es usar Arrays cuyos campos
apuntan (referencian) a instancias de objetos en el
escenario ( en nuestro caso botones ), una vez hecho
esto, podemos acceder a las propiedades de los objetos
que nos interezan ( en este caso, _x, _y ).
C.1.1. Array de botones.
En este Array vamos a guardar las referencias a los
botones que tenemos en el escenario ( de hecho más
que botones son movieClips que actuan como botones
), y lo hacemos de la siguiente forma.
botones = [btn1,btn2,btn3,btn4]
Que vendría siendo lo mismo que :
botones = new Array (btn1,btn2,btn3,btn4)
La ventaja de usar este array es que para acceder a
las propiedades de los botones solo tenemos que recorrer
el Array con un simple "for"
var largo = botones.length;
for( var n = 0; n < largo; n++ ){
trace ( botones[n]._name + "._x ="
+ botones[n]._x )
}
El código anterior nos muestra el nombre del
boton más las propiedad _x en la ventana del
ouput.
btn1._x =216
btn2._x =190
btn3._x =163
btn4._x =112
C.1.2 El Array dentro del SharedObject.
Ya que tenemos un array con las referencias a los botones,
podemos aprovechar para hacer uno dentro del sharedObject,
ya que de esta forma ambos arrays serían del
mismo largo, y podríamos actualizar u obtener
la información con un "for". En este
caso no vamos a guardar referencias a los botones
sino más bien vamos a guardar sus propiedades
dentro de un Objeto de manera que para acceder a los
datos guardados del objeto sharedObject podemos hacerlo
asi:
so.data.btns[n].x = valor// mostrando
el x valor del botonN donde N es un indice del array.
Si n vale 0 y buscamos en el array botones de nuestra
movie, botones[n] corresponde a la referencia hacia
el btn1 por lo que el valor x se refiere a la propiedad
_x (btn1._x) que tenía btn1 cuando grabamos
la información. Para grabar esta información
dentro del Array btns dentro de nuestro SharedObject
ocupamos también el Array botones en el que
tenemos las referencias, asi dentro del bucle ("for")
mientras vamos referenciando a cada clip con el indice,
igualmente vamos guardarndo su información
con el mismo indice pero en el array del sharedObject.
var l = botones.length;
for ( var n = 0; n < l; n++){
so.data.btns[n] = {x : botones[n]._x,
y: botones[n]._y};
}
Que es la versión corta para.
var l = botones.length;
for ( var n = 0; n < l; n++){
so.data.btns[n] = new Object();
so.data.btns[n].x = botones[n]._x;
so.data.btns[n].y = botones[n]._y;
}
C.2. Actualizar y Asignación.
Nos detenemos a analizar que debemos hacer y cuando
debemos hacerlo.
caso 1. El usuario entra por primera vez, por lo que
el sharedObject no existe, debemos crearlo junto con
las posiciones de los botones (Actualizar).
caso2. El usuario ya ha visitado nuestra página,
así que debemos asignar las posiciones a los
botones que tenemos guardadas en nuestro sharedObject
(Asignación).
caso3. El usuario arrastra un botón y cambia
la posición de algún botón, este
cambio también debemos guardarlo (Actualizar).
Una vez hecho este estudio podemos ver que ocupamos
sólo dos funciones : upDate para cuando hagan
cambios o se entre a nuestro proyecto no siendo visitado
antes; y setPos únicamente cuando ya se ha
entrado a nuestro proyecto anteriormente.
Notémos también que cada vez que el
usuario mueve un botón esta posición
debe ser guaradada llamando a la función upDate,
como cuando el botón deja de hacer Drag llama
a la función reset, lo lógico sería
que desde reset se llame a la función upDate.
upDate = function(){
var l = botones.length;
for ( var n = 0; n < l; n++){
so.data.btns[n] = {x : botones[n]._x,
y: botones[n]._y};
}
}
setPos= function(){
var l = botones.length;
for ( var n = 0; n < l; n++){
botones[n]._x = so.data.btns[n].x;
botones[n]._y = so.data.btns[n].y;
}
}
y la función reset con la llamada a upDate queda
así:
reset = function (){
stopDrag();
this._x = Math.round(this._x);
this._y = Math.round (this._y);
this._parent.upDate();
}
C.3 Creación del sharedObject.
Como vamos a guardar la información dentro de
un Array llamado btns, lo que tenemos que hacer una
vez creado el objeto es preguntar si btns ( dentro
de data, del sharedObject) existe, si no es así,
que lo cree y que nos guarde la información;
si este existe, que nos actualize la posición
de nuestros botones.
if(so.data.btns == undefined ){
so.data.btns = new Array();
upDate()
}else{
setPos()
}
D. Optimización
Como habrás notado cada vez que se mueve un
botón se actualizan todos, siendo esto algo
poco funcional en el caso que se tuvieran muchos objetos.
En el zip, podrás encontrar una versión
extra, con esta optimización.
E. Ejemplo.
Para ver el ejemplo funcionando: abre el ejemplo, mueve
los botones, cierra la ventana y lo abres de nuevo.
F. Soporte.
Si tienes preguntas sobre este tutorial, puedes ver
las echas por otros usuarios o postear una nueva dentro
del tema que hay en FlashLA presionando en botón.
|