🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

1138閲覧

タイピングゲームをjavascriptで作ったのですがどこが変ですか?

tanakashouzoux

総合スコア52

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2019/09/23 11:19

タイピングゲームを思い出しながら作り、下記のコードを書きました

予定では200文字タイピングした後、掛かった時間とGAME終了と画面に出るはずなのですが、私のコードでは200文字のタイピング終了後白い画面となり、更にスペースキーなどを長押しするとその間、最初から何秒経ったかが表示されます

どうしてこんなことになったのか全く見当がつきません

どなたか詳しい方がいらっしゃいましたらどこがどう間違ってるのか指摘して頂けないでしょうか?

html

1<html> 2 3<body onload="gameSet()"> 4 5<div id="waku"></div> 6 7 8</body> 9 10</html> 11 12

javascript

<script> document.onkeydown = typeGame; //文字を格納する配列 var moji = new Array("A","B","C","D","E","F","G","H","I", "J","K","L","M","N","O","P","Q","R", "S","T","U","V","W","X","Y","Z"); //キーコードを格納する配列 var kcode = new Array(65,66,67,68,69,70,71,72,73, 74,75,76,77,78,79,80,81,82, 83,84,85,86,87,88,89,90); //0~25までの乱数を格納する配列 var rnd = new Array(); var mondai = ""; //問題の文字列を格納 var cnt=0; //何問目か格納 var typStart,typEnd; //開始時と終了時の時刻を格納 //0~25までの乱数を200個作成して配列rndに格納する関数 //タイピングゲームの問題をセットする関数 function gameSet() { //問題文とカウント数をクリアする mondai=""; cnt=0; //乱数作成関数の呼び出し //問題文の作成(配列mojiの要素をランダムに200文字繋げる) //mondai= "" + moji[rnd[0]] + moji[rnd[1]] + … + moji[rnd[199]]となる for ( var i = 0 ; i < 200 ; i++) { rnd[i] = Math.ceil( Math.random() * 25 ); mondai = mondai + moji[ rnd[i] ]; } //問題枠に表示する document.getElementById("waku").innerHTML = mondai; } function typeGame(evt) { var vc; if(document.all){ vc=event.keyCode; }else{ vc=evt.which; } if (cnt==0) { typStart = new Date(); } if(cnt<20){ if(vc==kcode[rnd[cnt]]){ mondai=mondai.substring(1,mondai.Length); document.getElementById("waku").innerHTML=mondai; cnt++; } }else{  typEnd = new Date(); //終了時間-開始時間で掛かったミリ秒を取得する var keika = typEnd - typStart; //1000で割って「切捨て」、秒数を取得 var sec = Math.floor( keika/1000 ); //1000で割った「余り(%で取得できる)」でミリ秒を取得 var msec = keika % 1000; //問題終了を告げる文字列を作成 var fin="GAME終了 時間:"+sec+"秒"+msec; //問題枠にゲーム終了を表示 document.getElementById("waku").innerHTML = fin; } } </script>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shun-K

2019/09/23 12:24

試したコードは掲載のコードと異なるのではないでしょうか? 「200文字のタイピング終了後」と書いてますが、20文字で終了の判定になっているし、 とりあえず20文字打てば、結果画面(GAME終了 時間:XXX秒XXX)が表示されますよ。
m.ts10806

2019/09/24 00:59

「思い出しながら作り」という前提が意味不明です。 決められた仕様がきちんとないのにコードだけなんとなく作ってるんですか?
tanakashouzoux

2019/10/04 22:22

皆さんコメントありがとうございますm(__)m shun-Kさん 私の方は白い画面になっちゃうんですよね・・・ m.ts10806さん 仕様とは一体何なんでしょうか・・・ 私はウェブサイトに載ってたコードを見ない様に思い出しながら写経?してました
m.ts10806

2019/10/04 23:56 編集

コードは覚えるものではないですよ。 仕様や設計(どういうものを作るか、決め事)があってそれを実現するために組むものです。 既存のコードを、コードだけ覚えたところでプログラミングができるようにはなりません。
tanakashouzoux

2019/10/05 06:54

御指導ありがとうございます! 一応自分なりにコードで何をしているのか考え、それを自分で再現できるようにしているのですが・・・ 私にはプログラミングの道は難しいのかもしれませんね・・・
guest

回答1

0

ベストアンサー

コードがどういう風に進んでいくか、1行ずつ考えてみてください

JS

1if(cnt<20){ //200の間違えでは? 2 if(vc==kcode[rnd[cnt]]){ 3 mondai=mondai.substring(1,mondai.Length); 4 document.getElementById("waku").innerHTML=mondai 5 cnt++; // ...(1) 6 } 7}else{ 8 9  typEnd = new Date(); // ...(2) 10 11 //終了時間-開始時間で掛かったミリ秒を取得する 12 var keika = typEnd - typStart; 13 14 //1000で割って「切捨て」、秒数を取得 15 var sec = Math.floor( keika/1000 ); 16 17 //1000で割った「余り(%で取得できる)」でミリ秒を取得 18 var msec = keika % 1000; 19 20 //問題終了を告げる文字列を作成 21 var fin="GAME終了 時間:"+sec+"秒"+msec; 22 23 //問題枠にゲーム終了を表示 24 document.getElementById("waku").innerHTML = fin; 25}

今回であれば、200文字全て打ち終わった後、(1)の箇所でカウントされてcntが200になります。
その後のコードはif(cnt<20){のelse文になるので実行されません。
なので、空欄が出力されます。
次に何かしらのキーボードを入力した際、if(cnt<20){はfalseになるのでelse文が呼ばれ、経過時間が表示されます。
同様に、それ以降のキーボード入力は全てelse文が呼ばれ、(2)が何度も呼ばれることになり、経過時間が更新されてしまいます。

なので、今回であれば200文字打ち終えた後にもelse文が呼ばれたいわけなので、カウント(1)する箇所をif文より前に出すことになります。
キーボードの長押しでの更新を止めるのは、cntが200の時のみelse文を呼ぶか、リザルトを出力したことを何か変数でメモしておき、次回以降は呼ばないようにするか、ですかね。

質問内容にはないですが、補足です。
ブラウザにはデバッガ機能がありますので、まずはそちらで順番にどう実行されているのか確認してみてください。
デバッガ機能は使用しているブラウザによって違うので、「○○ JavaScript デバッガ」などで調べてください。

投稿2019/09/23 12:01

yuuyu

総合スコア1139

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tanakashouzoux

2019/10/04 22:24

わざわざ丁寧なご回答をありがとうございます!m(__)m yuuyuさんご指摘の様に、私には1行ずつ考える力が欠けていたんだと思います・・・ デバッガについても教えて頂きありがとうございますm(__)m 全く知らなかったので本当にありがたいです!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問