タイピングゲームでのmissの数の表示がおかしくなる
javascriptでタイピングのゲームを作成しています。
画面に表示された内容の文字を打つと、正解したタイプ数と間違えたタイプ数が表示されるだけのタイマー付きのシンプルなものです。
Enterキーを押すとゲームが始まり、終了時にはスコアがalertで表示されます。
終了時の状態でEnterを押すとリプレイできるようにしています。
ゲームの開始、進行には問題はないのですが、リプレイをする際に入力するEnterキーがmissとしてカウントされてしまいます。またリプレイ後は、リプレイの回数だけミスカウントの増加がおかしくなります(2,4,6と増えたり、3,6,9と増えたり)
addEventListenerが二重三重と起動してしまっているのではないか、とは思うのですが、どうにも解決ができませんでした。
該当のソースコード
javascript
1{ 2 3 4 5const getWord = document.getElementById(`word`); 6 7const getScore = document.getElementById(`score`); 8 9const getMiss = document.getElementById(`miss`); 10 11const randomWord = [ 12 `banana`, 13 `train`, 14 `apple`, 15 `rabbit`, 16 `elephant` 17] 18const getTimer = document.getElementById("timer"); 19 20let isPlaying = false;//ゲーム進行中かどうか 21let loc = 0;//添え字の役割 22let scoreCount = 0; 23let missCount =0; 24 25 26window.addEventListener(`keydown`,(e)=>{ 27 if(e.key === "Enter"){ 28 if(isPlaying ===true){ 29 return; 30 }//ゲームが始まっていたら以下の処理を読み込まない、つまり、一回スタートした後はisplayingがtrueになるので(ゲーム進行中)二重起動しない 31 32 isPlaying = true; 33 34 35 loc = 0; 36 scoreCount = 0; 37 missCount = 0; 38 39 getWord.textContent = wordMaker(); // 入力しなければならない値(この値は、一つの単語の入力を終えて次のwordMakerを起動するまで変化しません) 40 let target = getWord.textContent; // 表記を変えるための値(表記のための値なので変化します。) 41 42 let startTime = Date.now(); 43 44 Timer(); 45 46 //入力したキーをコンソールで確認 47 window.addEventListener(`keydown`, (c) =>{ 48 49 if(isPlaying !== true){ 50 return; 51 }//ゲーム進行中でなければ処理をしない 52 53 console.log(missCount) ; 54 55 //loc番目の文字が、取得したkeyと一緒か確認して条件分岐 56 if(target[loc] === c.key){ 57 scoreCount++; 58 loc++;//入力位置を示す 59 updateTarget(); 60 61 getScore.textContent = scoreCount; 62 console.log(`score =`,scoreCount); 63 }else{ 64 missCount++; 65 getMiss.textContent = missCount; 66 console.log(`miss =`,missCount); 67 } 68 if(loc === target.length){ 69 getWord.textContent = wordMaker(); 70 target = getWord.textContent; 71 72 loc = 0; 73 } 74 console.log(`target.length = `,getWord.textContent.length); 75 }) 76 77 function Timer(){ 78 79 let timeLimit = 3 * 1000; 80 let passedTime = Date.now() - startTime; 81 let timeLeft = timeLimit - passedTime; 82 getTimer.textContent = (timeLeft /1000).toFixed(2); 83 // console.log(startTime,Date.now()); 84 const timeoutId = setTimeout(() => { 85 Timer(); 86 }, 10);//10mm秒ごとに呼び出す 87 88 if(timeLeft < 0){ 89 isPlaying = false; 90 clearTimeout(timeoutId); 91 getTimer.textContent = `00:00`; 92 //なんで00:00とかじゃなくて、00:01とかなっちゃうんだ? 93 setTimeout(() => { 94 showResult(); 95 getWord.textContent = `Press "Enter" to replay`; 96 97 }, 100); 98 //alertはブラウザを完全ストップさせるのでタイマー表記に多少の誤差がでてしまう、それを防ぐためにalertを少し遅らせて表示させる 99 } 100 } 101 102 function updateTarget(){ 103 let underscore = `_`; 104 for(let i = 0; i < loc; i++){ 105 underscore += `_`; 106 } 107 getWord.textContent = underscore + target.substring(loc); 108 //ここ変数じゃだめっぽい(targetにgetWord以下代入してるので行けると思ったのに、、、なんで?? 109 console.log(`loc = `,loc); 110 }// f updateTarget end 111 112 113 function wordMaker(){ 114 return randomWord[Math.floor(Math.random() * randomWord.length)]; 115 } // f wordMaker end 116 117 118 function showResult(){ 119 let accuracy = scoreCount + missCount === 0 ? 0 : ((missCount / scoreCount) * 100); 120 //条件演算子っていうのらしい、要google 121 122 alert(`${scoreCount} letters typed correctly, ${missCount} lettrs typed wrongly, acurracy is ${accuracy}`); 123 124 } 125 }// if e.key === enter end 126 127 })//addeve enter end 128 129 130 131}//use strict end
html
1<!DOCTYPE html> 2<html lang = "ja"> 3 <head> 4 <title>typing game</title> 5 <meta charset = "utf-8"> 6 <link rel ="stylesheet" href = "main.css"> 7 8 </head> 9 <body> 10 <p id = "word">Press "Enter" to start</p> 11 <p>score:<span id = "score">0</span> miss:<span id = "miss">0</span></p> 12 <p id = "timer">timer:00:00</p> 13 14 <script src = "typing.js"> 15 </script> 16 </body> 17</html>
試したこと
preventDafaultやstopPropagation を調べ使ってみたましたが、解決しませんでした。
いまいち使い方を把握できていないことも原因かもしれません。
回答2件
あなたの回答
tips
プレビュー