Cristalab

                 ¿Quieres registrarte?

Rompecabezas y puzzles con imágenes en Actionscript

Por: Teseo
23 de Febrero del 2007
1401 de clabLevel
Otros artículos de Teseo
35,446 visitas

Muchas veces necesitamos dividir una imagen en partes independientes para hacer diversos efectos. Este código efectúa una partición en trozos de cualquier imagen. Las "piezas" quedan almacenadas como un array llamado pz[] para poder moverse o usarse según convenga.
Está escrito como una función llamada puzzle a la que llamamos para dividir la imagen del siguiente modo:

Código :

puzzle("imagen", filas, columnas, false);

Imagen es el nombre de vinculación desde la biblioteca, luego las filas y colunmas deseadas y por último si hacer cuadros o piezas de puzzle (true o false).

Simplemente la llamamos y ya está hecho completamente el puzzle!!

Las piezas del puzzle tienen cada una una forma de borde distinta que se genera aleatoriamente.
La profundidad y brillos de los bordes y el "imán" de posición se ajustan automáticamente dependiendo del tamaño de las piezas.

La partición en cuadraditos, tiras, etc es muy util para efectos de transiciones de imágenes tipo explotar, entrelazado, recombinación, etc. Pondré ejemplos posteriormente con estas y otras transiciones.

He añadido solamente el cambiador de nivel, un ajustador automático de posición y un detector de puzzle terminado o "todas en su sitio" en las funciones de drag. Las funciones de mezcla y dispersión no las incluyo porque son funciones aparte que dependen de la aplicación que demos al script.

Ejemplo:
Clickear en las piezas para moverlas y usar los botones para ver distintas formas y divisiones.


Código Puzzle


Código :

import flash.display.*;
import flash.geom.*;
import flash.filters.*;

puzzle("imagen", 4, 4, false); // tipo de llamada a la función

function puzzle(imagen, f, c, lin) {
   for (hg=0; hg<4*tpz; hg++){pz[hg].removeMovieClip();} // borra puzzle anterior si existe.
   a=new Array(1,12,0,.35,2,12,1,.15,3,2,4,.2,5,4,6,.5,7,6,8,.5,10,12,2,.15,9,8,10,.4,11,12,10,.15);
   tpz = f*c;
   c>f ? j=20/c : j=20/f;
   bF = new BevelFilter(1,45,0xffffff,.5,0,.5,j,j,4,3,"inner",false);
   img = BitmapData.loadBitmap(imagen);
   w = img.width; h = img.height; m1 = w/(3*c); m2 = h/(3*f);
   // creando matriz delados congruentes entre piezas contiguas
   p = []; d = 0; 
   for (m=0; m<4*tpz; m+=4) {
      p[m+7] = p[m+1] = d++;
      if((d-1)%(2*c) == 2*(c-1)) {p[m+1]=p[(m+4)%(4*tpz) +3]=2*tpz-2};
      p[m+4*c] = p[m+2] = d++;
      if(d>2*(tpz-c) && d%2 == 0) {p[m+2]=p[(m+4*c)%(4*tpz)]=2*tpz-1};
   }
   for (g=0; g<2*tpz; g++) {
      b[g] = [];
      b[g][0] = new Point(m1, m2);
      alea()<0 ? sig=-1 : sig=1; // las curvas de encaje para distinto lado aleatoriamente
      if (g%2 == 0) { //puntos para lados horizontales
         b[g][12] = new Point(m1, 4*m2);
         b[g][4] = new Point(m1-m1*sig*.6, m2*(2+alea()));
         b[g][6] = new Point(m1-m1*sig*.9, m2*(2.5+alea()));
         b[g][8] = new Point(m1-m1*sig*.6, m2*(3+alea()));
      } else { //puntos para lados verticales
         b[g][12] = new Point(4*m1, m2);
         b[g][4] = new Point(m1*(2+alea()), m2-m2*sig*.6);
         b[g][6] = new Point(m1*(2.5+alea()), m2-m2*sig*.9);
         b[g][8] = new Point(m1*(3+alea()), m2-m2*sig*.6);
      }
      for (r=0; r<29; r+=4){ //puntos centrales de curvas para H y V 
         b[g][a[r]] = Point.interpolate(b[g][a[r+1]],b[g][a[r+2]],a[r+3]+alea());
      }
   }
   pz = [];
   pt=[];
   for (n=0; n<f*c; n++) {
      pz[n] = createEmptyMovieClip("pz"+n, n+1);
      tmp2 = new BitmapData(5*m1, 5*m2, true, 0);
      pt[n] = new Point((n%c)*3*m1-m1, Math.floor(n/c)*3*m2-m2);
      tmp2.copyPixels(img,new Rectangle(pt[n].x,pt[n].y,5*m1,5*m2),null);
      //dibujando los 4 lados de cada pieza
      for (z=0; z<4; z++) {
         z == 2 ? sy=3*m2 : sy=0; z == 1 ? sx=3*m1 : sx=0;
         g = p[4*n+z];
         pz[n].beginBitmapFill(tmp2);
         pz[n].moveTo(5*m1/2, 5*m2/2);
         pz[n].lineTo(b[g][0].x+sx, b[g][0].y+sy);
         if (g>(2*tpz-3) || lin){pz[n].lineTo(b[g][12].x+sx, b[g][12].y+sy);}
         else {
            pz[n].lineTo(b[g][1].x+sx, b[g][1].y+sy);
            for (j=2; j<12; j+=2){
               pz[n].curveTo(b[g][j].x+sx, b[g][j].y+sy,b[g][j+1].x+sx,b[g][j+1].y+sy);
            }
            pz[n].lineTo(b[g][12].x+sx, b[g][12].y+sy);
         }
         pz[n].lineTo(5*m1/2, 5*m2/2);
         pz[n].endFill();
      }
      //doblando la asignacion para evitar fallos de ajuste por decimales.
      pz[n]._x = pt[n].x; pt[n].x = pz[n]._x;
      pz[n]._y = pt[n].y; pt[n].y = pz[n]._y;
      pz[n].filters = [bF];
      pz[n].v = n;
   }
   for (h=0; h<tpz; h++) {
      pz[h].onPress = function() {
         this.startDrag();
         this.swapDepths(tpz+1);
      }
      pz[h].onRelease = function() {
         this.stopDrag();
         // iman de colocación si  la pieza está cerca de su sitio.
         cerca = new Point(this._x,this._y)
         if (Point.distance(pt[this.v],cerca)< 4+(m1+m2)/15){
            this._x = pt[this.v].x; this._y = pt[this.v].y;
         }
         //comprobador de puzzle completo o piezas que faltan por colocar
         cnt=0;
         for (tt=0; tt<tpz; tt++){
           if((pz[tt]._y == pt[tt].y) && (pz[tt]._x == pt[tt].x)) {++cnt;}
           cnt==tpz ? texto="completo" : texto="faltan: "+(tpz-cnt);
        }
      }
   }
   function alea() {return (.1-Math.random()/5);} // función de extración aleatoria en general.
}

No son necesarias modificaciones pues todos los parámetros se autoajustan. Si acaso variar el radio mínimo de captación y la "potencia" del iman de colocación:
if (Point.distance(pt[this.v],cerca)< 4+(m1+m2)/15){

En los ejemplos de transiciones y juegos que usan esta función que ya iré posteando, les he incluido volumen y sombras.


Artículos Relacionados


Etiquetas actionscript

Comentarios | Enviar un comentario
Muy bueno el código (y)
lastima que no se puedan unir piezas fuera de su sitio y luego moverlas conjuntamente ;)
Por: Zguillez
Aquí trato simplemente el modo de división, no el Puzzle de formas como juego específico. Ni el modo Sam Lloyd ni ningún otro.
Mi idea era poner el "motor" de fabricación de piezas y luego ponerle unas tropecientas mil funciones para usarlo.
Como digo en el tip:
" Las funciones de mezcla y dispersión no las incluyo porque son funciones aparte que dependen de la aplicación que demos al script."

En la aplicación específica para puzzle de formas SI tengo la función de agrupación exterior asi como botón de de fondo visionable, recomposición automática con movimiento, zoom, giro de piezas y ayuda focal, etc.
Además de que el puzzle completo pueda ser de cualquier forma (no solo un rectangulo). Pero esa es una aplicación entera y no un Tip de uso. :wink:
Por: Teseo
Wosh, esto debería ir también en ejemplos, genial Teseo :D
Por: Coyr
Muy buen manejo de los arrays :D, espectacular el código
Por: karkuxx_blog
Misteriosamente hoy estaba pensando en mi futura web .. y el elemento principal sera un puzzle ..
sabes como me vino ??!!!
Genial Teseo
Gracias ;)
Por: majitto
Genial Teseo.

Deberías pasarlo a una clase, definir datatypes, y optimizar cosas como:
Before

Código :

for (hg=0; hg<4*tpz; hg++)


After

Código :

var Total:Number;
Total = 4*tpz;
for (var hg:Number=0; hg<Total; hg++)


Este tipo de cosas, podrían leerse de un archivo de configuración.

Código :

   a=new Array(1,12,0,.35,2,12,1,.15,3,2,4,.2,5,4,6,.5,7,6,8,.5,10,12,2,.15,9,8,10,.4,11,12,10,.15);


Saludos ^^
Por: Dano
Grande Teseo, grande!
Por: eveevans
Espectacular. Una pena que sea un principiante y no sepa cómo llamar a la funcion puzzle. He copiado y pegado el código tal como está y no funciona. Si colgaras el fla sería fantástico.

andsigil@hotmail.com
Por: andsigil_blog
Para usar este ejemplo hay que hacer simplemente 3 cosas:
TENER UNA IMAGEN EN LA BIBLIOTECA (PNG, GIF, BMP, JPG..)
Poner la imagen en la biblioteca del FLA. y vincularla con el nombre "imagen" OJO : vincularla no es ponerla en el escenario. Colocar u MC, gráfico o botón en el Escenario y darle nombre de instancia es "instanciar", no es "vincular para attach".
Instrucciones para vincular una imagen que está en la biblioteca:
1) En la biblioteca pones una imagen llamada digamos "paisaje".
2) Pinchas con ratón derecho sobre su icono en la biblioteca.
3) Pinchas en vinculación en el menú que aparece.
4) En la ventana que sigue: Propiedades de vinculación marcas Exportar para ActionScript , marcará también Exportar en primer fotograma, déjalo marcado. En identificador pon imagen (ese es el nombre que buscará el script para cargarlo en attach). Deja la entrada de Clase AS2 en blanco. pulsa Aceptar. Si todo ha ido bien, en las columnas de la biblioteca verás: nombre, tipo, nº de usos, y en vinculación la palabra imagen.

COLOCAR EL CODIGO EN LAS ACCIONES DEL PRIMER FRAME DE LA LINEA DE TIEMPO PRINCIPAL

LLAMAR A LA FUNCION PUZZLE CON LOS PARAMETROS QUE DESEEMOS:
En el código hay una linea que hace la llamada:
puzzle("imagen", 4, 4, false); // tipo de llamada a la función
Cambiamos los parametros que deseemos de filas y columnas (4 y 4 en este ejemplo) y si deseamos cuadraditos( true) o piezas de puzzle (false). El primer parámetro "imagen" es el nombre que pusimos para la vinculación desde la biblioteca.
Por: Teseo
Muchísimas gracias por tu consideración hacia los torpes y principiantes como yo.
Voy a seguir tus instrucciones al pie de la letra a ver si esta vez tengo más suerte.

¡GRACIAS TESEO!

andsigil@hotmail.com
Por: andsigil_blog
Lo siento Teseo pero después de haberte tomado las molestias de explicar cómo se vincula una imagen yo he seguido tus pasos uno a uno y me sigue sin funcionar.
Sigo pensando que no te cuesta ningún trabajo colgar el fla.

Debo ser más torpe que un guardahabas...

Mi correo es

andsigil@hotmail.com
Por: andsigil_blog
HOLA! Justamente esto es lo que necesito hacer pero con el MACROMEDIA FLASH MX 2004, con estos códigos me da error... ¿hay otra manera de hacerlo o sabéis como puedo hacer esto pero con este programa??
Muchas gracias!
Por: AYUDA!!_blog
Hola AYUDA!!

Creo que Teseo ha configurado el código para que sólo 'funcione'en Flash8 aunque yo he copiado, pegado el código y he seguido sus instrucciones y tampoco funciona. Me encantaría poder ayudarte porque a mí me interesa muchísimo este código y espero que Teseo se apiade de nosotros y nos cuelgue el fla o nos diga qué es lo que hacemos mal. Yo estoy dispuesto a que si Teseo me proporciona su correo electrónico mandarle el fla con su código para que él vea que no funciona y me diga qué es lo que estoy haciendo mal.

andsigil@hotmail.com
Por: andsigil_blog
andsigil, NO funciona con otra versión que NO sea Flash 8. Simplemente así es. Es por el uso de BitmapData. No hay forma de hacerlo funcionar en MX 2004. acéptalo, serás mejor persona
Por: Freddie
Hola Freddie.

Ya sé que el código 'funciona' SÓLO en Flash 8. Lo que yo comento es que a mi ni siquiera me funciona en Flash8. Ya lo he comentado en el foro y estoy a la espectativa de que alguien me explique qué es lo que hago mal para que tampoco me funcione en Flash8. Acepto mis limitaciones y acepto que soy un torpe. Estaba intentando ayudar al mensaje puesto por AYUDA!!_blog. De todas formas, gracias por tus comentarios, Freddie.

Un saludo.
andsigil@hotmail.com
Por: andsigil_blog
Te envio el FLA.
Pero enseguida pongo un botón para el FLA en el ejemplo de modo que lo puedan bajar todos los que tengan algún problema.
Por: Teseo
teseo eres lo maximo, ojala sigas ayudando asi a los novatos como yo, tus codigos son de lo mejor

gracias
Por: josedelaranda
Hola Teseo yo comparto la misma incertidumbre de andsigil_blog soy nueva en flash y no logro que tu codigo funcione, por favor me puedes mandar el FLA a mi correo confundida181083@yahoo.com. Te lo agradeceria muchisimo.

Gracias
Por: Confundidad_blog
Ya he puesto un botón en el ejemplo para bajar el FLA.
Por: Teseo
Muy bueno el codigo ,sirve para implementar ejercicios parecidos al puzzle
Por: kingKaiser_blog
Hola mira yo necesito hacer algo más o menos parecido. El problema es:
Tengo unos test psicométricos en el cual uno consiste en ensamblar piezas pequeñas para armar una pieza grande, apuesto que alguna vez lo han hecho, bueno el punto es que hay muchisimas formas de ensamblar la figura y no se quiere limitar a el usuario a solo armarla de la forma que a nosotros se nos ocurre, entonces lo único que necesito es como saber si una pieza esta encima de otra, pero las piezas son amorfas y hasta ahorita solo he encontrado detector de colisiones que toman la pieza como si fuese un cuadrado o un rectángulo, alguien me podría ayudar con eso, necesito algo asi como un detector de colisiones para figuras amorfas.
gracias
Por: Moisés_blog
Moisés:
Sobre colisiones entre formas mira este post:
http://www.cristalab.com/foros/viewtopic.php?t=28259
Por: Teseo
estyoy necesitanmdo tipos de letras para me colegio un fobor embienmelo
Por: jose maria _blog
yo quiero saber exactamente para que esta hecho, se que es para la forma de las piezas, pero como lo sacastes???

a=new Array(1,12,0,.35,2,12,1,.15,3,2,4,.2,5,4,6,.5,7,6,8,.5,10,12,2,.15,9,8,10,.4,11,12,10,.15);
Por: dark _blog
bueno, lo que preguntaba es como deduces los valores de ese Array
Por: dark_blog
dark:
Veamos el código que fabrica las curvas de cada lado del puzzle:

Código :

for (g=0; g<2*tpz; g++) {
      b[g] = [];
      b[g][0] = new Point(m1, m2);
      alea()<0 ? sig=-1 : sig=1; // las curvas de encaje para distinto lado aleatoriamente
      if (g%2 == 0) { //puntos para lados horizontales
         b[g][12] = new Point(m1, 4*m2);
         b[g][4] = new Point(m1-m1*sig*.6, m2*(2+alea()));
         b[g][6] = new Point(m1-m1*sig*.9, m2*(2.5+alea()));
         b[g][8] = new Point(m1-m1*sig*.6, m2*(3+alea()));
      } else { //puntos para lados verticales
         b[g][12] = new Point(4*m1, m2);
         b[g][4] = new Point(m1*(2+alea()), m2-m2*sig*.6);
         b[g][6] = new Point(m1*(2.5+alea()), m2-m2*sig*.9);
         b[g][8] = new Point(m1*(3+alea()), m2-m2*sig*.6);
      }
      for (r=0; r<29; r+=4){ //puntos centrales de curvas para H y V 
         b[g][a[r]] = Point.interpolate(b[g][a[r+1]],b[g][a[r+2]],a[r+3]+alea());
      }
   }


La curva a generar necesita 13 puntos (0 a 12) para poder dibujarse.
Primero tengo que determinar, a partir del punto 0, los puntos 12 (otro extremo del lado), 4 ,6 y 8 ("anchor" de cada curva). Hay dos grupos en el código según sea horizontal o vertical el lado.
Esos puntos saldrán aleatoriamente a un lado u otro de la recta 0-12 según el signo de la variable sig :
alea()<0 ? sig=-1 : sig=1;
Para que sea la curva continua, tienen que estar alineados en la misma recta cada grupo según el gráfico.
El array a[] se divide en grupos de 4
a=new Array(
1,12,0,.35,
2,12,1,.15,
3,2,4,.2,
5,4,6,.5,
7,6,8,.5,
10,12,2,.15,
9,8,10,.4,
11,12,10,.15);

y va generando los puntos restantes(1,2,3,5,7,10,9 y 11) por interpolación en la recta.
b[g][a[r]] = Point.interpolate(b[g][a[r+1]],b[g][a[r+2]],a[r+3]+alea());
Es decir:
Para obtener el punto 1 interpolo en la recta 12-0 en porcentaje .35 (+/- un alea de .1)
para el 2 recta 12-1 porcentaje .15 (+/- un alea de .1)
...y así continua el bucle con el resto del array.
Observa que tengo que determinar el punto 10 antes que el 9 pues para determinar el 9 necesito previamente el 10. Ese es el motivo de la alteración del orden de esos elementos en el array.
Los añadidos de aleatorio en el porcentaje de interpolación generan la variación en la forma de la curva.
Por: Teseo
Estaba buscando un codigo similar soy nuevo en Flash considero que esta muy bien explicado. Felicitaciones Teseo
Gracias.
Por: Casv_blog
Muchas gracias.. ahora si le entiendo por completo.
Por: Dark_blog
Bueno, desde hace rato llevo buscando en que parte esta el punto de posicion de cada pieza, por que cuando le metes rotacion a una pieza, esta se posiciona de tal forma que el punto de registro esta en la esquina iquierda de arriba.(la verdad es qun poco mas movido a la izquerda la verdad)¿por que pasa esto y como se soluciona?
Por: Dark_blog
como le meto rotacion y que gire desde su centro?
Por: Dark_blog
Dark:
La esquina de anclaje está correcta, ten en cuenta que necesita 5 módulos m1/m2 de ancho/alto para poder cubrir la "lenguetas" exteriores posibles.

Existen múltiples modos de efectuar un giro por cualquier punto distinto al de anclaje de un MC.
Usando localToGlobal , con trigonometria pura y dura, con la clase Matrix, etc...
Para el caso que nos ocupa ( el puzzle) las rotaciones creo que deben estar restringidas a giros de 90 grados por motivos harto evidentes. Pongo entonces una función adaptada al caso y muy simple que requiere una implementación sencilla. (un control de teclado, la función de rotar y una asignación inmediatamente después del startDrag().

Aparte de eso, en el código inicial del tip se deslizó un error entre el flash de ejemplo y dicho código.
FALTA UNA ASIGNACION DE ARRAY b=[] en esta linea:
Donde pone:
p = []; d = 0;
Debería poner:
p = []; d = 0; b = [];

También consignar que para ver el texto de piezas que faltan se necesita en el escenario un campo de texto dinámico con la variable (en propiedades) texto

Este es el código, con esa corrección efectuada y el giro añadido:

Código :

import flash.display.*;
import flash.geom.*;
import flash.filters.*;

puzzle("imagen", 6, 6, false); // tipo de llamada a la función

function puzzle(imagen, f, c, lin) {
   for (hg=0; hg<4*tpz; hg++){pz[hg].removeMovieClip();} // borra puzzle anterior si existe.
   a=new Array(1,12,0,.35,2,12,1,.15,3,2,4,.2,5,4,6,.5,7,6,8,.5,10,12,2,.15,9,8,10,.4,11,12,10,.15);
   tpz = f*c;
   c>f ? j=20/c : j=20/f;
   bF = new BevelFilter(1,45,0xffffff,.5,0,.5,j,j,4,3,"inner",false);
   img = BitmapData.loadBitmap(imagen);
   w = img.width; h = img.height; m1 = w/(3*c); m2 = h/(3*f);
   // creando matriz delados congruentes entre piezas contiguas
   p = []; d = 0; b = [];
   for (m=0; m<4*tpz; m+=4) {
      p[m+7] = p[m+1] = d++;
      if((d-1)%(2*c) == 2*(c-1)) {p[m+1]=p[(m+4)%(4*tpz) +3]=2*tpz-2};
      p[m+4*c] = p[m+2] = d++;
      if(d>2*(tpz-c) && d%2 == 0) {p[m+2]=p[(m+4*c)%(4*tpz)]=2*tpz-1};
   }
   for (g=0; g<2*tpz; g++) {
      b[g] = [];
      b[g][0] = new Point(m1, m2);
      alea()<0 ? sig=-1 : sig=1; // las curvas de encaje para distinto lado aleatoriamente
      if (g%2 == 0) { //puntos para lados horizontales
         b[g][12] = new Point(m1, 4*m2);
         b[g][4] = new Point(m1-m1*sig*.6, m2*(2+alea()));
         b[g][6] = new Point(m1-m1*sig*.9, m2*(2.5+alea()));
         b[g][8] = new Point(m1-m1*sig*.6, m2*(3+alea()));
      } else { //puntos para lados verticales
         b[g][12] = new Point(4*m1, m2);
         b[g][4] = new Point(m1*(2+alea()), m2-m2*sig*.6);
         b[g][6] = new Point(m1*(2.5+alea()), m2-m2*sig*.9);
         b[g][8] = new Point(m1*(3+alea()), m2-m2*sig*.6);
      }
      for (r=0; r<29; r+=4){ //puntos centrales de curvas para H y V 
         b[g][a[r]] = Point.interpolate(b[g][a[r+1]],b[g][a[r+2]],a[r+3]+alea());
      }
   }
   pz = [];
   pt=[];
   for (n=0; n<f*c; n++) {
      pz[n] = createEmptyMovieClip("pz"+n, n+1);
      tmp2 = new BitmapData(5*m1, 5*m2, true, 0);
      pt[n] = new Point((n%c)*3*m1-m1, Math.floor(n/c)*3*m2-m2);
      tmp2.copyPixels(img,new Rectangle(pt[n].x,pt[n].y,5*m1,5*m2),null);
         //se.attachBitmap(tmp2,0);
      //dibujando los 4 lados de cada pieza
      for (z=0; z<4; z++) {
         z == 2 ? sy=3*m2 : sy=0; z == 1 ? sx=3*m1 : sx=0;
         g = p[4*n+z];
         pz[n].beginBitmapFill(tmp2);
         pz[n].moveTo(5*m1/2, 5*m2/2);
         pz[n].lineTo(b[g][0].x+sx, b[g][0].y+sy);
         if (g>(2*tpz-3) || lin){pz[n].lineTo(b[g][12].x+sx, b[g][12].y+sy);}
         else {
            pz[n].lineTo(b[g][1].x+sx, b[g][1].y+sy);
            for (j=2; j<12; j+=2){
               pz[n].curveTo(b[g][j].x+sx, b[g][j].y+sy,b[g][j+1].x+sx,b[g][j+1].y+sy);
            }
            pz[n].lineTo(b[g][12].x+sx, b[g][12].y+sy);
         }
         pz[n].lineTo(5*m1/2, 5*m2/2);
         pz[n].endFill();
      }
      //doblando la asignacion para evitar fallos de ajuste por decimales.
      pz[n]._x = pt[n].x; pt[n].x = pz[n]._x;
      pz[n]._y = pt[n].y; pt[n].y = pz[n]._y;
      pz[n].filters = [bF];
      pz[n].v = n;
   }
   for (h=0; h<tpz; h++) {
      pz[h].onPress = function() {
         this.startDrag();
         this.swapDepths(tpz+1);
   clip = this;
      }
      pz[h].onRelease = function() {
         this.stopDrag();
         // iman de colocación si  la pieza está cerca de su sitio.
         cerca = new Point(this._x,this._y)
         if (Point.distance(pt[this.v],cerca)< 4+(m1+m2)/15){
            this._x = pt[this.v].x; this._y = pt[this.v].y;
         }
         //comprobador de puzzle completo o piezas que faltan por colocar
         cnt=0;
         for (tt=0; tt<tpz; tt++){
           if((pz[tt]._y == pt[tt].y) && (pz[tt]._x == pt[tt].x) && !pt[tt]._rotation) {++cnt;}
           cnt==tpz ? texto="completo" : texto="faltan: "+(tpz-cnt);
        }
      }
    }
   function alea() {return (.1-Math.random()/5);} // función de extración aleatoria en general.
   // giro de las piezas al pulsar la barra espacio
   teclado=new Object();
  teclado.onKeyDown = function(){Key.getCode()==Key.SPACE ? rotar90() : null;}
  Key.addListener(teclado);
   function rotar90(){
      clip._x -= clip.a2; clip._y -= clip.b2; 
      rt = clip._rotation += 90;
      clip.a2 = 2.5*(m1*(rt!=0)+m1*(rt==180)+m2*(rt==90)-m2*(rt==270));
      clip.b2 = 2.5*(m2*(rt!=0)+m2*(rt==180)-m1*(rt==90)+m1*(rt==270)); 
      clip._x += clip.a2; clip._y += clip.b2 
   }
}

El giro se efectúa al pulsar la barra espaciadora.
Por: Teseo
Muy interesante, y funciona, pero...
¿Has quitado el funcionamiento del botón para descargar el fla?
Por: Emilio_blog
No, no lo he quitado.
En el ejemplo, el botón para bajar el FLA funciona.
En el código publicado no incluyo la instrucción para ese botón.
Por: Teseo
Muchas gracias, es cierto. Ya lo he bajado. Voy a intentar hacer que me funcione la aplicación completa.
Por: Emilio_blog
Respondo aquí por ser más util a todos a un mensaje privado.

Para mezclar las piezas (contenidas en el array pz[] ) y deshacer el puzzle podemos usar una simple función que lo haga:
Para rotar al mezclar, hay que tener incluida la función rotar90() cuyo código anda por ahí en este post.

Código :

// mezcla las piezas en el espacio definido por el cuadrado
// con esquina superior-izquierda(a,b) e inferior-derecha (c,d).
//Si se pasa un quinto valor(e) cualquiera, gira, además, la pieza aleatoriamente 0,90,180 o 270º
function mezclar(a,b,c,d,e){ 
   len=pz.length;
   for(var j=0;j<len;j++){
      pz[j]._x=a+(c-a)*Math.random();
      pz[j]._y=b+(d-b)*Math.random();
       if(e){
         as=Math.floor(4*Math.random());
         for(var k=0;k<as;k++){
            rotar90(pz[j]);
         }
      }
   }
}

Por:
yo hice una que distribucion distinta y deje que se vieran las piezas rotando y se detienen en un momento Ramdon... lo que no encuentro es la forma de unir dos piezas fuera de su lugar y moverlas juntas.. tuve jugando con varios Array pero nada... o_O
Por: Dark_blog
juaz... perece que el tema es abandonado
Por: kal_blog
Aquí podeis ver como ejemplo una versión más completa donde se pueden crear grupos de piezas, zooms con la rueda del ratón, etc..
Por: Teseo
Oye Teseo tengo un cliente que quiere un rompecabezas como el tuyo, solo con unas modificaciones, no se si tengas chance de cotizarme , si gustas mi correo es: pepinillo0170@hotmail.com Saludos
Por: joshuavw
Hola Teseo y amigos del foro.He copiado y pegado el Script y funciona bien.Se trocean las imágenes y la barra de espacio también funciona, el texto dinámico ( "completo" ) también va bien.Los demás textos dinámicos no funcionan y no se porque.Mi mayor problema es con los símbolos , osea los botones.Hago símbolos nuevos los importo a biblioteca , luego los arrastro al escritorio
( antes les nombro como en el ejemplo..."mfilas" etc.) pero no funcionan en la vista previa.No se mucho de Flash , por eso díganme paso a paso como debo proceder para hacer símbolos....( no me sale en la biblioteca los " shape" y no se como se hace, si me sale los símbolos y las iamgenes) .
Hasta ahora solo puedo crear el puzzle con una sola imagen.
Gracias.
Por: Movie_clip
chicos ya se donde radicaba el error...en la capa Actionscript que la coloque abajo del todo.gracias de todas formas.
Por: Movie_clip
Excelente tuto!!! Ahora tengo una consulta, cómo hago para que el puzzle aparezca desarmado en vez de que cada pieza esté en su lugar?

Desde ya muchas gracias!!!
Por: Marcinduq
Es sencillamente genial, ahora hay q estudiar...
Por: Levis
estoy byscando un rompecabezas igual a flash, veo que nose distribuyen las piezas en el fla, si tuvieras un ejemplo con esa accion te lo agradeceria mucho y seria de mucha utlidad, este es mi correo camusjuly@yahoo.com
:)saludos
Por: julio-blog
Hola! Fantastico tutorial, lo he probado y funciona de maravilla incluso en Flash CS3. El único problema con el que me topado es que las fichas aparecen ordenadas. La verdad es que no se por donde empezar para solventar ese problema, si alguién me puede ayudar le estaré eternamente agradecido.

Gracias!!
Por: XAvi-blog
XAvi:
Si añades al código la función mezclar que puse un poco más arriba de este post y la llamas al comienzo, el puzzle aparecerá desordenado. O también puedes poner un botón para mezclar que llame a esa función.
Por: Teseo
ola como estan soy un aprendis de macromedia y pues copie todos los codigos y genial las imagenes se dividen pero lo que no puedo es dispersar las piezas del puzle por mas que intente con el codigo que dejaste Teseo, te agradeceria si pudieras ayudarme gracias.
Por: manuel-blog
Aquí pongo un ejemplo con rotación de las piezas (barra espaciadora) y mezclador. y su FLA:


Bajar FLA
Por: Teseo

Teseo :

Aquí pongo un ejemplo con rotación de las piezas (barra espaciadora) y mezclador. y su FLA
Solo haria falta un onRollOut, ya que cuando presionas una pieza, y la sueltas mientras mueves el cursor rapidamente... Se sigue arrastrando un poco lejos del mismo, haciendo muy dificil soltarla.
:D
Por: M@U
No... me parece que ocurre cuando sueltas la pieza fuera del escenario de flash y este no puede detectar que se ha soltado el mouse. Es algo que suele ocurrir en flash cuando está insertado en un html.
Por: elchininet

elchininet :

No... me parece que ocurre cuando sueltas la pieza fuera del escenario de flash y este no puede detectar que se ha soltado el mouse. Es algo que suele ocurrir en flash cuando está insertado en un html.
Si lo intentas con un movimiento digamos veloz, sin salir del player.. Veras que aun asi sucede, no es nescesaria tenerla fuera de su marco.. Como sea, es un excelente aporte en el Tip.
Teseo++;
Por: M@U
No soy lo suficientemente veloz :lol:

No puedo moverlo rápido sin salirme del marco, necesito un área más grande, parece que no tengo mucho control del mouse.

Pues claro, un excelente aporte. Mis respetos :alabado:
Por: elchininet
M@u:
Eso se produce cuando pinchas la pieza muy cerca de su borde y mueves rápido el ratón para "salir" de la pieza. La pieza puede quedar enganchada por que no lo da tiempo al onRelease a ser detectado en un intervalo de frames.

Tiene simple solución:
Cambiar la linea:

Código :

pz[h].onRelease = function() {


por esta otra:

Código :

pz[h].onRelease =  pz[h].onReleaseOutside = pz[h].onRollOut = function() {


Y el problema desaparece. :wink:
Por: Teseo
esta super chido es lo maximo gracias me saco de un apuro sigue haciendo este tipo de cosas que ayudas a muchos GRACIAS
Por: yajaira-blog
Ahora si tengo algo que estudiar este fin de semana
Por: dmarcasv
Buenas teseo. Que pedazo tutoria. Tengo una duda, he ido inclyendo el código para mezclar desde el principio hasta el final, en los diferents "apartados" del código y no me lo carga nunca mezclado, siempre me lo deja ordenado.
he copiado la función del botón y tampoco me lo desordena. Solo funciona si le doy al botón, pero lo que quiero es que salga desordenado sin presionar ningún botón. He intentado crear un primer frame con un botón "empezar" o algo parecido y que este llame al segundo frame con la función de mezcla pero no me funciona.
Que puedo hacer? o donde no pongo bien el código?

Saludos.
Por: Sacrom-blog
aqui no se encuentra naaaaaaaaaaaaaaaaaa
Por: mdweopfubv-blog
Hey, todo funciona a las mil maravillas, pero no se es como hacer desaparecer las fichas, si paso por ejemplo a otra parte de la presentacion que estoy haciendo despues de haber finalizado, o incluso sin finalizar.... la verdad no se como se quitan o deshabilitan... alguien podria echarme una mano???
Por: Cesar Augusto-blog
El puzzle está en un MovieClip llamado puzz que a su vez cuelga del MC que hizo la llamada a la función. En el caso normal - como en el ejemplo- dicho MC suele ser el raiz. Si se ha cargado en otro MC distinto del raiz habrá que poner la ruta completa en lugar de puzz solamente.

Para deshablilitar:

Código :

puzz._visible = false;


Para eliminar:

Código :

delete puzz;

Por: Teseo
Que tal

esta excelente el codigo
Una pregunta como puedo reemplazar las imagenes por otras?
Por: Arturo-blog
En la primera página de este post está el modo de poner una imagen cualquiera en la biblioteca y vincularla.
Por: Teseo
no entendi nada!!!
Por: el Chabelo-blog
ke alguien me explique no sean gachos
Por: el Chabelo
Gracias!!
Me ha parecido fabuloso tu puzzle :D

Lo utilicé, seguí los pasos de todas las dudas y me ha funcionado muy bien. Gracias por compartirlo con novatos como nosotros.

L.
Por: Luci-blog
Hola necesito hacer un rompecabezas, por tal motivo busque un tutorial que me orientará en la elaboración y me encuentro con esta pagina, soy más novata que todos y mi pregunta es si empiezo hacerlo teniendo encuanta las indicaciones, me voy a encontrar con problemas para que funcione? veo que hablan de un codigo de un fla, entonces quisiera saber donde termina el tutorial y es posible agregarle sonido a cada parte del rompecabezas?
Por: patricia-blog
huy gracias hombre, estube buscando un tuto por este estilo hace 3 dias y eres el unico que se diria que lo tiene sin errores gracias desde colombia.....
Por: alejandro mora -blog
Hola, amigo teseo podes explicar que se hace luego de la vinculacion de la imagen , como se crean los botones.Saludos y gracias
Por: Martin-blog
FELICITACIONES Teseo, muy bueno
Por: ANDRESCABEZA
donde hay q poner el codigo de mezclar para que ya salga descolocado sin tener que pulsar el boton.
Por: viley-blog
Teseo, cuando sea grande, quiero ser como vos..
hahaha, muchas gracias por el tuto.. y excelente manejo de Arrays..
saludos..
Por: ekapam
Hola Teseo, muchas gracias por compartir tu puzzle, oye una pregunta como podríamos poner un botón para desordenar las piezas del mismo, vaya que código llevaría un botón o algo así para que al presionarlo se desordenen todas las piezas del puzzle, creo que con eso quedaría completísima la aplicación. Ojalá me contestes y se pueda implementar eso, no lo he podido hacer yo porque soy un novato en flash y ni que decir en actionscript. Gracias de nuevo y ojalá puedas contestarme.
Por: manolo-blog
Teseo mil perdones, no había visto que lo que te mencione ya lo pusiste en los comentarios, me disculpo y te agradezco tu atención y apoyo, hasta luego.
Por: manolo-blog
Deja un comentario
IMPORTANTE

Recuerda ser respetuoso, no insultes a otras personas, ni uses palabrotas, hay una persona al otro lado de la pantalla.

Habla bien, NO ESCRIBAS EN MAYUSCULA TODO, no escribas como en un SMS, evita cosas como "ke", "x q" y demás abreviaciones.

Aquí funcionan las etiquetas de los foros, puedes usar [b] para negrita, [img] para las imágenes, [url] para los enlaces, etc.

Si tienes preguntas técnicas, envíalas mejor al foro.