Después de probar de distintas maneras se me ocurrió lo siguiente: tengo por un lado una imagen con el dibujo totalmente en blanco con las líneas del dibujo negras. Entonces al hacer clic con el bote de pintura, lo que hago es detectar en el dibujo con un BitmapData cuándo me encuentro con un píxel en negro. Para ir rellenando de un color, lo que hago es intentar dibujar en todas direcciones, arriba, abajo, izquierda y derecha. Cuando me quedo "atascado", vuelvo hacia atrás a intentar otro "movimiento". Cuando haya vuelto al primero y no pueda seguir "moviéndome", habré terminado de dibujar el área.
Os pongo el código:
Código :
function Bote(bmd:BitmapData,pos_x:Number,pos_y:Number) { // bmd es el bitmap donde guardo qué pixeles dibujo para al final aplicarlos a un nuevo mc // _global.BitmapDibujo es la imagen que tengo en blanco y negro para detectar cuándo llego // al borde del área para dibujar // _global.ColorPincel es el color seleccionado para rellenar el área // Comprobamos que el punto esté en las coordenadas del lienzo if((pos_x>200)&&(pos_x<680)&&(pos_y>20)&&(pos_y<740)) { if(_global.BitmapDibujo.getPixel(pos_x,pos_y).toString(16)<>"000000") { // El pixel no está en negro, así que comenzamos Coordenadas=new Array(); // Apuntamos el punto en las coordenadas // Indice activo (ia): índice del vector de coordenadas ya dibujadas var ia:Number=0; Coordenadas[ia]=Array(pos_x,pos_y); while(ia>=0) { atasco=true; // Probamos a ir hacia arriba // Tres comprobaciones: si está fuera de las coordenadas, si es un pixel negro // y si ya está dibujado con el color del pincel. Si se da algun caso, es un atasco // y hay que probar con otro "movimiento". if((Coordenadas[ia][0]>200)&&(Coordenadas[ia][0]<680)&& ((Coordenadas[ia][1]-1)>20)&&((Coordenadas[ia][1]-1)<740)) { if(_global.BitmapDibujo.getPixel( Coordenadas[ia][0],(Coordenadas[ia][1]-1)).toString(16)<>"000000") { if(bmd.getPixel(Coordenadas[ia][0],(Coordenadas[ia][1]-1))<> _global.ColorPincel) { // Se puede pintar. Quitamos el atasco atasco=false; // Dibujamos el pixel bmg.setPixel(Coordenadas[ia][0],(Coordenadas[ia][1]-1), _global.ColorPincel); // Añadimos el nuevo pixel a la lista Coordenadas[ia+1]=Array(Coordenadas[ia][0],(Coordenadas[ia][1]-1)); ia=ia+1; } } } // Si sigue habiendo atasco, probamos con el de la izquierda if(atasco==true) { if(((Coordenadas[ia][0]-1)>200)&&((Coordenadas[ia][0]-1)<680)&& ((Coordenadas[ia][1])>20)&&(Coordenadas[ia][1]<740)) { if(_global.BitmapDibujo.getPixel( (Coordenadas[ia][0]-1),Coordenadas[ia][1]).toString(16)<>"000000") { if(bmd.getPixel((Coordenadas[ia][0]-1),Coordenadas[ia][1])<> _global.ColorPincel) { // Se puede pintar. Quitamos el atasco atasco=false; // Dibujamos el pixel bmg.setPixel((Coordenadas[ia][0]-1),Coordenadas[ia][1], _global.ColorPincel); // Añadimos el nuevo pixel a la lista Coordenadas[ia+1]=Array((Coordenadas[ia][0]-1),Coordenadas[ia][1]); ia=ia+1; } } } } // Si sigue habiendo atasco, probamos con el de abajo if(atasco==true) { if((Coordenadas[ia][0]>200)&&(Coordenadas[ia][0]<680)&& ((Coordenadas[ia][1]+1)>20)&&((Coordenadas[ia][1]+1)<740)) { if(_global.BitmapDibujo.getPixel( Coordenadas[ia][0],(Coordenadas[ia][1]+1)).toString(16)<>"000000") { if(bmd.getPixel(Coordenadas[ia][0],(Coordenadas[ia][1]+1))<> _global.ColorPincel) { // Se puede pintar. Quitamos el atasco atasco=false; // Dibujamos el pixel bmg.setPixel(Coordenadas[ia][0],(Coordenadas[ia][1]+1), _global.ColorPincel); // Añadimos el nuevo pixel a la lista Coordenadas[ia+1]=Array(Coordenadas[ia][0],(Coordenadas[ia][1]+1)); ia=ia+1; } } } } // Si sigue habiendo atasco, probamos con el de la derecha if(atasco==true) { if(((Coordenadas[ia][0]+1)>200)&&((Coordenadas[ia][0]+1)<680)&& ((Coordenadas[ia][1])>20)&&(Coordenadas[ia][1]<740)) { if(_global.BitmapDibujo.getPixel( (Coordenadas[ia][0]+1),Coordenadas[ia][1]).toString(16)<>"000000") { if(bmd.getPixel((Coordenadas[ia][0]+1),Coordenadas[ia][1])<>_global.ColorPincel) { // Se puede pintar. Quitamos el atasco atasco=false; // Dibujamos el pixel bmg.setPixel((Coordenadas[ia][0]+1),Coordenadas[ia][1], _global.ColorPincel); // Añadimos el nuevo pixel a la lista Coordenadas[ia+1]=Array((Coordenadas[ia][0]+1),Coordenadas[ia][1]); ia=ia+1; } } } } // Si hay atasco en todas las direcciones, tenemos que probar con la coordenada // anterior if(atasco==true) { ia--; } } } } }
Depurando el código y ejecutando paso por paso he comprobado que funciona. El problema es que la animación se ralentiza una barbaridad, hasta que me sale el dichoso mensaje de que un script está haciendo que vaya muy lento y que si quiero detener el script.
Ésta es la tercera versión, jejejeje. Al principio probé con recursividad, con el mismo procedimiento: pintaba un píxel y sus adyacentes, y los apuntaba en un array, y seguia pintando píxeles de la misma manera siempre que no estuvieran en la lista de los ya pintados. Pero me encuentro con que Actionscript no soporta más de 256 ejecuciones recursivas... vamos, que me cortó el rollo. Cuando pasé esa función de recursiva a iterativa, me encontré con el mismo problema, que se ralentizaba pero pensé que podría ser por buscar tantas veces en el Array coordenadas ya dibujadas, así que al final di con esta solución para sólo tener que moverte hacia delante y hacia atrás en el Array y no tener que recorrerlo cada vez que intentas dibujar un pixel. Pero vamos, las desgracias nunca vienen solas, jejejeje.
Por si a alguien le ha gustado la idea, le comento que por el momento lo he solucionado "mapeando" las zonas que puedes rellenar, de la siguiente forma: Photoshop en mano, he invertido los colores de la imagen, y guardado cada "trozo" que se puede rellenar. En el script cargo todas las imagenes en mc separados. Cuando uso el bote de pintura miro todos estos mc con un BitmapData a ver dónde se encuentra dibujado en negro. Cuando lo encuentro, duplico la capa y utilizo ésta nueva como máscara de otra que relleno del color elegido con setMask(). Lo malo de esta solución es que tienes que preparar la imagen con anterioridad para poder usarla, cuando tiene más gracia que pudiera hacerse con cualquier gif que cargues.
Un saludo, y gracias de antemano por la ayuda.
Anubis