cre8cre8
AskMe♥

cre8なJavaScript入門
~for文(繰り返し)を使ってDQ風ゲームを改造してみよう~

前回の記事のif文講座の最後のサンプルゲーム作成は、ちょっと難しかったですか?

講座第三弾の今回は記事はなんと!
無限ループって怖くね?というワードが有名な繰り返し(ループ)編です。
無限ループというワードがでましたが、
うまく作れれば無限ループになりませんので、安心してくださいね。
万一、作ったサンプルが無限ループになった場合は、開いているブラウザを閉じれば
やりなおせますので、最悪のときには閉じて対処してください。
(といっても、最近のブラウザは賢いのでJavaScript重いので中止しますか?ってダイアログでると思います。)

今回の最終サンプルは、前作のゲームを改良しますので、楽しみにしていてくださいね。
それでは、さっそくループの醍醐味を味わえるサンプルを作りましょう!

1<!doctype html>
2<html>
3  <head>
4    <meta charset="utf-8">
5  </head>
6  <body>
7    <script>
8      // 好きな数値に変えて遊んでみてください
9      var max = 10;
10
11      for (var i = 0; i < max; i++) {
12        var e = document.createElement("div");
13        e.innerText = "羊が" + i + "匹...";
14        document.body.appendChild(e);
15      }
16    </script>
17  </body>
18</html>

0から9までの10回ループします。
0回目があるので、10回になるのですね。
ちょっとわかりづらいかたは、表示された「羊がn匹...」を数えるとわかると思います。
また、 max 変数の数値をいろいろと変えて遊んでみてください。

for (var i = 0; i < max; i++) の箇所ですが、
これは、
for ( 初期化処理; ループを抜ける条件; 更新処理 )
となります。

このサンプルの場合は
i 変数を用意して0を代入して初期化(ループの最初の1回しか実行されない)
ループを抜ける条件は、imax より大きくなった時
i++ はループが実行されるたびに、i が1増える
処理を書いてます。

ループの中の
var e = document.createElement("div");
div タグを生成する処理です。
div タグを作って、その中に「羊がn匹...」と作っていってます。
n はループのカウンター(i変数)を使っているので、どんどん増えていくわけです。

ちなみに、
e.innerText = "羊が" + (i+1) + "匹...";
とすると、羊が1匹... から 羊が10匹... まで表示されます。
なぜそうなるのか、少し考えてみてくださいね。

では、次に複数のボタンに対して、一気にイベントを登録してみましょう。
今までは、 document.getElementById でひとつづつ設定していたのが、
ループを使うことによって楽に全部に設定できるようになりますよ。

1<!doctype html>
2<html>
3  <head>
4    <meta charset="utf-8">
5  </head>
6  <body>
7
8    <button class="clickme" data-song="いつもと違う髪型に気が付くこと">その一</button>
9    <button class="clickme" data-song="ちゃんと靴まで見ること いいね?">その二</button>
10    <button class="clickme" data-song="わたしの一言には三つの言葉で返事すること">その三</button>
11
12    <div id="showMessage"></div>
13
14    <script>
15
16      var elements = document.getElementsByClassName("clickme");
17
18      for (var i = 0; i < elements.length; i++) {
19        elements[i].addEventListener("click", function() {
20          document.getElementById("showMessage").innerText = this.dataset.song;
21        });
22      }
23
24    </script>
25  </body>
26</html>

ボタンが3つ並び、JavaScriptでクリックイベントをつけています。
今までと違うのは、 for ループでボタンすべてにクリックイベントをつけているところです。
もし、 document.getElementById で作るとなると、 addEventListener を3つ書かないといけません。
今回は、ボタンが3つでしたが、これが、100個や1000個になってくると…(´・ω・`)
ループの便利さがわかっていただけましたか?

this.dataset.song の箇所ですが、これはちょっとむずかしいので、
今は <button class="clickme" data-song="...">data-song に指定したものをとってくるのだと理解しておいてください。
詳細の説明はもっとJavaScriptを慣れてからしますね。
(歌詞はワールドイズマインから引用しました。)

さぁ!ここまで来たら前回のゲームをどのように便利にするかお察しのいい方は気づいたでしょう!
そうです!フォームに入力するのではなく、ボタンにするのです!!!<ナッナンダッテー>(棒読み)

1<!doctype html>
2<html>
3  <head>
4    <meta charset="utf-8">
5  </head>
6  <body>
7    <style>
8      h1 {
9        font-size: 1.25rem;
10      }
11      .damage {
12        color: #cc0000;
13      }
14      .underZero {
15        font-size: .75rem;
16      }
17    </style>
18    <dl>
19      <dt>あなた</dt>
20      <dd>(肉体的な)HP: <span id="hp">320</span></dd>
21    </dl>
22    <h1 id="message">ふと見ると、公園のベンチに おめがうぇぽん 座っていました</h1>
23
24    <button data-action="attack">戦う</button>
25    <button data-action="superSkill">超☆必殺</button>
26    <button data-action="megante">メガンテ</button>
27
28    <script>
29      // アクションボタン
30      var buttons = document.getElementsByTagName("button");
31
32      // DOM選択
33      var messageElement = document.getElementById("message");
34      var hpElement = document.getElementById("hp");
35
36      // 現在のHP(足し引きするために数値に変換する)
37      var hp = parseInt(hpElement.innerText);
38
39      /* データの形式 */
40      // アクション: [ダメージ, メッセージ]
41      var data = {
42        attack: [80, "じ、持病の腰痛がっ…!!!"],
43        superSkill: [280, "メタボ the パワー で自分へダメージ!!"],
44        megante: [999, "あぁ^~心がぴょんぴょんするんじゃぁ^~。"]
45      };
46
47
48      for (var i = 0; i < buttons.length; i++) {
49        buttons[i].addEventListener("click", function() {
50          var action = this.dataset.action;
51          var damage = data[action][0];
52          var message = data[action][1];
53
54          hp = hp - damage;
55
56          message = message + '<p class="damage">' + damage + " ポイントのダメージをうけた!" + "</p>";
57
58          if (hp <= -3000) {
59            message = message + '<p class="underZero">さすがに、マイナス3000を超えると死んでる…かも…</p>';
60          } else if (hp <= 0) {
61            message = message + '<p class="underZero">HPがマイナスでも死ぬまで戦えます。あなたならできます。信じてください。</p>';
62          }
63
64          messageElement.innerHTML = message;
65          hpElement.innerText = hp;
66        });
67      }
68
69    </script>
70  </body>
71</html>

どうです?ちょっとゲームっぽくなりましたでしょ?
いい感じでしょ?夢広がってきましたでしょ?
簡単にゲームの概要を説明しますと、
ボタンを押して行動を選択して、その選択に応じたメッセージ表示とダメージ計算をしています。

JavaScriptの解説ですが、難しいと思いますので、全部理解しなくても大丈夫です。
なんとなーく、こうすれば動くんだと把握しておいてくださいね。

まず、var buttons = document.getElementsByTagName("button"); で、<button> タグをすべて選択してとっています。
その後の DOM選択とHP は前回の記事のものを流用しています。

1var data = {
2  attack: [80, "じ、持病の腰痛がっ…!!!"],
3  superSkill: [280, "メタボ the パワー で自分へダメージ!!"],
4  megante: [999, "あぁ^~心がぴょんぴょんするんじゃぁ^~。"]
5};

上記のコードがちょっとむずかしいと思います。
これは、選択したボタンの data-action に入れているデータと、ダメージ&メッセージのひも付けを行っています。
攻撃(attack)を選んだときは、80ダメージで、"じ、持病の腰痛がっ…!!!"と表示するためのものです。

あとは、 for ループで <button> タグの数だけクリックイベントをバインドしています。
さりげなく、 if 文もいれてますので、前の講座の復習にもなりますね。たっくんてばさいきょーね。

今回は、 innerHTML を使用しています。 innerText との違いですが、
HTMLタグを使用できるかどうかの違いがあります。
メッセージを装飾(ダメージの部分を赤色や、HPが0を下回ったときの文字を小さく表示する)するために
innerHTML を使って <p> タグで囲みました。

上記のサンプルを使って、行動メニューを増やしてみたり、
メッセージやダメージ量を変えて遊んだりしてみてください。
自分で考えて作るとおどろくほどJavaScriptを学ぶ速度があがるので。

ループや条件分岐にはこのほかにも書き方があるのですが、
まずは、このやり方を覚えていって、ステップアップしていきましょう!
次回は関数を学んでグラフィカルなものをつくりましょう!
あとはこれを覚えればだいたいなんとかなります。
それでは、お楽しみに!お疲れ様でした(`・ω・´)

≪ 前の記事
cre8cre8なJavaScript入門
~if文(条件分岐)を使って簡単なDQ風ゲームを作ってみよう~
次の記事 ≫
cre8cre8なJavaScript入門
~関数を使ってグラフィカルなプログラムをつくろう~

いいねやコメントを送っていただけると中の人がしっぽ振って大喜びします♪

あなたへのおすすめの記事