Пример действий мыши: WordSearch

Flash Player 9 и более поздних версий, Adobe AIR 1.0 и более поздних версий

В этом примере показано взаимодействие с пользователем с помощью событий мыши. У пользователя есть расчерченное поле со случайным набором букв. Задача — найти как можно больше слов, записанных по горизонтали или по вертикали, при этом нельзя дважды использовать одну букву. В этом примере демонстрируются следующие функции языка ActionScript 3.0:

  • динамическое построение сетки компонентов;

  • реагирование на события мыши;

  • ведение счета на основе взаимодействия с пользователем.

Получить файлы приложения для этого примера можно на странице www.adobe.com/go/learn_programmingAS3samples_flash_ru. Файлы приложения WordSearch находятся в папке Samples/WordSearch. Приложение состоит из следующих файлов.

File

Описание

WordSearch.as

Класс, обеспечивающий основную функциональность приложения.

WordSearch.fla

или

WordSearch.mxml

Основной файл приложения для Flex (MXML) или Flash (FLA).

dictionary.txt

Файл, используемый для проверки орфографии и «стоимости» каждого слова.

Загрузка словаря

Для создания игры на нахождение слов необходим словарь. В примере используется текстовый файл dictionary.txt, содержащий список слов, разделенных переводами каретки. После создания массива words функция loadDictionary() запрашивает этот файл, который после успешной загрузки становится длинной строкой. Эту строку можно разобрать на массив слов с помощью метода split(), отделяя слова друг от друга по переводу каретки (код символа 10) или новой строке (код символа 13). Разбор осуществляется в функции dictionaryLoaded():

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

Создание пользовательского интерфейса

После сохранения слов можно создать пользовательский интерфейс. Создайте два экземпляра Button: один для подтверждения слова, а другой — для очистки слова, над которым пользователь в данный момент работает. В каждом случае нужно отвечать на команды пользователя путем прослушивания события MouseEvent.CLICK, которое транслирует кнопка, и вызова функции. В функции setupUI() этот код создает прослушиватели на двух кнопках:

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

Генерация игрового поля

Игровое поле — это сетка со случайными буквами. Функция generateBoard() создает двухмерную сетку, размещая один цикл внутри другого. Первый цикл приращивает ряды, а второй — общее количество столбцов в ряду. Каждая ячейка, формируемая этими рядами и столбцами, содержит кнопку с буквой.

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); 
        } 
    } 
}

Хотя прослушиватель для событий MouseEvent.CLICK добавляется только на одну строку, так как он находится в цикле for, он все равно назначается каждому экземпляру Button. Кроме того, каждой кнопке назначается имя на основе ее положения в столбце и в ряду, что облегчает работу с каждой из кнопок в коде.

Составление слов в ответ на действия пользователя

Слова можно составлять, выбирая буквы, стоящие рядом по вертикали и по горизонтали, но одну и ту же букву нельзя использовать дважды. Каждый щелчок вызывает событие мыши: в этот момент программа проверяет, чтобы слово, которое составил пользователь, должным образом продолжало буквы, на которых пользователь щелкнул ранее. Если это не так, предыдущее слово удаляется и начинается новое. Эта проверка осуществляется методом 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)); 
}

Методы charAt() и indexOf() класса String возвращают значения рядов и столбцов текущей и предыдущей букв. Метод isLegalContinuation() возвращает значение true, если текущая буква находится в том же ряду или столбце, что и предыдущая, при этом положение в столбце или ряду увеличивается на единицу. Если вы хотите, чтобы пользователь мог составлять слова и по диагонали, удалите проверку последовательности рядов и столбцов. Итоговая строка будет выглядеть так:

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

Проверка подтверждения слов

Остался последний шаг в написании кода к игре: необходим механизм для проверки подтверждения слов и ведения счета. Метод searchForWord() помогает решить обе эти задачи:

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; 
}

Функция проходит по всем словам в словаре, при этом цикл непрерывно повторяется. Если слово, составленное пользователем, совпадает со словом из словаря, возвращается его положение в словаре. Метод submitWord() проверяет ответ и обновляет счет, если положение действительно.

Персонализация

В начале класса есть несколько констант. Можно модифицировать игру, изменив эти переменные. Например, можно изменить количество времени, которое дается пользователю, исправив переменную TOTAL_TIME. Также можно немного увеличить значение переменной PERCENT_VOWELS, чтобы пользователю было проще находить слова.