Crear una aplicación básica de dibujo en Flash
Spanish (Español) translation by Esther (you can also view the original English article)
Dos veces al mes, revisamos algunas de las publicaciones favoritas de nuestros lectores a lo largo de la historia de Activetuts+. Este tutorial se publicó por primera vez en agosto de 2009.
En este tutorial, crearemos una aplicación de dibujo con funciones básicas y una interfaz fácil de usar. ¿Te sientes artístico? Entonces vamos...
Paso 1: Resumen
Esta aplicación contará con una serie de herramientas como el lápiz, la goma de borrar, la herramienta de texto, y también la posibilidad de guardar tu dibujo en formato png utilizando el codificador PNG de Adobe.
Paso 2: Configuración
Abra Flash y crea un nuevo archivo Flash (ActionScript 3).

Establece el tamaño del escenario en 600x350px y la velocidad de fotogramas en 25fps.


Paso 3: Tablero
Dibuja un rectángulo blanco de 600x290px y conviértelo en MovieClip. Establece su nombre de instancia como "board" y alinéalo en la parte superior izquierda del escenario.


Esta será la zona sobre la que podremos dibujar.
Paso 4: Panel de herramientas
Crea un rectángulo gris (#DFDF) de 600px de ancho y 60px de alto y alinéalo en la parte inferior del escenario. Este será nuestro fondo para el Panel de Herramientas.


Paso 5: Iconos de herramientas
No voy a cubrir la creación de los iconos de las herramientas ya que esa no es la intención del turorial, aun así, puedes ver cómo se hacen en el archivo Fla incluido en el Source.

Como puedes ver en la imagen, vamos a utilizar dos iconos, uno en tono gris y otro en color.
Convierte el icono del lápiz gris en un Botón (F8) y nómbralo "pencilTool", haz doble clic para editarlo y añade un KeyFrame (F6) en el estado "over". Aquí es donde vamos a poner la versión en color del icono.


Por último, añade otro KeyFrame en el estado "hit", y dibuja un cuadrado de 30x30px para que actúe como el área de hit del botón.


Repite este proceso con todos tus iconos de herramientas, no olvides darles los nombres de instancia correctos (eraserTool, textTool, saveButton, clearTool).
Para mostrar el icono de la herramienta activa, vamos a utilizar la versión en color del icono y colocarlo en la misma posición del botón que hemos creado antes. Los nombres de las instancias serán "lápiz", "borrador" y "texto".

Más adelante ocultaremos estos iconos utilizando ActionScript.
Paso 6: Guardar el diálogo
Cuando utilicemos la opción de guardar vamos a mostrar un mensaje de "guardar con éxito".
Crea un rectángulo negro de 600x350px con 50% de alfa para usarlo como fondo.


Añade un rectángulo negro redondeado en el centro con el icono del botón de guardado y algún texto que indique que el guardado se ha completado.


Crea un botón de cierre y alinéalo en la parte superior izquierda del rectángulo redondeado, llámalo "closeBtn". Como puedes imaginar, este botón cerrará el diálogo de guardar.


Convierte todos los elementos en un único MovieClip y marca la casilla "Exportar para ActionScript". Establece el campo de texto Clase como "SaveDialog".


Instanciaremos esta clase cuando el usuario pulse el SaveButton y se complete el guardado.
Paso 7: Tamaño del panel
El tamaño del panel es el área donde puedes cambiar el tamaño del lápiz, el borrador y la herramienta de texto. Puedes hacerlo haciendo clic en el área del panel o en el óvalo que hay dentro de él.
Selecciona la Herramienta Primitiva Rectángulo, establece el radio de la esquina en 4 y crea un rectángulo #EFEFEF 80x50px. Conviértelo en un MovieClip y nómbralo "sizePanel".


Abre el panel de Filtros y añade una Sombra Caída con los siguientes valores:


Ahora usa la Herramienta Oval para crear un círculo negro de 5x5px y céntralo en el Panel de Tamaño, conviértelo en MovieClip y establece su nombre de instancia como "shapeSize".

Paso 8: Colores por defecto
Crearemos una paleta de colores por defecto en lugar de utilizar el componente de selección de colores.
Crea un círculo de 22x22px usando la Herramienta Oval, establece su color a #EEEEEE y conviértelo en MovieClip. Añade el mismo filtro de sombra que usamos en el panel de tamaño.

Dibuja un segundo círculo de 16x16px y utiliza esta vez el color negro. Centra los círculos y repite este proceso cambiando el último color del círculo por el siguiente:

Alinearlos para terminar con algo así:


Convierte todos los colores a un solo MovieClip, nómbralo "colores" y asegúrate de establecer el Punto de Registro en la parte superior izquierda, ya que vamos a obtener datos de píxeles utilizando la Clase Bitmap.

Paso 9: Adobe PNG Encoder
Para utilizar la función Save necesitaremos el Adobe PNG Encoder que forma parte del as3corelib que puedes encontrar en Google Code.
Para utilizar esta clase fuera del paquete que viene por defecto, tenemos que cambiar una línea. Abre el archivo PNGEncoder.as y cambia la línea "package com.adobe..." por solo "package". Esto nos permitirá llamar a la clase en el directorio donde está el archivo Fla.
Paso 10: Clase principal
Una sola Clase manejará esta aplicación. Abre el Panel de Propiedades en el archivo Fla y establece la Clase de Documento como "Principal".

Crea un nuevo documento ActionScript y guárdalo como "Main.as" en el mismo directorio donde está el archivo Fla.
Paso 11: Importar las clases requeridas
Estas son las clases que vamos a necesitar en esta aplicación. Recuerda consultar la ayuda de Flash (F1) si no estás seguro de una clase específica.
1 |
package |
2 |
{
|
3 |
import PNGEncoder; |
4 |
import flash.display.MovieClip; |
5 |
import flash.display.Shape; |
6 |
import flash.display.DisplayObject; |
7 |
import flash.text.TextField; |
8 |
import flash.text.TextFormat; |
9 |
import flash.text.TextFieldType; |
10 |
import flash.text.TextFieldAutoSize; |
11 |
import flash.display.BitmapData; |
12 |
import flash.geom.ColorTransform; |
13 |
import flash.events.MouseEvent; |
14 |
import flash.events.Event; |
15 |
import flash.utils.ByteArray; |
16 |
import flash.net.FileReference; |
Paso 12: Ampliar la clase
Estamos extendiendo la clase MovieClip ya que utilizamos las propiedades y métodos específicos de esta clase.
1 |
public class Main extends MovieClip |
2 |
{
|
Paso 13: Variables
Estas son las variables que utilizaremos. Todas están explicadas en los comentarios del código.
1 |
/* Pencil Tool shape, everything drawn with this tool and the eraser tool is stored inside board.pencilDraw */ |
2 |
|
3 |
var pencilDraw:Shape = new Shape(); |
4 |
|
5 |
/* Text format */ |
6 |
|
7 |
var textformat:TextFormat = new TextFormat(); |
8 |
|
9 |
/* Colors */ |
10 |
|
11 |
var colorsBmd:BitmapData; //We'll use this Bitmap Data to get the pixel RGB Value when clicked |
12 |
var pixelValue:uint; |
13 |
var activeColor:uint = 0x000000; //This is the current color in use, displayed by the shapeSize MC |
14 |
|
15 |
/* Save dialog instance */ |
16 |
|
17 |
var saveDialog:SaveDialog; |
18 |
|
19 |
/* Active var, to check which tool is active */ |
20 |
|
21 |
var active:String; |
22 |
|
23 |
/* Shape size color */ |
24 |
|
25 |
var ct:ColorTransform = new ColorTransform(); |
Paso 14: Función principal
La función principal se encargará de establecer el Formato de Texto de la Herramienta de Texto, convertir el MovieClip de Colores a Datos de Mapa de Bits para que podamos extraer el Valor RGB de los Píxeles, añadir los oyentes y ocultar los iconos activos.
1 |
public function Main():void |
2 |
{
|
3 |
textformat.font = "Quicksand Bold Regular"; // You can use any font you like |
4 |
textformat.bold = true; |
5 |
textformat.size = 16; |
6 |
|
7 |
/* We create these functions later */ |
8 |
|
9 |
convertToBMD(); |
10 |
|
11 |
addListeners(); |
12 |
|
13 |
/* Hide tools highlights */ |
14 |
|
15 |
pencil.visible = false; |
16 |
hideTools(eraser, txt); |
17 |
} |
Paso 15: Acciones de las herramientas
Las acciones de las herramientas se dividen en cuatro funciones.
El primero pondrá la herramienta en su estado Activo, el segundo y el tercero manejarán los Eventos del Ratón (como Dibujar o Borrar) y el cuarto detendrá esos Eventos.
Paso 16: Herramienta Lápiz
Estas funciones manejan la Herramienta Lápiz, lee los comentarios en el código para una mejor comprensión.
La función de fijar en activo:
1 |
private function PencilTool(e:MouseEvent):void |
2 |
{
|
3 |
/* Quit active tool */ |
4 |
|
5 |
quitActiveTool(); //This function will be created later |
6 |
|
7 |
/* Set to Active */ |
8 |
|
9 |
active = "Pencil"; //Sets the active variable to "Pencil" |
10 |
|
11 |
/* Adds the listeners to the board MovieClip, to draw just in it */ |
12 |
|
13 |
board.addEventListener(MouseEvent.MOUSE_DOWN, startPencilTool); |
14 |
board.addEventListener(MouseEvent.MOUSE_UP, stopPencilTool); |
15 |
|
16 |
/* Highlight, sets the Pencil Tool Icon to the color version, and hides any other tool */ |
17 |
|
18 |
highlightTool(pencil); |
19 |
hideTools(eraser, txt); |
20 |
|
21 |
/* Sets the active color variable based on the Color Transform value and uses that color for the shapeSize MovieClip */ |
22 |
|
23 |
ct.color = activeColor; |
24 |
shapeSize.transform.colorTransform = ct; |
25 |
} |
La función de inicio; esta función se llama cuando se pulsa el MovieClip de la Junta.
1 |
private function startPencilTool(e:MouseEvent):void |
2 |
{
|
3 |
pencilDraw = new Shape(); //We add a new shape to draw always in top (in case of text, or eraser drawings) |
4 |
board.addChild(pencilDraw); //Add that shape to the board MovieClip |
5 |
|
6 |
pencilDraw.graphics.moveTo(mouseX, mouseY); //Moves the Drawing Position to the Mouse Position |
7 |
pencilDraw.graphics.lineStyle(shapeSize.width, activeColor);//Sets the line thickness to the ShapeSize MovieClip size and sets its color to the current active color |
8 |
|
9 |
board.addEventListener(MouseEvent.MOUSE_MOVE, drawPencilTool); //Adds a listener to the next function |
10 |
} |
La función Draw; llamada cuando el usuario presiona el MovieClip de la Junta y mueve el ratón.
1 |
private function drawPencilTool(e:MouseEvent):void |
2 |
{
|
3 |
pencilDraw.graphics.lineTo(mouseX, mouseY); //Draws a line from the current Mouse position to the moved Mouse position |
4 |
} |
Función de parada, ejecutada cuando el usuario suelta el ratón.
1 |
private function stopPencilTool(e:MouseEvent):void |
2 |
{
|
3 |
board.removeEventListener(MouseEvent.MOUSE_MOVE, drawPencilTool); //Stops the drawing |
4 |
} |
Paso 17: Herramienta Borrador
La Herramienta Borrador es prácticamente igual que la Herramienta Lápiz, excepto que no utilizamos ningún otro color que no sea el blanco.
1 |
private function EraserTool(e:MouseEvent):void |
2 |
{
|
3 |
/* Quit active tool */ |
4 |
|
5 |
quitActiveTool(); |
6 |
|
7 |
/* Set to Active */ |
8 |
|
9 |
active = "Eraser"; |
10 |
|
11 |
/* Listeners */ |
12 |
|
13 |
board.addEventListener(MouseEvent.MOUSE_DOWN, startEraserTool); |
14 |
board.addEventListener(MouseEvent.MOUSE_UP, stopEraserTool); |
15 |
|
16 |
/* Highlight */ |
17 |
|
18 |
highlightTool(eraser); |
19 |
hideTools(pencil, txt); |
20 |
|
21 |
/* Use White Color */ |
22 |
|
23 |
ct.color = 0x000000; |
24 |
|
25 |
shapeSize.transform.colorTransform = ct; |
26 |
} |
27 |
|
28 |
private function startEraserTool(e:MouseEvent):void |
29 |
{
|
30 |
pencilDraw = new Shape(); |
31 |
board.addChild(pencilDraw); |
32 |
|
33 |
pencilDraw.graphics.moveTo(mouseX, mouseY); |
34 |
pencilDraw.graphics.lineStyle(shapeSize.width, 0xFFFFFF); //White Color |
35 |
|
36 |
board.addEventListener(MouseEvent.MOUSE_MOVE, drawEraserTool); |
37 |
} |
38 |
|
39 |
private function drawEraserTool(e:MouseEvent):void |
40 |
{
|
41 |
pencilDraw.graphics.lineTo(mouseX, mouseY); |
42 |
} |
43 |
|
44 |
function stopEraserTool(e:MouseEvent):void |
45 |
{
|
46 |
board.removeEventListener(MouseEvent.MOUSE_MOVE, drawEraserTool); |
47 |
|
48 |
} |
Como puedes ver, el código es el mismo excepto por los cambios de color blanco.
Paso 18: Herramienta texto
La Herramienta Texto tiene solo dos funciones; una encargada de ponerla en activo, y la otra para manejar la escritura del texto. Echemos un vistazo:
1 |
private function TextTool(e:MouseEvent):void |
2 |
{
|
3 |
/* Quit active tool */ |
4 |
|
5 |
quitActiveTool(); |
6 |
|
7 |
/* Set to Active */ |
8 |
|
9 |
active = "Text"; |
10 |
|
11 |
/* Listener */ |
12 |
|
13 |
board.addEventListener(MouseEvent.MOUSE_UP, writeText); |
14 |
|
15 |
/* Highlight */ |
16 |
|
17 |
highlightTool(txt); |
18 |
hideTools(pencil, eraser); |
19 |
} |
20 |
|
21 |
private function writeText(e:MouseEvent):void |
22 |
{
|
23 |
/* Create a new TextField Object, this way we won't replace older instances */ |
24 |
|
25 |
var textfield = new TextField(); |
26 |
|
27 |
/* Set Formats, position, and focus */ |
28 |
|
29 |
textfield.type = TextFieldType.INPUT; |
30 |
textfield.autoSize = TextFieldAutoSize.LEFT; |
31 |
textfield.defaultTextFormat = textformat; |
32 |
textfield.textColor = activeColor; |
33 |
textfield.x = mouseX; |
34 |
textfield.y = mouseY; |
35 |
stage.focus = textfield; |
36 |
|
37 |
/* Add text to Board */ |
38 |
|
39 |
board.addChild(textfield); |
40 |
} |
Esta fue fácil, recuerda que puedes cambiar el tamaño y el color usando el shapeSize y el Colors MovieClips.
Paso 19: Opción Guardar
La opción de guardar manejada por el saveButton hará uso de la clase PNGEnconder de Adobe para guardar la obra de arte como un archivo PNG.
1 |
private function export():void |
2 |
{
|
3 |
var bmd:BitmapData = new BitmapData(600, 290);//Creates a new BitmapData with the board size |
4 |
|
5 |
bmd.draw(board);//Draws the board MovieClip into a BitmapImage in the BitmapData |
6 |
|
7 |
var ba:ByteArray = PNGEncoder.encode(bmd); //Creates a ByteArray of the BitmapData, encoded as PNG |
8 |
|
9 |
var file:FileReference = new FileReference(); // Instantiates a new File Reference Object to handle the save |
10 |
|
11 |
file.addEventListener(Event.COMPLETE, saveSuccessful); //Adds a new listener to listen when the save is complete |
12 |
|
13 |
file.save(ba, "MyDrawing.png"); //Saves the ByteArray as a PNG |
14 |
} |
15 |
|
16 |
private function saveSuccessful(e:Event):void |
17 |
{
|
18 |
saveDialog = new SaveDialog();// Instantiates a new SaveDialog Class |
19 |
|
20 |
addChild(saveDialog); //Adds the SaveDialog MovieClip to the Stage |
21 |
|
22 |
saveDialog.closeBtn.addEventListener(MouseEvent.MOUSE_UP, closeSaveDialog);//Adds a listener to the close button of the dialog |
23 |
} |
24 |
|
25 |
private function closeSaveDialog(e:MouseEvent):void |
26 |
{
|
27 |
removeChild(saveDialog); //Removes the dialog of the Stage |
28 |
} |
29 |
|
30 |
private function save(e:MouseEvent):void |
31 |
{
|
32 |
export(); //Calls the export function to begin the saving process |
33 |
} |
Paso 20: Herramienta Borrar
La Herramienta Borrar añadirá una pantalla blanca delante de todos los elementos para dejar el tablero listo para volver a dibujar.
1 |
private function clearBoard(e:MouseEvent):void |
2 |
{
|
3 |
/* Create a white rectangle on top of everything */ |
4 |
|
5 |
var blank:Shape = new Shape(); |
6 |
|
7 |
blank.graphics.beginFill(0xFFFFFF); |
8 |
blank.graphics.drawRect(0, 0, board.width, board.height); |
9 |
blank.graphics.endFill(); |
10 |
|
11 |
board.addChild(blank); |
12 |
} |
Paso 21: Obtener el valor de los colores
Para obtener el valor de los colores que estamos utilizando en el MovieClip Colors, lo convertimos en un objeto BitmapData y utilizamos el método getPixel para obtener el valor RGB del píxel pulsado.
1 |
private function convertToBMD():void |
2 |
{
|
3 |
colorsBmd = new BitmapData(colors.width,colors.height); |
4 |
colorsBmd.draw(colors); |
5 |
} |
6 |
|
7 |
private function chooseColor(e:MouseEvent):void |
8 |
{
|
9 |
pixelValue = colorsBmd.getPixel(colors.mouseX,colors.mouseY);//Gets the cliked pixel RGB value |
10 |
activeColor = pixelValue; |
11 |
|
12 |
/* Use a ColorTransform object to change the shapeSize MovieClip color */ |
13 |
|
14 |
ct.color = activeColor; |
15 |
shapeSize.transform.colorTransform = ct; |
16 |
} |
Añadiremos el listener de chooseColor en la función addListeners más adelante en el código.
Paso 22: Herramienta Activa
Anteriormente, declaramos una variable para establecer la herramienta activa o actual en uso, y llamamos a esta función para eliminar los oyentes correspondientes con el fin de tener solo una herramienta activa.
Básicamente, la función comprueba la variable "activa" en un bucle de conmutación, y luego, dependiendo de su valor, elimina los oyentes que tiene.
1 |
private function quitActiveTool():void |
2 |
{
|
3 |
switch (active) |
4 |
{
|
5 |
case "Pencil" : |
6 |
board.removeEventListener(MouseEvent.MOUSE_DOWN, startPencilTool); |
7 |
board.removeEventListener(MouseEvent.MOUSE_UP, stopPencilTool); |
8 |
case "Eraser" : |
9 |
board.removeEventListener(MouseEvent.MOUSE_DOWN, startEraserTool); |
10 |
board.removeEventListener(MouseEvent.MOUSE_UP, stopEraserTool); |
11 |
case "Text" : |
12 |
board.removeEventListener(MouseEvent.MOUSE_UP, writeText); |
13 |
default : |
14 |
} |
15 |
} |
También tenemos que resaltar la herramienta activa y ocultar las demás:
1 |
private function highlightTool(tool:DisplayObject):void |
2 |
{
|
3 |
tool.visible=true; //Highlights tool in the parameter |
4 |
} |
5 |
|
6 |
/* Hides the tools in the parameters */ |
7 |
|
8 |
private function hideTools(tool1:DisplayObject, tool2:DisplayObject):void |
9 |
{
|
10 |
tool1.visible=false; |
11 |
tool2.visible=false; |
12 |
} |
Paso 23: Tamaño de la forma
Hacemos clic en el Panel de Tamaño o en el MovieClip ShapeSize para cambiar el tamaño del Lápiz, el Borrador y la Herramienta Texto. El tamaño se cambia en intervalos de 5, y se restablece cuando el tamaño es mayor o igual a 50. Echa un vistazo al código:
1 |
private function changeShapeSize(e:MouseEvent):void |
2 |
{
|
3 |
if (shapeSize.width >= 50) |
4 |
{
|
5 |
shapeSize.width = 1; |
6 |
shapeSize.height = 1; |
7 |
|
8 |
/* TextFormat */ |
9 |
|
10 |
textformat.size = 16; |
11 |
} |
12 |
else |
13 |
{
|
14 |
shapeSize.width += 5; |
15 |
shapeSize.height=shapeSize.width; |
16 |
|
17 |
/* TextFormat */ |
18 |
|
19 |
textformat.size+=5; |
20 |
} |
21 |
} |
Paso 24: Añadir oyentes
Una función para añadir todos los oyentes.
1 |
private function addListeners():void |
2 |
{
|
3 |
pencilTool.addEventListener(MouseEvent.MOUSE_UP, PencilTool); |
4 |
eraserTool.addEventListener(MouseEvent.MOUSE_UP, EraserTool); |
5 |
textTool.addEventListener(MouseEvent.MOUSE_UP, TextTool); |
6 |
saveButton.addEventListener(MouseEvent.MOUSE_UP, save); |
7 |
clearTool.addEventListener(MouseEvent.MOUSE_UP, clearBoard); |
8 |
colors.addEventListener(MouseEvent.MOUSE_UP, chooseColor); |
9 |
sizePanel.addEventListener(MouseEvent.MOUSE_UP, changeShapeSize); |
10 |
shapeSize.addEventListener(MouseEvent.MOUSE_UP, changeShapeSize); |
11 |
} |
Paso 25: Prueba
Prueba tu aplicación pulsando cmd+return y comprueba si todo funciona como se espera.
Utiliza todas las herramientas, colores y funciones y empieza a dibujar tu escena.
Conclusión
Esta película Flash puede ser fácilmente adaptada como una aplicación de dibujo para niños, tiene una interfaz de usuario amigable y herramientas básicas que pueden enseñar cómo funciona el ratón mientras se divierten en el proceso.
También puedes explorar el resto de as3corelib y leer su documentación para aprender algunas nuevas características de ActionScript.
¡Gracias por leer!



