【中級者向け】第二回 メモ帳だけでゲーム作ってみた〈ぷよぷよ編〉

2020年10月5日

今回も、パソコンに入っている「メモ帳」だけを使って、「ぷよぷよ」を作っていきたいと思います♪

前回の記事をまだ読んでいない方は、ぜひそちらを先に読んでください!


今回作るもの

前回は、ぷよぷよのフィールドを作り、実際にぷよを置いて見ました。

  1. ぷよぷよのフィールドを作ろう! ←前回
  2. ぷよを上から落としてみよう! ←今回
  3. ぷよを操作できるようにしてみよう!
  4. ぷよを回転できるようにしてみよう!
  5. ぷよが下に落ちるようにしよう!
  6. 連鎖をできるようにしよう!
  7. 次のぷよが何なのかわかるようにしてみよう!

今回は、ぷよを真ん中の上から落としてみたいと思います!

完成イメージは以下の通りです。

ぷよが上から落ちてきて、下に設置すると新しく上からランダムな色のぷよが落ちてくるようにします!


コードを書いていこう!

ここからは、前回と同様に、メモ帳に書いていきましょう!

今回は、条件分岐をたくさん使うので、ややこしくなるかもしれませんが、ゆっくり考えて行きましょうね♪


変数を作る

まず初めに、今回使う変数を作っていきましょう。

前回の多次元配列の下の部分に追加していきましょう。

… 
 [1, 2, 0, 3, 4, 4]
];

let position = [2, 0];
let child =  [0, 1];
let color = [Math.floor(Math.random() * 4 + 1), Math.floor(Math.random() * 4 + 1)];

let down = 0.02;

「position」というのが、ぷよの位置を指していています。

それの初期設定が、「2, 0」になっているので、真ん中の上に設定しました!

そして次の「child」というのですが、これはぷよぷよの正しい仕組みを知らないとわかりにくいかもしれません…

ぷよぷよを操作するときに、回るぷよと回らないぷよがあります。

その回らない方のぷよを「親」として、回る方のぷよを「子」とします。

そして先ほど作った「親」の位置を指すのが、「position」という変数で、親から見てどの位置にあるのかを指す変数が、「child」となっています。

なので、child = [0, 1];になっているので、親ぷよの下に子ぷよがある状態ですね。

子ぷよに関しては第4回でも詳しく説明するので、今は大体の理解で大丈夫です。

そして「color」というのが、落ちてくるぷよの色を設定しています。

1から4を出す乱数が使われていますね。

これは前回の多次元配列に閉まった数字と同じで、それぞれの数字に対応する色が決められていますね。

最後の「down_speed」というのが、ぷよの落ちる速さです。

もう少し早くしたければ、0.04などにしてみましょう。


落ちてくるぷよを表示させる

では次に、先ほど設定した変数を使って、ぷよを上に表示させてみましょう。

前回作った「drawPuyo」という関数に、落ちてくるぷよを表示させるコードを書いて見ましょう。

function drawField() {
  CONTEXT.clearRect(0, 0, 300, 600);
  switch (color[0]) {
    case 1:
      CONTEXT.fillStyle = "red";
      break;
    case 2:
      CONTEXT.fillStyle = "yellow";
      break;
    case 3:
      CONTEXT.fillStyle = "blue";
      break;
    case 4:
      CONTEXT.fillStyle = "green";
      break;

  }
  CONTEXT.fillRect((position[0] + child[0]) * 50, (position[1] + child[1]) * 50, 50, 50);

  switch (color[1]) {
    case 1:
      CONTEXT.fillStyle = "red";
      break;
    case 2:
      CONTEXT.fillStyle = "yellow";
      break;
    case 3:
      CONTEXT.fillStyle = "blue";
      break;
    case 4:
      CONTEXT.fillStyle = "green";
      break;

  }
  CONTEXT.fillRect(position[0] * 50, position[1] * 50, 50, 50);

  for (let i = 0; i < 12; i++) {
    for (let j = 0; j < 6; j++) {
      if (field[i][j] > 0) {
        switch (field[i][j]) {
          case 1:
            CONTEXT.fillStyle = "red";
            break;
          case 2:
            CONTEXT.fillStyle = "yellow";
            break;
          case 3:
            CONTEXT.fillStyle = "blue";
            break;
          case 4:
            CONTEXT.fillStyle = "green";
            break;

        }
        CONTEXT.fillRect(j * 50, i * 50, 50, 50);
      }
    }
  }
}

下半分は前回書いているので、書かなければいけないのは前半部分ですね。

最初に「clearRect」というのは画面を一度真っ白に戻すために書いています。
今はこれがあってもなくても動きますが、あとでどうせ書くので先に書いておきました。

これで実行してみると、上にぷよが表示されるはずですね!


ぷよを下に動かす

ここからは少しずつぷよを下に動かしていく処理を書いていきます。

私の、初心者向けメモ帳プログラミングの「ブロック崩し編」を読んだ方は、分かると思いますが、

すこしずつぷよを下に動かす処理には、パラパラ漫画のような手法を使います。

ぷよを表示→数秒後に画面を消去→ぷよを少し下に表示→…

これを人間の目には見えないぐらい早く行うことで、まるで動いているかのように処理させます。

プログラムで書くのは、そのぷよを少し下に表示させるコードと、画面を消去するものだけです。

そして、画面の消去は先ほど書いたので、ぷよを少し下に表示させるコードだけですね。

また、これをパラパラ漫画のように処理させるために、「setInterval」というのを使います。

ここでは「setInterval」については詳しく説明しないので、気になる方は私のブロック崩し編を読むか、ネットで調べてみてください!

…
let down_speed = 0.02;

function downPuyo() {
  position[1] += down_speed;
  drawField();
}

let timer = setInterval(downPuyo, 1000 / 60);

function drawField() {

ブロック崩し編の時と、「setInterval」の書き方が少し違いますが、処理は同じです。

新しく「downPuyo」という関数を作り、ぷよの「position」を少し下にして、ぷよを表示させるという処理を書きました!

あとは、下についたら上に新しいぷよを表示させればいいですね!


画面の下についたら次のぷよを上に表示させる

まず初めに、ぷよが画面の一番下についたかどうかを判定するif文を、downPuyoの中に追加しましょう。

上の画像より、ぷよの位置が、一番下の時はposition[1]は11より大きい数になっているので…

function downPuyo() {
  position[1] += down_speed;
  if (position[1] >= 11 || position[1] + child[1] >= 11) {

  }
  drawField();
}

と書くことができますね!

あとは、一番下についたとき、多次元配列の中の対応する場所にぷよを記録させて、ぷよの位置を上に戻し、色をランダムで入れ替えるようにすればいいので…

if (position[1] >= 11 || position[1] + child[1] >= 11) {
  field[Math.floor(position[1])][Math.floor(position[0])] = color[1];
  field[Math.floor(position[1] + child[1])][Math.floor(position[0] + child[0])] = color[0];

  position = [2, 0];
  child = [0, 1];
  color = [Math.floor(Math.random() * 4 + 1), Math.floor(Math.random() * 4 + 1)];
}

となりますね。

「||」というのは「または」という意味があります。

ifの中が「||」を使って二つにしている理由は、「||」の左は親ぷよ、「||」の右は子ぷよで、二つのぷよの下のどっちかが埋まっていたら置くようにしたいからです。

今はぷよの回転を考えていないので、この2つを考える必要はないですが、今後回転を考える時に書くことになるので、先に書いておきましょう。

また、floorをちょこちょこ使っているのは、もしもpositionが「11.02」など少しずれてしまったときに、「11」に戻すためにありますので、一応なくても行けるはずです。

念のためってプログラミングでは少し大事なので、書くのも練習かもしれません笑

これで一番最初にぷよが下に置かれると、上にランダムな色の新しいぷよが出てくるはずです!

そして最後の問題は、2つ目以降のぷよが、下のぷよに乗る時にすり抜けちゃうことですね。

今はif文で画面の一番下にあるかどうかを確認したので、次はぷよがあるかどうかを判別するコードを書きます。


下にぷよがあると次のぷよを表示するようにする

これを実現するには、今のpositionが例えば「2, 5」だったら、一個下のマスである「2, 6」にぷよがあるかチェックするようにすればいいですね。

なので、先ほどのif文にelse ifをくっつけて下のように書けばいいですね!

if (position[1] >= 11 || position[1] + child[1] >= 11) {
  field[Math.floor(position[1])][Math.floor(position[0])] = color[1];
  field[Math.floor(position[1] + child[1])][Math.floor(position[0] + child[0])] = color[0];

  position = [2, 0];
  child = [0, 1];
  color = [Math.floor(Math.random() * 4 + 1), Math.floor(Math.random() * 4 + 1)];
}else if (field[Math.floor(position[1]) + 1][Math.floor(position[0])] > 0 || field[Math.floor(position[1] + child[1]) + 1][Math.floor(position[0] + child[0])] > 0) {
  field[Math.floor(position[1])][Math.floor(position[0])] = color[1];
  field[Math.floor(position[1] + child[1])][Math.floor(position[0] + child[0])] = color[0];

  position = [2, 0];
  child = [0, 1];
  color = [Math.floor(Math.random() * 4 + 1), Math.floor(Math.random() * 4 + 1)];

}

fieldのぷよがある場所の下にぷよがあるかどうかを、またまた親ぷよと子ぷよでチェックしていますね。

そこだけが少し難しいだけで、ifの中とelse ifの中は全く同じですね!

これで実行すれば、ぷよが下に落ちていって、下につくと新しいぷよが上に出てくるようになっているはず!


うまくいかなかった方向け

うまくいかなかった方は、まずエラーが出ていないか確認しましょう!

エラーの確認方法については、別の記事で詳しくまとめたので、ぜひそちらを参考にしてください!

【初心者向け】 JavaScriptの エラーの直し方

自分が作ったコードがうまく動かないってこと、プログラミングで本当によく起きますよね?私なんて、10回トライして9回エラーでうまくいかないなんてこともよくあります。 でもそんなときどこが間違っているか、自分の目ですべて探す […]

それでもうまくいかなければ、下のサンプルコードをダウンロードして、自分のコードを比較してみましょう!


今回はここまで!

というわけで、第二回はここまでとしたいと思います!

ちょっとずつぷよぷよに近づいてきましたね。

きちんと作った通りに動くと嬉しいですね!
その嬉しい気持ちをバネにして次回も頑張っていきましょう!

次回は、ぷよをキーボード入力で、右左に動かせるようにしたいと思います!

長くなってしまいましたが、

最後まで読んでいただきありがとうございました!

ご感想などあれば、コメントやTwitterにどしどしお寄せください!

第三回はこちらから!