マウス入力の例:WordSearch

Flash Player 9 以降、Adobe AIR 1.0 以降

この例では、マウスイベントの処理によるユーザーとの対話を説明します。 ユーザーはマス目にランダムに配置された文字を縦横につないで、できる限り多くの単語を作ります。ただし、同じ文字を 2 回使用することはできません。この例は、ActionScript 3.0 の次のような機能を使用します。

  • コンポーネントのグリッドの動的な作成

  • マウスイベントへの応答

  • ユーザー操作に基づくスコアの管理

このサンプルのアプリケーションのファイルを入手するには、 www.adobe.com/go/learn_programmingAS3samples_flash_jp を参照してください。 WordSearch アプリケーションのファイルは、Samples/WordSearch フォルダーにあります。 このアプリケーションは次のファイルで構成されています。

ファイル

説明

WordSearch.as

このクラスは、アプリケーションの主な機能を提供します。

WordSearch.fla

または

WordSearch.mxml

Flex(MXML)または Flash(FLA)のメインアプリケーションファイル。

dictionary.txt

作成された単語のスペルが正しく、スコアを加算できるかどうかを判断するファイル。

辞書のロード

単語検索を利用するゲームを作成するには、辞書が必要になります。 この例では、復帰文字で区切られた単語のリストを格納する dictionary.txt というテキストファイルを使用しています。 words という配列を作成した後、 loadDictionary() 関数がこのファイルを要求します。ロードに成功すると、このファイルは長い 1 つのストリングになります。 split() メソッドを使用し、復帰文字(文字コード 10)または改行文字(文字コード 13)の各インスタンスで分割することにより、このストリングを単語の配列に変換して解析することができます。この解析は、 dictionaryLoaded() 関数で発生します。

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

ユーザーインターフェイスの作成

単語を配列に格納したら、ユーザーインターフェイスを設定します。 2 つの Button インスタンスを作成します。1 つは単語の送信用、もう 1 つは、ユーザーが現在作成している単語のクリア用です。 どちらの場合も、 MouseEvent.CLICK イベントを監視して、関数を呼び出し、ユーザー入力に応答する必要があります。このイベントは、ボタンが押されるとブロードキャストされます。 setupUI() 関数内で、このコードは 2 つのボタンに対するリスナーを作成します。

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

ゲームボードの作成

ゲームボードはランダムな文字のマス目です。 generateBoard() 関数内で、1 つのループを別のループ内にネストすることによって 2 次元のマス目を作成できます。最初のループが行を増やし、2 番目のループが行ごとの列の総数を増やします。 これらの行と列で作成された各セルには、ボード上の文字を表すボタンを配置します。

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 イベントに対するリスナーを追加するコードを 1 行記述するだけで、これは for ループ内の処理であるため、リスナーが各 Button インスタンスに割り当てられます。さらに、その行と列の位置を使用した名前を各ボタンに割り当てます。これにより、後からコード内で各ボタンの行と列を容易に参照できるようになります。

ユーザー入力からの単語構築

単語は横または縦に隣り合う文字を選択することで作成できますが、同じ文字を 2 度使用することはできません。 文字をクリックすると、マウスイベントが生成されます。このときに、ユーザーが作成している単語をチェックし、前にクリックした文字の続きとして適切かどうかを確認する必要があります。 適切でない場合は、前に作成していた単語を削除して新しい単語を開始します。 このチェックは、 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)); 
}

String クラスの charAt() メソッドと indexOf() メソッドは、現在クリックされているボタンと前にクリックされたボタンの両方から適切な行と列を取得します。行または列の値が変更されていない場合、あるいは、変更された行または列の値が前のクリックの値よりも 1 だけ大きい場合、 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 変数の値を少しだけ大きくすると、単語が見つかる可能性が高くなります。