diff --git a/src/game/lib/string_util.js b/src/game/lib/string_util.js index 70f80b2..5add855 100644 --- a/src/game/lib/string_util.js +++ b/src/game/lib/string_util.js @@ -25,4 +25,66 @@ class StringUtil { return n.length >= digitCount ? n : new Array(digitCount - n.length + 1).join('0') + n; } + + static toKoreanAlphabets(text) { + const cCho = [ 'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ' ]; + const cJung = [ 'ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅓ', 'ㅔ', 'ㅕ', 'ㅖ', 'ㅗ', 'ㅘ', 'ㅙ', 'ㅚ', 'ㅛ', 'ㅜ', 'ㅝ', 'ㅞ', 'ㅟ', 'ㅠ', 'ㅡ', 'ㅢ', 'ㅣ' ]; + const cJong = [ '', 'ㄱ', 'ㄲ', 'ㄳ', 'ㄴ', 'ㄵ', 'ㄶ', 'ㄷ', 'ㄹ', 'ㄺ', 'ㄻ', 'ㄼ', 'ㄽ', 'ㄾ', 'ㄿ', 'ㅀ', 'ㅁ', 'ㅂ', 'ㅄ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ' ]; + + let cho, jung, jong; + let str = text; + let cnt = str.length; + let chars = [], cCode; + + for (let i = 0; i < cnt; i++) { + cCode = str.charCodeAt(i); + // if (cCode == 32) { continue; } // 한글이 아닌 경우 + if (cCode < 0xAC00 || cCode > 0xD7A3) { + chars.push(str.charAt(i)); + continue; + } + cCode = str.charCodeAt(i) - 0xAC00; + jong = cCode % 28; // 종성 + jung = ((cCode - jong) / 28 ) % 21; // 중성 + cho = (((cCode - jong) / 28 ) - jung ) / 21; // 초성 + + chars.push(cCho[cho], cJung[jung]); + if (cJong[jong] !== '') { + chars.push(cJong[jong]); + } + } + return chars; + }; + + + static getUnicodeAlphabetCount(text) { + let chars = StringUtil.toKoreanAlphabets(text); + // console.log('char : ' + chars); + + let doubleJaum = [ + 'ㄲ', 'ㅉ', 'ㄸ', 'ㄲ', 'ㅆ', + 'ㄳ', 'ㄵ', 'ㄶ', 'ㄺ', 'ㄻ', 'ㄼ', 'ㄽ', 'ㄾ', 'ㄿ', 'ㅀ', 'ㅄ' + ]; + let doubleMoum = [ + 'ㅒ', 'ㅖ', + 'ㅘ', 'ㅙ', 'ㅚ', 'ㅝ', 'ㅞ', 'ㅟ', 'ㅢ' + ]; + + let alphabetCount = 0; + let alphabet; + for(let i = 0; i < chars.length; i++) { + alphabet = chars[i]; + if(doubleJaum.indexOf(alphabet) > -1 || doubleMoum.indexOf(alphabet) > -1) { + // console.log('double alphabet : ' + alphabet); + alphabetCount += 2; + } + else + alphabetCount++; + } + + // return chars; + return alphabetCount; + }; + + } \ No newline at end of file diff --git a/src/game/typing/test/game.js b/src/game/typing/test/game.js index ef01066..ef27244 100644 --- a/src/game/typing/test/game.js +++ b/src/game/typing/test/game.js @@ -4,6 +4,8 @@ class Test { create() { + self = this; + this.game.stage.backgroundColor = '#4d4d4d'; sessionStorageManager.isNewBestRecrd = false; @@ -17,14 +19,79 @@ class Test { let fullscreenButton = new FullscreenButton(this.game); + // record + var scoreboardAreaPositionY = 2; + game.add.text(340 - Test.OFFSET_RIGHT_ALIGN, scoreboardAreaPositionY, "현재 타수 :", textStyleBasic) + .setTextBounds(0, 0, 200, 80) + .setShadow(3, 3, 'rgba(0, 0, 0, 0.5)', 2); - // waiting room - this.game.add.graphics() - .beginFill(0xffffff, 0.1) - .drawRect(0, 100, game.world.width, 100); + this.textTypingRecordTotal = game.add.text(540, scoreboardAreaPositionY, "", textStyleBasic) + .setTextBounds(0, 0, 200, 80) + .setShadow(3, 3, 'rgba(0, 0, 0, 0.5)', 2); + + this.textPlayingWordNumber = game.add.text(900, scoreboardAreaPositionY, "0", textStyleBasic) + .setTextBounds(0, 0, 300, 80) + .setShadow(3, 3, 'rgba(0, 0, 0, 0.5)', 2); - // contents + // typing content + var typingAreaPositionY = 260; + var bar = game.add.graphics(); + bar.beginFill(0x000000, 0.2); + bar.drawRect(0, typingAreaPositionY, GAME_SCREEN_SIZE.x, 120); + + // if(playingStageData.level == "10") + // textStyleBasic.font = "bold 48px Arial"; + // else + // textStyleBasic.font = "bold 84px Arial"; + + this.textTypingContent = game.add.text(0, 2, "test", textStyleBasic) + .setTextBounds(0, typingAreaPositionY, GAME_SCREEN_SIZE.x, 120) + .setShadow(3, 3, 'rgba(0, 0, 0, 0.5)', 2) + .addColor(Test.COLOR_CONTENT_WRONG, 0); + + textStyleBasic.font = "32px Arial"; + + var textDoneColor = [ '#99994d', '#77774d', '#66664d' ]; + this.textTypingContentsDone = []; + this.textTypingRecordsDone = []; + for(var i = 0; i < Test.TYPING_CONTENT_DONE_COUNT; i++) { + this.textTypingContentsDone[i] = game.add.text(0, 2, "test", textStyleBasic) + .setTextBounds(0, typingAreaPositionY - 50 - i * 50, GAME_SCREEN_SIZE.x, 40) + .setShadow(3, 3, 'rgba(0, 0, 0, 0.5)', 2) + .addColor(textDoneColor[i], 0); + + var scorePositionX = 600; + // if(playingStageData.level == "10") + // scorePositionX = 740; + + this.textTypingRecordsDone[i] = game.add.text(0, 2, "", textStyleBasic) + .setTextBounds(scorePositionX, typingAreaPositionY - 50 - i * 50, 200, 40) + .setShadow(3, 3, 'rgba(0, 0, 0, 0.5)', 2) + .addColor(textDoneColor[i], 0); + + } + + var textPreviewColor = [ '#999999', '#888888', '#777777' ]; + this.textTypingContentPreview = []; + for(var i = 0; i < Test.TYPING_CONTENT_PREVIEW_COUNT; i++) { + this.textTypingContentPreview[i] = game.add.text(0, 2, "test", textStyleBasic) + .setTextBounds(0, typingAreaPositionY + 130 + i * 50, GAME_SCREEN_SIZE.x, 40) + .setShadow(3, 3, 'rgba(0, 0, 0, 0.5)', 2) + .addColor(textPreviewColor[i], 0); + } + + + // input text + this.inputTextContent = new InputTypeText(this.game.world.centerX, typingAreaPositionY + 360); + this.inputTextContent.anchor.set(0.5); + this.inputTextContent.canvasInput.value(''); + this.inputTextContent.canvasInput.focus(); + // inputTextContent.canvasInput._onkeydown = this.checkInputText; + // inputTextContent.canvasInput._onkeyup = function() { + this.inputTextContent.canvasInput._onkeyup = function() { + self.checkTypingContents(event); + } // bottom @@ -66,7 +133,7 @@ class Test { this.countDownText.alpha = 1; let countDownTween = game.add.tween(this.countDownText); - countDownTween.to( { alpha: 0 }, 1000, Phaser.Easing.Linear.None, true); + countDownTween.to( { alpha: 0 }, GAME_SCREEN_SIZE.x, Phaser.Easing.Linear.None, true); countDownTween.onComplete.add(this.tweenCountDown, this); this.countDownNumber--; @@ -74,6 +141,12 @@ class Test { */ startGame() { + this.initTypingData(); + + this.initStage(); + + this.showTypingTestContents(); + this.showPlayingWordNumber(); } gameOver() { @@ -86,4 +159,313 @@ class Test { location.href = '../../web/client/result.html'; } -} \ No newline at end of file + initTypingData() { + this.typingTestContents = this.getTypingTestContents(); + var randomContents = Phaser.ArrayUtils.shuffle(this.typingTestContents); + this.typingRandomContents = randomContents.slice(1, Test.WORD_COUNT_FOR_STAGE + 1); // start Num, end Num (not index) + console.log(this.typingRandomContents); + this.typingContentLength = this.typingTestContents.length; + this.typingIndex = 0; + + this.isTyping = false; + this.timeTypingStart = 0; + this.timeTypingEnd = 0; + + this.typingLetterCountTotal = 0; + + // this.typingRecordTotal = 0; + // bestRecord = 0; + } + + initStage() { + // this.textBestRecord.text = Math.floor(sessionStorageManager.bestRecord); + this.textTypingRecordTotal.text = 0; + } + + getTypingTestContents() { + var typingTestContents = this.loadTestContent(); + // console.log('playingStageData.language : ' + playingStageData.language); + // console.log('playingStageData.level : ' + playingStageData.level); + // console.log('typingTestContents : ' + typingTestContents); + + this.typingRecordForLines = []; + this.typingElapsedTime = []; + for(var i = 0; i < typingTestContents.length; i++) { + this.typingRecordForLines[i] = 0; + this.typingElapsedTime[i] = 0; + } + + return typingTestContents; + } + + loadTestContent() { + var testContent = []; + switch(sessionStorageManager.playingAppName) { + case "korean_word": + testContent = koreanWordList; + break; + case "korean_sentence": + testContent = koreanSentenceList; + break; + case "english_word": + testContent = englishWordList; + break; + case "english_sentence": + testContent = englishSentenceList; + break; + } + + return testContent; + + // if(playingStageData.language == LANGUAGE_KOREAN) + // return this.loadKoreanTestContent(); + // else + // return this.loadEnglishTestContent(); + } + + loadKoreanTestContent() { + var testContent = []; + switch(Number(playingStageData.level)) { + case 1: + testContent = koreanBasicWordList; + break; + case 2: + testContent = koreanLeftUpperWordList; + break; + case 3: + testContent = koreanSecondFingerWordList; + break; + case 4: + testContent = koreanRightUpperWordList; + break; + case 5: + testContent = koreanLeftLowerWordList; + break; + case 6: + testContent = koreanRightLowerWordList; + break; + case 7: + testContent = koreanLeftUpperDoubleWordList; + break; + case 8: + testContent = koreanRightUpperDoubleWordList; + break; + case 9: + testContent = koreanWordList; + break; + case 10: + testContent = koreanSentenceList; + break; + default: + testContent = koreanBasicWordList; + } + + return testContent; + } + + loadEnglishTestContent() { + + /* + var testContent = [ + "보리밭 사잇길로 걸어가면", + "뉘 부르는 소리 있어", + "입에 들어가는 밥술도 제가", + "떠 넣어야 한다", + "큰 방죽도 개미 구멍으로 무너진다.", + ]; + */ + + var testContent = []; + switch(Number(playingStageData.level)) { + case 1: + testContent = englishBasicWordList; + break; + case 2: + testContent = englishLeftUpperWordList; + break; + case 3: + testContent = englishSecondFingerWordList; + break; + case 4: + testContent = englishRightUpperWordList; + break; + case 5: + testContent = englishLeftLowerWordList; + break; + case 6: + testContent = englishRightLowerWordList; + break; + case 9: + testContent = englishWordList; + break; + case 10: + testContent = englishSentenceList; + break; + default: + testContent = englishBasicWordList; + } + + return testContent; + } + + showTypingTestContents() { + for(var i = 0; i < Test.TYPING_CONTENT_DONE_COUNT; i++) { + var doneIndex = this.typingIndex - i - 1; + if(doneIndex < 0) { + this.textTypingContentsDone[i].text = ""; + this.textTypingRecordsDone[i].text = ""; + } else { + this.textTypingContentsDone[i].text = this.typingRandomContents[doneIndex]; + this.textTypingRecordsDone[i].text = Math.floor(this.typingRecordForLines[doneIndex]); + } + } + + if(this.typingIndex == Test.WORD_COUNT_FOR_STAGE) { + this.textTypingContent.text = ""; + return; + } + + this.textTypingContent.text = this.typingRandomContents[this.typingIndex]; + + for(var i = 0; i < Test.TYPING_CONTENT_PREVIEW_COUNT; i++) { + var previewIndex = this.typingIndex + i + 1; + if(previewIndex < this.typingRandomContents.length) + this.textTypingContentPreview[i].text = this.typingRandomContents[previewIndex]; + else + this.textTypingContentPreview[i].text = ""; + } + } + + resetTypingContent() { + this.textTypingContent.clearColors(); + this.textTypingContent.addColor(Test.COLOR_CONTENT_WRONG, 0); + this.inputTextContent.canvasInput.value(''); + } + + checkTypingContents(evnet) { + if(event.keyCode == Phaser.Keyboard.ENTER) { + // console.log("### enter ###"); + var inputContent = this.inputTextContent.canvasInput.value(); + var typingContent = this.typingRandomContents[this.typingIndex]; + + if(inputContent == typingContent) { + this.calculateTypingRecord(typingContent); + this.playNextContent(); + + if(this.typingIndex == Test.WORD_COUNT_FOR_STAGE) + this.state.start('TypingTestResult'); + } + } + else { + // console.log(this.inputTextContent.canvasInput.value()); + if(this.isTyping == false) { + // console.log(event); + this.setTimeTypingStart(); + } + + this.showTypingContentHighlight(); + } + } + + showTypingContentHighlight() { + var typingContent = this.typingRandomContents[this.typingIndex]; + var inputContent = this.inputTextContent.canvasInput.value(); + + this.textTypingContent.clearColors(); + this.textTypingContent.addColor(Test.COLOR_CONTENT_RIGHT, 0); + + if(typingContent == null) + return; + + var typingContentLength = typingContent.length; + for(var i = 0; i < typingContentLength; i++) { + // console.log("typingContent.charAt(i) : " + typingContent.charAt(i)); + // console.log("inputContent.charAt(i) : " + inputContent.charAt(i)); + + if(typingContent.charAt(i) != inputContent.charAt(i)) { + this.textTypingContent.addColor(Test.COLOR_CONTENT_WRONG, i); + return; + } + } + } + + calculateTypingRecord(typingContent) { + // console.log('입력 단어 : ' + this.typingRandomContents[this.typingIndex]); + + this.isTyping = false; + this.timeTypingEnd = this.game.time.elapsedSince(0); + // console.log('this.timeTypingEnd : ' + this.timeTypingEnd); + + var elapsedTimeMS = this.timeTypingEnd - this.timeTypingStart; + // console.log('elapsedTimeMS : ' + elapsedTimeMS); + + var typingContentLength = StringUtil.getUnicodeAlphabetCount(typingContent); + // console.log('typingContentLength : ' + typingContentLength); + var typingContentPlusEnterCount = typingContentLength + Test.TYPING_COUNT_PLUS_ENTER; + + var typingRecord = (typingContentPlusEnterCount + Test.TYPING_COUNT_PLUS_ENTER) * 60000 / elapsedTimeMS; + + this.typingElapsedTime[this.typingIndex] = elapsedTimeMS; + this.typingLetterCountTotal += typingContentPlusEnterCount; + this.typingRecordForLines[this.typingIndex] = typingRecord; + // console.log(this.typingRecordForLines[this.typingIndex]); + + var typingElapsedTimeTotal = 0; + for(let i = 0; i <= this.typingIndex; i++) { + // console.log('i : ' + i + ' - time : ' + this.typingElapsedTime[i]); + typingElapsedTimeTotal += this.typingElapsedTime[i]; + } + let typingRecordTotal = this.typingLetterCountTotal * 60000 / typingElapsedTimeTotal; + console.log(this.typingLetterCountTotal); + console.log(typingElapsedTimeTotal); + console.log(typingRecordTotal); + this.textTypingRecordTotal.text = Math.floor(typingRecordTotal); + // console.log('-------------- total --------------'); + // console.log('typingLetterCountTotal : ' + this.typingLetterCountTotal); + // console.log('typingElapsedTimeTotal : ' + typingElapsedTimeTotal); + // console.log('typingRecordTotal : ' + typingRecordTotal); + // console.log('-----------------------------------'); + } + + playNextContent() { + this.typingIndex++; + this.showTypingTestContents(); + this.showPlayingWordNumber(); + this.resetTypingContent(); + } + + showPlayingWordNumber() { + this.textPlayingWordNumber.text = (this.typingIndex + 1) + " / " + Test.WORD_COUNT_FOR_STAGE; + } + + setTimeTypingStart() { + this.timeTypingStart = this.game.time.elapsedSince(0); + var timeGap = this.timeTypingStart - this.timeTypingEnd; + + if(timeGap < 50) + return; + + this.isTyping = true; + // console.log('last End : ' + this.timeTypingEnd); + // console.log('this.timeTypingStart : ' + this.timeTypingStart); + + // console.log('time gap : ' + (this.timeTypingStart - this.timeTypingEnd)); + } + +} + + +Test.TYPING_CONTENT_PREVIEW_COUNT = 3; +Test.TYPING_CONTENT_DONE_COUNT = 3; +Test.TYPING_COUNT_PLUS_ENTER = 1; + +Test.OFFSET_RIGHT_ALIGN = 10; + +Test.WORD_COUNT_FOR_STAGE = 10; +// if(isDebugMode()) +// WORD_COUNT_FOR_STAGE = 3; + +Test.COLOR_CONTENT_WRONG = "#aaaaaa"; +Test.COLOR_CONTENT_RIGHT = "#ffff4d"; + +