前回までで、大まかな暗記カードの処理は作成できました。
今回はゲーム性を追加していきましょう。
ウェブアプリ入門、前回までの確認
まずは今までに作ったプログラムの確認です。
これまでの2回の授業で、暗記ゲームのプログラムは
次のようになっています。
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<body> <div> <span id="mondai"></span> <br> <input type="text" id='input_answer' value=""><br> <input type="button" id="answer_button" value="回答!"> <input type="button" id="next_question" value="次の問題!"> </div> <img src="neko-hutuu.png"> <img src="hart0.png"> <img src="hart0.png"> <img src="hart0.png"> </body> |
main.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
var questionNumber = 0; var data = [ ['Dog','犬'] ,['Cat','猫'] ,['Apple','りんご'] ,['Egg','卵'] ]; //画面読み込み時の処理 $(window).on('load',function(){ $('#next_question').trigger('click'); }); //次の問題ボタンの処理 $(document).on('click', '#next_question', function(){ $('#mondai').text(data[questionNumber][0]); questionNumber++; }); //回答ボタンの処理 $(document).on('click', '#answer_button', function(){ //入力された値を持ってくる var inputValue = $('#input_answer').val(); //配列の内容を変数に入れる var arrayAnswer = data[questionNumber-1][1]; //入力された内容と配列の回答を比較 if(inputValue == arrayAnswer){ alert("正解"); }else{ alert("不正解 答え:"+data[questionNumber-1][1]); } }); |
style.css
1 2 3 4 5 6 7 8 9 |
div{ background-color:#9ef442; margin:20px; padding:10px; } img{ max-width:20%; } |
もし足りない部分があれば前回の内容をもう1度見直しましょう。
不明点があれば、随時質問してください。
ウェブアプリのライフの実装
今回のキャラクターの横にハートが3つあります。
これをキャラクターのライフとします。
今回は3つハートを表示しているので、3回間違えたらゲームオーバにします。
つまりライフの値は3,2,1,0と減らして行くことになります。
なので、ライフの値は変数にします。
変数名は 『life』とします。
1 2 3 4 5 6 7 |
var questionNumber = 0; var life = 3 //ライフの変数を宣言 var data = [ ['Dog','犬'] ,['Cat','猫'] //以下省略 |
ライフが減る条件は不正解の場合ですね。
前回の授業で不正解のアラートを出すようにしていました。
この部分にライフを減らす処理を入れましょう。
そして、ライフが0の時間違えた場合は、ゲームオーバーのアラートを出すようにします。
1 2 3 4 5 6 7 8 9 10 11 12 |
//入力された内容と配列の回答を比較 if(inputValue == arrayAnswer){ alert("正解"); }else{ alert("不正解"); life--; } //lifeが0でゲームオーバーと表示 if(life <= 0){ alert("ゲームオーバー!"); } |
ここまでできたら動かしてみましょう。
3回間違えた段階でアラートが表示されることが確認できました。
ゲームオーバーが表示されるようになりましたが、
せっかくハートの画像が表示されているので、変数のlifeの値に
合わせて画像を変えてみましょう。
下の画像をダウンロードしてください。
ライフが減った事を表現する
変数lifeが減ると現在のライフの画像
を左の画像に変更していきます。
左の画像は、現在画像を格納しているフォルダと同じ場所に
保存しておいてください。
画像の変更方法はまだ教えていませんでしたが。
jQueryを使って下のように書くことができます。
1 |
$('セレクタ').attr('src','画像名') |
想像通りですが、imgタグのsrcに書かれている内容を
jQueryで書き換えています。
imgタグを変更するので、セレクタにはimgタグのimgをかけばいいはずですが。。。
HTMLをみてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<body> <div> <span id="mondai"></span> <br> <input type="text" id='input_answer' value=""><br> <input type="button" id="answer_button" value="回答!"> <input type="button" id="next_question" value="次の問題!"> </div> <img src="neko-hutuu.png"> <img src="hart0.png"> <img src="hart0.png"> <img src="hart0.png"> </body> |
imgタグがたくさんあります。
今回はキャラクタとライフでimgタグを利用しています。
idとclassで目印をつける
判断ができないので、classまたは、idをつけましょう。
ライフは同じ画像を利用しているのでclass名をつけましょう。class名はhartとします。
キャラクタの画像は単一なのでidをつけましょう。id名はcharacterとしましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<body> <div> <span id="mondai"></span> <br> <input type="text" id='input_answer' value=""><br> <input type="button" id="answer_button" value="回答!"> <input type="button" id="next_question" value="次の問題!"> </div> <img src="neko-hutuu.png"id="character"> <img src="hart0.png" class="hart"> <img src="hart0.png" class="hart"> <img src="hart0.png" class="hart"> </body> |
それではハートの画像を書き換えていきます。
思い出してください。
classをjqueryで指定する場合は『eq(数字)』とすることで同じクラスの中から
1つを選択することができました。
1つめのハートはeq(0)、 2つめはeq(1)、3つめはeq(2)ですね。
eqの中の数字は変数lifeと一致することがわかります。
ライフが3→2:eq(2)を変更
ライフが2→1:eq(1)を変更
ライフが1→0:eq(0)を変更してゲームオーバー
つまり不正解の場合はlifeの数字をeqに入れて画像を変更してやれば良いのです。
実際には次のようになります。
間違えるごとにライフが減っていく
1 2 3 4 5 6 7 8 9 |
//入力された内容と配列の回答を比較 if(inputValue == arrayAnswer){ alert("正解"); }else{ alert("不正解"); life--; //画像の変更 $('.hart').eq(life).attr('src','hart_empty.png'); } |
間違えるごとにハートが減っていきますね。
せっかくなので、ハートが減ると同時にキャラクターもダメージを受けた
画像に変更しましょう。
1 2 3 4 5 6 7 8 9 10 11 |
//入力された内容と配列の回答を比較 if(inputValue == arrayAnswer){ alert("正解"); }else{ alert("不正解"); life--; //ハートを減らす $('.hart').eq(life).attr('src','hart_empty.png'); //キャラクターがダメージを受けた画像にする $('#character').attr('src','neko-dame-ji.png'); } |
正解した場合には喜ぶ画像にしましょう。
ウェブアプリで正解を表現する
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//入力された内容と配列の回答を比較 if(inputValue == arrayAnswer){ alert("正解"); //キャラクターが喜ぶ $('#character').attr('src','neko-yorokobi.png'); }else{ alert("不正解"); life--; //ハートを減らす $('.hart').eq(life).attr('src','hart_empty.png'); //キャラクターがダメージを受けた画像にする $('#character').attr('src','neko-dame-ji.png'); } |
実際に遊んでみましょう。いい感じになってきましたね。
もう少し変化をつけてみましょう。
次へのボタンが押されたらキャラクターを普通の画像に戻します。
1 2 3 4 5 6 7 |
//次の問題ボタンの処理 $(document).on('click', '#next_question', function(){ $('#mondai').text(data[questionNumber][0]); questionNumber++; //キャラクターを普通の状態に戻す $('#character').attr('src','neko-hutuu.png'); }); |
ウェブアプリでゲームオーバーを表現する
ゲームオーバーの場合は負け画像に変更します。
1 2 3 4 5 |
//lifeが0でゲームオーバーと表示 if(life <= 0){ alert("ゲームオーバー!"); $('#character').attr('src','neko-sibou.png'); } |
アラートでゲームオーバが表示されるようになりました。
ただ、これは表示しただけですね。
画面上の『回答ボタン』や『次の問題』ボタンは動作し続けます。
これではゲームオーバーの意味がないので、ゲームオーバの際にはボタンを消して
しまいましょう。
ゲームオーバになった時に実行されるif文にボタンを隠す処理を入れます。
1 2 3 4 5 6 7 8 |
//lifeが0でゲームオーバーと表示 if(life <= 0){ alert("ゲームオーバー!"); $('#character').attr('src','neko-sibou.png'); $('#answer_button').hide(); $('#next_question').hide(); } |
上のようにhide()を利用して隠しましょう。
ウェブアプリで正解、不正解の画像を表示
正解、不正解の結果をキャラクターに喋ってもらいます。
まず、結果表示用の枠を作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<body> <div> <span id="mondai"></span> <br> <input type="text" id='input_answer' value=""><br> <input type="button" id="answer_button" value="回答!"> <input type="button" id="next_question" value="次の問題!"> </div> <img src="neko-hutuu.png" id="character"> <img src="hart0.png" class="hart"> <img src="hart0.png" class="hart"> <img src="hart0.png" class="hart"><br> <span id="result">テスト</span> </body> |
spanを追加しました。
ここは結果によって文字を変えていくのでidをつけます。
idは『result』です。
正解、不正解で文字を表示するので、javascriptに処理を追加します。
正解の場合、不正解の場合、『次の問題』ボタンが押された場合の3パターンですね。
ついでにゲームオーバーも入れておきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
//次の問題ボタンの処理 $(document).on('click', '#next_question', function(){ $('#mondai').text(data[questionNumber][0]); questionNumber++; //キャラクターを普通に戻す $('#character').attr('src','neko-hutuu.png'); //キャラクタの発言を消す $('#result').text(''); }); ~~~省略~~~ //入力された内容と配列の回答を比較 if(inputValue == arrayAnswer){ alert("正解"); //キャラクターが喜ぶ $('#character').attr('src','neko-yorokobi.png'); //キャラクタが正解という $('#result').text('正解ニャー!'); ~~~省略~~~ alert("不正解 答え:"+data[questionNumber-1][1]); life--; //ハートを減らす $('.hart').eq(life).attr('src','hart_empty.png'); //キャラクターがダメージを受けた画像にする $('#character').attr('src','neko-dame-ji.png'); //キャラクタが回答を説明する $('#result').text('不正解!'); } ~~~省略~~~ //lifeが0でゲームオーバーと表示 if(life <= 0){ alert("ゲームオーバー!"); $('#character').attr('src','neko-sibou.png'); //キャラクタがゲームオーバーを伝える $('#result').text('ゲームオーバー!'); |
アラートはもう必要ないので消しておきましょう。
ボタンの表示制御の追加
もうゲームとして遊ぶことはできますが、一部修正します。
現在のゲームは、『回答ボタン』と『次の問題』が同時に出てくるため
問題を回答しなくても次の問題に進めてしまいます。
これを、回答ボタンを押さないと次の問題に進めないように変更します。
対応は簡単です。
『回答ボタン』を押して正解の場合の時だけ『次の問題』ボタンをshowすればいいのです。
変更したjavascriptの部分を抜粋して記載します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
//次の問題ボタンの処理 $(document).on('click', '#next_question', function(){ ~~~省略~~~ //次の問題ボタンを非表示に $('#next_question').hide(); }); ~~~省略~~~ //lifeが0でゲームオーバーと表示 if(life <= 0){ $('#character').attr('src','neko-sibou.png'); ~~~省略~~~ //キャラクタが正解という $('#result').text('正解ニャー!'); //次の問題ボタンを表示 $('#next_question').show(); |
これで『回答』ボタンを押した場合に『次の問題』ボタンが表示されます。
ウェブアプリで問題のランダム出題を行う
最後です。
現在の問題の出題順序は配列に格納されている順番です。
これをランダムに出題するようにします。
処理が始まる前に、問題データをシャッフルしてやれば、
今まで作ってきた処理に影響を影響を与えないので
シャッフル処理も入れてみましょう。
javascript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var data = [ ['Dog','犬'] ,['Cat','猫'] ,['Apple','りんご'] ,['Egg','卵'] ]; //配列のシャッフル for(var i = data.length - 1; i > 0; i--){ var r = Math.floor(Math.random() * (i + 1)); var tmp = data[i]; data[i] = data[r]; data[r] = tmp; } |
これで完成です!
完成したHTML、css、javascriptを以下に表示します。
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" type="text/css" href="style.css"> <script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script> <script src="main.js"></script> <title>暗記ゲーム</title> </head> <body> <div> <span id="mondai"></span> <br> <input type="text" id='input_answer' value=""><br> <input type="button" id="answer_button" value="回答!"> <input type="button" id="next_question" value="次の問題!"> </div> <img src="neko-hutuu.png" id="character"> <img src="hart0.png" class="hart"> <img src="hart0.png" class="hart"> <img src="hart0.png" class="hart"><br> <span id="result"></span> </body> </html> |
CSS
1 2 3 4 5 6 7 8 9 |
div{ background-color:#9ef442; margin:20px; padding:10px; } img{ max-width:20%; } |
javascript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
var questionNumber = 0; var life = 3 var data = [ ['Dog','犬'] ,['Cat','猫'] ,['Apple','りんご'] ,['Egg','卵'] ]; //配列のシャッフル for(var i = data.length - 1; i > 0; i--){ var r = Math.floor(Math.random() * (i + 1)); var tmp = data[i]; data[i] = data[r]; data[r] = tmp; } //画面読み込み時の処理 $(window).on('load',function(){ $('#next_question').trigger('click'); }); //次の問題ボタンの処理 $(document).on('click', '#next_question', function(){ $('#mondai').text(data[questionNumber][0]); questionNumber++; //キャラクターを普通に戻す $('#character').attr('src','neko-hutuu.png'); //キャラクタの発言を消す $('#result').text(''); //次の問題ボタンを非表示に $('#next_question').hide(); }); //回答ボタンの処理 $(document).on('click', '#answer_button', function(){ //入力された値を持ってくる var inputValue = $('#input_answer').val(); //配列の内容を変数に入れる var arrayAnswer = data[questionNumber-1][1]; //入力された内容と配列の回答を比較 if(inputValue == arrayAnswer){ //キャラクターが喜ぶ $('#character').attr('src','neko-yorokobi.png'); //キャラクタが正解という $('#result').text('正解ニャー!'); //次の問題ボタンを表示 $('#next_question').show(); }else{ life--; //ハートを減らす $('.hart').eq(life).attr('src','hart_empty.png'); //キャラクターがダメージを受けた画像にする $('#character').attr('src','neko-dame-ji.png'); //キャラクタが回答を説明する $('#result').text('不正解!'); } //lifeが0でゲームオーバーと表示 if(life == 0){ $('#character').attr('src','neko-sibou.png'); //キャラクタがゲームオーバーを伝える $('#result').text('ゲームオーバー!'); $('#answer_button').hide(); $('#next_question').hide(); }else{ //次の問題ボタンを表示 $('#next_question').show(); } }); |
もっと複雑な処理を勉強すれば、キャラクターをアニメーションで
動かしたりすることができますよ。
次のSTEPでは地理問題を作成していきます。
かなり複雑ですが、他のゲームを作る上で大切な要素がたくさん詰まっているので
是非挑戦してみてください。