Ejemplo de entrada de ratón: WordSearch

Flash Player 9 y posterior, Adobe AIR 1.0 y posterior

En este ejemplo se ilustra la interacción del usuario mediante la gestión de eventos del ratón. Los usuarios deben crear la mayor cantidad posible de palabras a partir de una cuadrícula aleatoria de letras moviéndose horizontalmente o verticalmente por la cuadrícula, pero no pueden utilizar dos veces una misma letra. Este ejemplo muestra las siguientes características de ActionScript 3.0:

  • Generación de una cuadrícula de componentes de forma dinámica

  • Respuesta a eventos de ratón

  • Mantenimiento de una puntuación según la interacción del usuario

Para obtener los archivos de la aplicación de este ejemplo, consulte www.adobe.com/go/learn_programmingAS3samples_flash_es. Los archivos de la aplicación WordSearch se encuentran en la carpeta Samples/WordSearch. La aplicación consta de los siguientes archivos:

Archivo

Descripción

WordSearch.as

Clase que proporciona la funcionalidad principal de la aplicación.

WordSearch.fla

o

WordSearch.mxml

Archivo principal de la aplicación Flex (MXML) o Flash (FLA).

dictionary.txt

Un archivo que se utiliza para determinar si las palabras escritas puntúan y están bien escritas.

Carga de un diccionario

Para crear un juego consistente en encontrar palabras hay que utilizar un diccionario. En el ejemplo se incluye un archivo de texto denominado dictionary.txt, que contiene una lista de palabras separadas por retornos de carro. Después de crear un conjunto denominado words, la función loadDictionary() solicita este archivo y, una vez cargado correctamente, lo convierte en una cadena larga. Esta cadena se puede analizar para generar un conjunto de palabras con el método split(), dividiéndola en cada instancia del retorno de carro (código de carácter 10) o línea nueva (código de carácter 13). Este análisis se realiza en la función dictionaryLoaded():

words = dictionaryText.split(String.fromCharCode(13, 10));

Creación de la interfaz de usuario

Una vez almacenadas las palabras, se puede configurar la interfaz de usuario. Cree dos instancias de Button: una para enviar una palabra y otra para borrar una palabra que ya se ha formado. En cada caso, hay que responder a entradas de usuario detectando el evento MouseEvent.CLICK difundido por el botón y llamando a continuación a la función. En la función setupUI(), este código crea los detectores en los dos botones:

submitWordButton.addEventListener(MouseEvent.CLICK,submitWord); 
clearWordButton.addEventListener(MouseEvent.CLICK,clearWord);

Generación de un tablero de juego

El tablero del juego es una cuadrícula de letras aleatorias. En la función generateBoard() se crea una cuadrícula bidimensional anidando un bucle dentro de otro. El primer bucle incrementa las filas y el segundo incrementa el número total de columnas por fila. Cada una de las celdas creadas por estas filas y columnas contiene un botón que representa una letra del tablero.

private function generateBoard(startX:Number, startY:Number, totalRows:Number, totalCols:Number, buttonSize:Number):void 
{ 
    buttons = new Array(); 
    var colCounter:uint; 
    var rowCounter:uint; 
    for (rowCounter = 0; rowCounter < totalRows; rowCounter++) 
    { 
        for (colCounter = 0; colCounter < totalCols; colCounter++) 
        { 
            var b:Button = new Button(); 
            b.x = startX + (colCounter*buttonSize); 
            b.y = startY + (rowCounter*buttonSize); 
            b.addEventListener(MouseEvent.CLICK, letterClicked); 
            b.label = getRandomLetter().toUpperCase(); 
            b.setSize(buttonSize,buttonSize); 
            b.name = "buttonRow"+rowCounter+"Col"+colCounter; 
            addChild(b); 
             
            buttons.push(b); 
        } 
    } 
}

Aunque solo hay una línea que añade un detector para un evento MouseEvent.CLICK, como está en un bucle for se asignará un detector a cada instancia de Button. Además, a cada botón se le asigna un nombre derivado de su posición de fila y columna, lo que proporciona una manera sencilla de hacer referencia a la fila y columna de cada botón en otras partes del código.

Creación de palabras a partir de entradas de usuario

Las palabras pueden escribirse seleccionando letras contiguas horizontal o verticalmente, pero nunca se puede usar dos veces la misma letra. Cada clic genera un evento de ratón y hace que se compruebe que la palabra que el usuario está escribiendo es la continuación correcta de las letras en las que se hizo clic previamente. En caso contrario, se elimina la palabra anterior y se inicia otra nueva. Esta comprobación se produce en el método isLegalContinuation().

private function isLegalContinuation(prevButton:Button, currButton:Button):Boolean 
{ 
    var currButtonRow:Number = Number(currButton.name.charAt(currButton.name. indexOf("Row") + 3)); 
    var currButtonCol:Number = Number(currButton.name.charAt(currButton.name.indexOf("Col") + 3)); 
    var prevButtonRow:Number = Number(prevButton.name.charAt(prevButton.name.indexOf("Row") + 3)); 
    var prevButtonCol:Number = Number(prevButton.name.charAt(prevButton.name.indexOf("Col") + 3)); 
     
    return ((prevButtonCol == currButtonCol && Math.abs(prevButtonRow - currButtonRow) <= 1) || 
             (prevButtonRow == currButtonRow && Math.abs(prevButtonCol - currButtonCol) <= 1)); 
}

Los métodos charAt() e indexOf() de la clase String recuperan las filas y columnas adecuadas del botón en el que se acaba de hacer clic y del botón en el que se hizo clic previamente. El método isLegalContinuation() devuelve true si la fila o columna no cambia, y si la fila o columna que ha cambiado corresponde a un solo incremento con respecto a la anterior. Si se desea cambiar las reglas del juego y permitir la formación de palabras en diagonal, se pueden eliminar las comprobaciones de filas o columnas que no cambian; la línea final sería como la siguiente:

return (Math.abs(prevButtonRow - currButtonRow) <= 1) && Math.abs(prevButtonCol - currButtonCol) <= 1));

Comprobación de las palabras formadas

Para completar el código del juego son necesarios mecanismos para comprobar las palabras formadas y actualizar la puntuación. El método searchForWord() realiza estas funciones:

private function searchForWord(str:String):Number 
{ 
    if (words && str) 
    { 
        var i:uint = 0 
        for (i = 0; i < words.length; i++) 
        { 
            var thisWord:String = words[i]; 
            if (str == words[i]) 
            { 
                return i;     
            } 
        } 
        return -1; 
    } 
    else 
    { 
        trace("WARNING: cannot find words, or string supplied is null"); 
    } 
    return -1; 
}

Esta función recorre todas las palabras del diccionario. Si la palabra del usuario coincide con una palabra del diccionario, se devuelve su posición en el diccionario. El método submitWord() comprueba entonces la respuesta y actualiza la puntuación si la posición es válida.

Personalización

Al principio de la clase hay varias constantes. Se puede modificar el juego modificando estas variables. Por ejemplo, se puede cambiar la cantidad de tiempo de juego incrementando la variable TOTAL_TIME. O se puede incrementar ligeramente la variable PERCENT_VOWELS para aumentar la probabilidad de encontrar palabras.