마우스 입력 예제: WordSearch

Flash Player 9 이상, Adobe AIR 1.0 이상

이 예제는 마우스 이벤트 처리를 통한 사용자 상호 작용에 대한 것입니다. 사용자는 바둑판 무늬에 배열된 임의의 문자로 가능한 한 많은 단어를 조합해야 하며, 문자를 가로 또는 세로로 이동하여 철자를 맞추고 같은 문자를 두 번 사용할 수 없습니다. 이 예제에서는 다음과 같은 ActionScript 3.0의 기능이 사용됩니다.

  • 구성 요소 배열을 동적으로 구성

  • 마우스 이벤트에 응답

  • 사용자 상호 작용에 기초하여 점수 유지 관리

이 샘플에 대한 응용 프로그램 파일을 가져오려면 www.adobe.com/go/learn_programmingAS3samples_flash_kr 을 참조하십시오. WordSearch 응용 프로그램 파일은 Samples/WordSearch 폴더에 있습니다. 이 응용 프로그램은 다음과 같은 파일로 구성됩니다.

파일

설명

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() 함수에서 한 루프 내에 다른 루프를 중첩시켜 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 이벤트에만 리스너를 추가해도 이것이 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)); 
}

String 클래스의 charAt() indexOf() 메서드는 현재 클릭한 버튼과 이전에 클릭한 버튼 둘 다에서 적절한 행과 열을 얻습니다. 이때 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 변수의 값도 약간 늘릴 수 있는데, 이렇게 하면 단어를 찾을 가능성이 커집니다.