Ejemplo de Arrastrar y Soltar (Puzzle)

| domingo, 2 de mayo de 2010
Trabajo realizado por: Miguel Angel Muras

Este artículo intenta explicar cómo hacer una aplicación un poquito compleja, es por ello que si no estais familiarizados con el programa Flash, os recomiendo que sigais los siguientes pasos antes de empezar con este tutorial:

1) Utilizad la ayuda de Flash. Es excelente. Os explicará cómo hacer todo tipo de objetos y cómo incluir sencillas pero efectivas programaciones.

2) Probad con pequeñas animaciones (objetos que cambian, botones que van a fotogramas, películas que se muevan por la pantalla…) No es tan difícil. Al final del artículo os indico direcciones dónde podéis encontrar cientos de ejemplos y tutoriales.

3) Paciencia. Mucha paciencia. Aprender a utilizar un programa con tantas posibilidades es un proceso lento que requiere de muchas horas y continuo trabajo.

Si aún así, estáis interesados en seguir el ejercicio, intentaré explicarme lo mejor que pueda, para que todos podais seguirlo.

Para seguir el tutorial, al final del artículo encontrareis un enlace al ejercicio ya realizado para que podáis investigar vosotros y ver cómo se ha realizado.



EL PUZZLE

Hay varias figuras y varias zonas dónde colocar esas figuras. El objetivo del juego consiste en colocar las figuras en sus cajas según su forma.


Como fase previa, dibujaremos los elementos, dos cuadrados y dos rectángulos. Fijaros en la imagen superior.

Para dibujarlos; utilizaremos las herramientas de Flash. Si deseamos utilizar gráficos de otro tipo (fotografía, dibujo escaneado, 3d…), el proceso será el mismo.

Una vez creados estos objetos, dibujaremos otro cuadrado. Este cuadrado actuará como centro para todos los demás elementos.

Convertiremos los elementos de la zona blanca en un botón, seleccionándolos y pulsando en el menú Insertar, la opción Convertir en símbolo…

* Cuando convertimos un gráfico en símbolo, nos pide un nombre y un comportamiento. Podemos poner cualquier nombre (luego los referenciaremos correctamente) y elegiremos un tipo de comportamiento.

Ahora convertiremos el cuadrado pequeño en un clip de película. Para ello, hacemos lo mismo que antes pero ahora seleccionamos en comportamiento, la opción Clip de película.

* Los clip de película representan un tipo de objeto manipulable en flash, que se utiliza sobre todo en animaciones e interacciones. Aparte de clip de película, podemos indicar que tenga un comportamiento de botón.

* Los botones permiten sin necesidad de código extra indicar acciones rápidas con el ratón (activar ordenes cuando nos colocamos encima del botón, cuando presionamos un botón o incluso cuando pulsamos una tecla).


Click en la imagen para ampliar

* El tercer comportamiento que podemos seleccionar es gráfico. Se marca para aquellos objetos que no sean botones ni interese manipular.


Colocamos un cuadrado pequeño (ya cambiado de nombre) encima (más o menos) de cada uno del resto de los objetos, duplicándolo.

Ya tenemos dos botones, dos gráficos y un clip de película.

El cuadrado pequeño en realidad es un controlador de contacto. Nos servirá para detectar cuando un objeto entra en contacto con otro objeto.

Se puede hacer este ejemplo sin este cuadrado, pero así, el resultado es más realista. Flash detecta que un objeto está encima de otro aunque sólo una esquina lo toque. Si no ponemos un cuadrado más pequeño, y tenemos varios objetos cerca, pueden llegar a confundirse.

Si ponemos un objeto más pequeño que sea el que detecte la colisión, nos aseguramos que el resultado sea más exacto.

* Cada objeto que nos interese manipular debe ser único. De tal manera que siempre podamos saber qué objeto pulsamos y sobre cual lo soltamos.

Para ello, está el nombre de instancia. Este nombre lo podemos definir en la ventana Propiedades.

Seleccionamos el cuadrado pequeño y le indicamos “centro” como nombre.


(Click en la imagen para ampliar)

Ahora tenemos dos botones en la parte inferior, dos gráficos en la superior y un objeto llamado centro.

Colocamos un cuadrado pequeño (ya cambiado de nombre) encima (más o menos) de cada uno del resto de los objetos, duplicándolo. (Imagen lateral)

Al final del ejercicio veremos los objetos sin cuadrados extras, manipulando lo que se llama el alfa del objeto.




(Clic para ampliar)
Una vez tengamos todos los objetos convertidos en clip de película, hay que darles un nombre (para saber luego sobre cual pulsamos y sobre cual estamos situados).

Ahora se trata de convertir cada pareja de objetos en otro objeto.

* En Flash, un elemento puede tener múltiples elementos. Es lo que se conoce como jerarquia.

En mi aplicación puede existir un objeto llamado cuadrado, que tenga dentro un ojeto llamado círculo que a su vez tenga dentro dos objetos llamados texto1 y texto2, por ejemplo.

Si quiero acceder a uno de los objetos, lo haré siguiendo su ruta.
cuadrado.circulo.texto1
cuadrado.circulo.texto2

Para ello, seleccionaremos los dos objetos, el cuadrado o circulo grande y el cuadrado interior, y los convertiremos en clip de película.

Una vez tengamos todos los objetos convertidos en clip de película, hay que darles un nombre (para saber luego sobre cual pulsamos y sobre cual estamos situados).

En el panel de propiedades, definimos los nombres según la imagen de la izquierda.


(Clic para ampliar)

Ahora tenemos cuatro elementos que tienen a su vez objetos en su interior.

Los dos objetos de abajo son clips de película que tienen a su vez, un botón y un clip de película.

Para entrar en un objeto hacemos doble clic en el mismo.

Estoy dentro del objeto cuad, que está en Escena 1

* Para salir del objeto, debemos fijarnos en el camino que ha seguido, y volver al objeto que lo contiene hasta llegar al inicio.

El sitio donde están todos los objetos, lo que denominamos raiz o root, se llama habitualmente Escena 1. Si hacemos un clic en Escena 1, saldremos de cualquier objeto.





La programación – Paso 1

Ahora viene la parte más compleja de todo este asunto, se trata de programar la interacción.

Para evitar confusiones, voy a poner primero el código sin comentarios para que se pueda copiar y pegar y luego lo comento.

El primer código es el que ha de ir en la ventana de acciones de los objetos circulo_movil y cuadrado_movil.

Código 1
(en el panel de acciones del objeto circulo_movil)

onClipEvent (load)
{
var x = this._x;
var y = this._y;
}

onClipEvent (enterFrame) {
if (this.soltar == "si")
{
distancia_x = Math.round((Number(x)-Number(this._x))/2);
distancia_y = Math.round((Number(y)-Number(this._y))/2);
if (Math.abs(distancia_x)<=1 and Math.abs(distancia_y)<=1)
{
}
else
{
this._x = this._x+distancia_x;
this._y = this._y+distancia_y;
}
}
}

* Para introducir este código no tenemos que hacer nada más que copiar y pegar, pero para manipularlo, hay que activar la opción de edición de código experto, ya que en modo normal, hay cosas que el ordenador no te dejará escribir.

La diferencia entre el código en Modo Experto y el Modo Normal está en la forma de introducir el código. El Modo Normal te permite introducir el código de forma guiada, y ayuda a empezar a familiarizarse con el código, sin embargo, el Modo Experto te deja escribir libremente, no ofreciéndote ayuda extra.

Para activar la opción experto, debes activar la opción Modo Experto en el menú que aparece pulsando la esquina superior derecha de la ventana Acciones.


(Clic para ampliar)

La primera parte del código (load), se activa cuando el objeto aparece en pantalla por primera vez. Cuando esto sucede, almacena en dos variables, llamadas x e y (por ejemplo) el valor de las coordenadas x e y del objeto que lo contiene, es decir, si el código está en el objeto cuadrado_movil, ,guardará las coordenadas iniciales de cuadrado_movil.

De esta manera, se puede saber dónde estaban los objetos al principio para devolverlos luego al mismo sitio.

onClipEvent (load)
{
var x = this._x;
var y = this._y;
}


La segunda parte de la función controla una acción que luego definiremos.

Si el usuario pulsa el ratón sobre este objeto (press), hay una variable dentro de este clip de película, llamada soltar que coge el valor no. Cuando coge el valor no, significa que el usuario está arrastrando el objeto.

Cuando lo suelta el objeto (release), la variable coge el valor si, que significa que el usuario ha soltado el objeto. Es en ese momento cuando tenemos que devolver el objeto a su sitio, que es la función que está en el apartado Enterframe.

La función básicamente hace lo siguiente:
Coge el valor de las coordenadas x e y dónde está el objeto (que acabamos de soltar), estos valores los resta a los valores que hemos almacenado en la función onload.

Esta diferencia, la divide en 2 (aunque podría ser en otro valor… a más valor, más tarda en volver).

Sumamos o restamos al valor actual la diferencia, y colocamos el objeto en la posición que nos da esta operación… y así consecutivamente hasta que llega a la posición original.

onClipEvent (enterFrame) {
if (this.soltar == "si")
{
distancia_x = Math.round((Number(x)-Number(this._x))/2);
distancia_y = Math.round((Number(y)-Number(this._y))/2);
if (Math.abs(distancia_x)<=1 and Math.abs(distancia_y)<=1)
{
}
else
{
this._x = this._x+distancia_x;
this._y = this._y+distancia_y;
}
}
}

* Si queremos comprobar que hemos escrito un código correctamente, tenemos una opción dentro de la ventana Acciones. Si pulsamos el botón indicado en la imagen y no nos da ningún error, nuestro código estará bien escrito. Eso no significa que funcione :)







Programación – Paso 2

Ahora tenemos que programar los botones interiores.

Antes de meter el código, tenemos que declarar una variable en un fotograma.
Para ello, entramos en uno de los objetos inferiores y nos colocamos en el fotograma que existe.


(Click en la imagen para ampliar)


En este caso, el código que hay que poner es el siguiente:

var soltar;

Esta orden, define una variable llamada soltar, (la hemos nombrado en la pantalla 4) que luego nos permitirá controlar si tengo un objeto pulsado o no.

* Si nos fijamos, después de poner acciones en un fotograma, aparece una a minúscula. Esta a minúscula indica que el fotograma tiene algún código insertado en la ventana de acciones.

Una vez declarada la variable tenemos que programar los botones.


(Click en la imagen para ampliar)

¡OJO!. El siguiente código hay que copiarlo
y pegarlo en el botón que está dentro de cuadrado_movil.

on (press)
{
soltar = "no";
this.startDrag();
}
on (release, releaseOutside)
{
if(centro.hitTest(_parent.cuadrado.centro))
{
soltar = "centro";
this._x = _parent.cuadrado._x;
this._y = _parent.cuadrado._y;
}
else
{
soltar = "si";
}
stopDrag();
}


¡OJO!. El siguiente código hay que copiarlo
y pegarlo en el botón que está dentro de circulo_movil.

on (press)
{
soltar = "no";
this.startDrag();
}

on (release, releaseOutside)
{
if(centro.hitTest(_parent.circulo.centro))
{
soltar = "centro";
this._x = _parent.circulo._x;
this._y = _parent.circulo._y;
}
else
{
soltar = "si";
}
stopDrag();
}


La primera parte del código es una acción que se activa al pulsar encima del botón (press).
Esta acción hace que el valor de la variable soltar sea “no” y comienza a arrastrar el objeto pulsado this.startDrag();

La segunda parte de la programación, se activa cuando soltamos el ratón.
Release es liberar: liberamos el ratón.

Básicamente, con esta función, comprobamos si el objeto centro de mi clip de película (en el primer caso cuadrado_movil), toca el centro del objeto cuadrado (zona verde)

En caso afirmativo, colocamos el objeto que encima del la caja que le corresponde. Es por ello que en cada código, cambia el valor del objeto de referencia. Si estamos en el objeto cuadrado_movil, detectaré la colisión con el objeto cuadrado. Sin embargo, si estamos en el objeto circulo_movil, detectaré la colisión con el objeto circulo.

Al final de este código, indicamos a Flash que suelte el objeto, con la “orden” StopDrag();

* Este código vale para cualquier número de objetos, lo único que hay que cambiar es la referencia al objeto de colisión en el código del paso 2.

Cada objeto, que arrastro, tiene su botón, y cada botón tiene una detección de colisión con un objeto diferente.

Como paso final, habría que reducir el alfa de los cuadrados interiores para que no se vean en la pantalla.

*El alfa es una propiedad de los objetos flash que define la transparencia de los mismos. Un objeto con alfa 0 será transparente y un objeto con alfa 100 será opaco.


(Click en la imagen para ampliar)

Ahora podemos complicarlo como queramos, activar mensaje cada vez que se acierte, poner un sonido asociado al fallo o al fracaso… lo que nuesta imaginación y nuestro tiempo nos permitan...


Y ya está.

Si habeis llegado hasta aquí sin preguntaros en qué idioma estaba hablando y sin cuestionar demasiado mi capacidad de comunicación... me sentiré muy halagado.

Este ejercicio muestra una forma de hacer las cosas... hay otras opciones aún más versátiles, utilizando otros métodos, pero esta solución es bastante limpia y sencilla.

Miguel Angel Muras (tak)

Para cualquier duda o sugerencia sobre próximos capítulos,

---

Materiales del curso

ejercicio 7: Objeto Sonido
ejercicio 6: Operaciones matemáticas
ejercicio 5: Flash y javascript
ejercicio 4: Trabajo con Arrays
ejercicio 3: Pequeñas utilidades
ejercicio 2: Precarga/Galería de fotos
ejercicio 1: Cómo hacer un puzzle

Enlaces interesantes:
Materiales y códigos… una gran biblioteca (en inglés)
http://www.flashkit.com/index.shtml

En castellano
http://www.nomaster.com/
http://www.webexperto.com/flash/
http://www.lawebdelprogramador.com

Un genio con flash… un maestro
http://www.kadazuro.com/tutoriales/


0 comentarios:

Publicar un comentario