🎯
JavaScriptへの最初のダイブ①(数字当てゲーム)
MDN( https://developer.mozilla.org/ja/docs/Web/JavaScript )
を参考に勉強するように注意が入ったので、こらを教本にしていきます。
その為、抜粋しながら進めたいと思います。
今回はこちらのページです
数字当てゲーム
今回、こちらのゲームを作ります。
数字当てゲーム
ゲームの概要
上司から、次のように作るゲームの概要を聞いたところを想像してみてください。
数字を予想する単純なゲームを作って欲しい。
ランダムな 1 から 100 の数字を決めて、プレイヤーに10回以内に当ててもらうゲームだ。
プレイヤーには予想する都度、正解か間違いかを表示する。もしプレイヤーが間違っていれば、プレイヤーが予想した数字に応じて、大きすぎるか小さすぎるかを表示する。また、プレイヤーの前回の予想がどうだったかも表示する。
ゲームはプレイヤーの予想が正しかった場合、もしくは回数の上限に達した場合に終了する。
ゲームが終了したら、プレイヤーはもう一度プレイ開始できるようにする。
ゲームの概要を聞き、最初に行うべきこと
最初に行うべきことは、簡潔な実行可能な単位に分割することです。
- 1 から 100 までの数字をランダムに一つ生成する。
- プレイヤーの予想した回数を記録する。最初は 1 回から。
- プレイヤーが数字が何かを予想する方法を用意する。
- 予想が入力されたら、プレイヤーが以前の予想を見られるように、どこかに記録する。
- 入力された数字が正しいかどうかを調べる。
- 入力された数字が正しい場合...
①正解したお祝いのメッセージを表示
②プレイヤーが次の予想を出来ないようにする
③プレイヤーが次のゲームを始められるようなコントロールを表示 - プレイヤーの予想が間違いで、予想回数の上限にはまだ達していない場合...
①プレイヤーが間違っていることを表示
②次の予想を入力できるようにする
③予想回数に1を加算する - プレイヤーの予想が間違いで、予想回数の上限に達した場合...
①プレイヤーにゲームオーバーであることを伝える。
②プレイヤーが次の予想を出来ないようにする。
③プレイヤーが次のゲームを始められるようなコントロールを表示する。 - ゲームがもう一度始まったら、画面とロジックが完全にリセットされるようにして、1.に戻る。
まず初めに(HTML・CSS)
自分のファイルにestelleさんが作成したこちらのhtml&CSSをダウンロードします。
これを見る限り今回は『内部のJavaScript』の使用ですね。
JavaScriptを書いてみよう
<script> 要素の中に以下の内容を書いてみてください。
- データを保持する変数を追加
//1から100までのランダムな数字が代入
let randomNumber = Math.floor(Math.random() * 100) + 1;
//段落に値を追加するために使用
const guesses = document.querySelector('.guesses');
const lastResult = document.querySelector('.lastResult');
const lowOrHi = document.querySelector('.lowOrHi');
//テキスト入力フォームおよび送信ボタンへの参照が保持され、後で予想の送信をコントロールする際に使用される。
const guessSubmit = document.querySelector('.guessSubmit');
const guessField = document.querySelector('.guessField');
//プレイヤーが予想した回数を記録するため1
let guessCount = 1;
//リセットボタンへの参照を保持
let resetButton;
- 予想の確認
function checkGuess() {
//userGuessという変数を宣言して、現在のテキストフィールドに入力された値をセット。組み込みの Number() 関数を呼び出して、テキストフィールドに入力された値が数値であることも確認。
const userGuess = Number(guessField.value);
//条件分岐を伴うコードブロック。guessCount変数が1(プレイヤーの初回の予想)であるかどうかを判定。
if (guessCount === 1) {
guesses.textContent = '前回の予想: ';
}
//予想が表示されるときにはスペースで区切られて表示するように記載。
guesses.textContent += userGuess + ' ';
//ランダムな数字を格納したrandomNumber変数の値と等しいかどうかを調査。もし等しければ、プレイヤーは正解し勝ち(祝福のメッセージを緑色で表示)。さらに、数字の大小を表示する段落をクリアして、後で説明するsetGameOver()関数を実行。
if (userGuess === randomNumber) {
lastResult.textContent = 'おめでとう!正解です!';
lastResult.style.backgroundColor = 'green';
lowOrHi.textContent = '';
setGameOver();
//else if(){ } という部分で、ひとつ前の条件に続けて条件を記載。この条件はユーザの最後のターンかどうかを調査。最後の回ならば、プログラムはゲームオーバーとする以外は、ひとつ前の部分と同じことを実行。
} else if (guessCount === 10) {
lastResult.textContent = '!!!ゲームオーバー!!!';
lowOrHi.textContent = '';
setGameOver();
//前の二つの条件がどちらも当てはまらなかった場合のみ実行。(プレイヤーは間違えてはいるものの、予想回数が残っている。) この場合、プレイヤーに予想が間違っていることを伝え、入力された数字が大きいか小さいかを伝えるため、さらなる条件の確認を行う。
} else {
lastResult.textContent = '間違いです!';
lastResult.style.backgroundColor = 'red';
if(userGuess < randomNumber) {
lowOrHi.textContent = '今の予想は小さすぎです!' ;
} else if(userGuess > randomNumber) {
lowOrHi.textContent = '今の予想は大きすぎです!';
}
}
//次の予想の入力を受け取るための準備。guessCount変数に1を加算し、プレイヤーの予想回数を数えます。(++はインクリメント演算子で、1だけインクリメント(増加)。) そして、入力フォームのテキストフィールドを空にしてから焦点を当て、プレイヤーの次の入力に備える。
guessCount++;
guessField.value = '';
guessField.focus();
}
- "予想を入力"のボタンが押されたときに、イベントを起こす
//guessSubmitボタンに対して、イベントが発生したことを聞き取る構成(イベントリスナー)を追加。これは発生したことを知りたいイベントの種類 (click)と、イベントが発生した場合に実行するコード (checkGuess()) の2つの入力値 (引数) を取る関数です。
guessSubmit.addEventListener('click', checkGuess);
- ゲームの機能を完成させる(ゲームオーバーになった時)
function setGameOver() {
//入力フォームのテキストフィールドとボタンのdisabledプロパティをtrueに設定することで、入力できないようにしている。
guessField.disabled = true;
guessSubmit.disabled = true;
//新しいbutton要素を生成し、そのラベルに"新しいゲームを始める"という文言を設定し、HTMLページに追加。
resetButton = document.createElement('button');
resetButton.textContent = '新しいゲームを始める';
document.body.appendChild(resetButton);
//上で生成したボタンがクリックされたときに resetGame() という関数が実行されるようにイベントリスナーを設定
resetButton.addEventListener('click', resetGame);
}
- ゲームの機能を完成させる(次のゲームができるようにゲームを初期化)
function resetGame() {
//guessCount に 1 を代入して元に戻す
guessCount = 1;
//情報段落のすべてを消去。
const resetParas = const resetParas = document.querySelectorAll('.resultParas p');
for (let i = 0 ; i < resetParas.length ; i++) {
resetParas[i].textContent = '';
}
//リセットボタンをページから削除。
resetButton.parentNode.removeChild(resetButton);
//入力フォームの要素を使用可能にして、新しい予想が入力できるようにテキストフィールドを空にしてフォーカスを設定します。
guessField.disabled = false;
guessSubmit.disabled = false;
guessField.value = '';
guessField.focus();
//最終結果を表示している lastResult 段落の背景色を消去。
lastResult.style.backgroundColor = 'white';
//同じ数字以外の数字でゲームができるように、新しいランダムな数字を再度生成
randomNumber = Math.floor(Math.random() * 100) + 1;
}
完成のソースコード(日本語)
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<title>数字当てゲーム</title>
<style>
html {
font-family: sans-serif;
}
body {
width: 50%;
max-width: 800px;
min-width: 480px;
margin: 0 auto;
}
.form input[type="number"] {
width: 200px;
}
.lastResult {
color: white;
padding: 3px;
}
</style>
</head>
<body>
<h1>数字当てゲーム</h1>
<p>1~100の中からランダムな数字を選びました。10ターン以内に当てられるかどうか試してみてください。あなたの予想が大きすぎたり小さすぎた場合は、お知らせします。</p>
<div class="form">
<label for="guessField">予想を入力してください: </label>
<input type="number" min="1" max="100" required id="guessField" class="guessField">
<input type="submit" value="予想を入力" class="guessSubmit">
</div>
<div class="resultParas">
<p class="guesses"></p>
<p class="lastResult"></p>
<p class="lowOrHi"></p>
</div>
<script>
let randomNumber = Math.floor(Math.random() * 100) + 1;
const guesses = document.querySelector('.guesses');
const lastResult = document.querySelector('.lastResult');
const lowOrHi = document.querySelector('.lowOrHi');
const guessSubmit = document.querySelector('.guessSubmit');
const guessField = document.querySelector('.guessField');
let guessCount = 1;
let resetButton;
function checkGuess() {
const userGuess = Number(guessField.value);
if (guessCount === 1) {
guesses.textContent = '前回の予想: ';
}
guesses.textContent += userGuess + ' ';
if (userGuess === randomNumber) {
lastResult.textContent = 'おめでとう!正解です!';
lastResult.style.backgroundColor = 'green';
lowOrHi.textContent = '';
setGameOver();
} else if (guessCount === 10) {
lastResult.textContent = '!!!ゲームオーバー!!!';
lowOrHi.textContent = '';
setGameOver();
} else {
lastResult.textContent = '間違いです!';
lastResult.style.backgroundColor = 'red';
if(userGuess < randomNumber) {
lowOrHi.textContent = '今の予想は小さすぎです!' ;
} else if(userGuess > randomNumber) {
lowOrHi.textContent = '今の予想は大きすぎです!';
}
}
guessCount++;
guessField.value = '';
guessField.focus();
}
guessSubmit.addEventListener('click', checkGuess);
function setGameOver() {
guessField.disabled = true;
guessSubmit.disabled = true;
resetButton = document.createElement('button');
resetButton.textContent = '新しいゲームを始める';
document.body.appendChild(resetButton);
resetButton.addEventListener('click', resetGame);
}
function resetGame() {
guessCount = 1;
const resetParas = document.querySelectorAll('.resultParas p');
for (let i = 0 ; i < resetParas.length ; i++) {
resetParas[i].textContent = '';
}
resetButton.parentNode.removeChild(resetButton);
guessField.disabled = false;
guessSubmit.disabled = false;
guessField.value = '';
guessField.focus();
lastResult.style.backgroundColor = 'white';
randomNumber = Math.floor(Math.random() * 100) + 1;
}
</script>
</body>
</html>
Discussion