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

今回からなんと、七回続いていたメモ帳プログラミングのぷよぷよシリーズの続編を始めていきたいと思います!

前編の第一回のURLも載っけて置きます!


今回作るもの

続編として始めていきます「ぷよぷよ編・続」では、全5回に分けて進めていきたいと思います!

  1. 落ちる場所を表示しよう! ←今回
  2. 壁にぶつかっている状態でも回転できるようにしよう!
  3. 設置する前にすこし動かせるようにしよう!
  4. スコアを表示しよう!
  5. コードをまとめてきれいにしよう!

続編では、主にぷよぷよとしての完成度を上げていきたいと思います!

そして今回は、下に置かれるぷよが表示されるようにしていきたいと思います!

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

ぷよの下に置かれる場所が表示されていますね!


コードを書いていこう!

というわけでさっそくコードを書いていきましょう!

続編は、前編と違い説明を少なくしていきたいと思います。

なので、少し難しいと感じるかもしれませんが、同じようなコードを組んでいくことになるので、前編のほうをまた読み返すことによってわかる場面も多いと思います!

自分のスピードで進めていきましょう~♪


関数を作る

まず初めに、今回作っていく関数を作っていきましょう!

function resetFall(e) {
  …省略…
}

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

function drawDropPuyo() {

}

function drawField() {
   …省略…
}

「drawDropPuyo」という関数を作りました!

ここに下に表示させる落ちる場所のコードを書いていきたいと思います!


さっきの関数をぷよが表示するときに実行させる

では次に、先ほど作った「drawDropPuyo」をぷよが表示されるときに実行されるようにしましょう!

これはすごく簡単で、ぷよが表示するコードに「draDropPuyo();」を書き込むだけです!

…
function drawField() {
  CONTEXT.clearRect(0, 0, 400, 600);
  CONTEXT.beginPath();
  CONTEXT.moveTo(300, 0);
  CONTEXT.lineTo(300, 600);
  CONTEXT.stroke();

  drawNextPuyo();

  if (stop == false) {
    drawDropPuyo();

    switch (color[0]) {
      case 1:
      CONTEXT.fillStyle = "red";
      break;
      case 2:
      …

もちろん、ぷよが下について連鎖が起きているときには表示させたくないので、「stop == false」のときだけ実行するif文がすでにあると思うので、そこに追記しましょう!


置かれる場所を表示させるコードを書いていく

では今回の目的であった置かれるぷよの場所を表示するコードを書いていきましょう!

もちろん書く場所は最初に作った「drawDropPuyo」という関数の中ですよ!

書いていくコードとしては、どこに落ちるかを計算してその場所にぷよよりは2周りほど小さい丸を表示するといったものですね!

そしてどこに落ちるかというのを計算するには、forループとif文で下にぷよが置かれているかおかれていないかというのを1つずつチェックしていきます!

まずは、ゲームを始めて1つめのぷよの置かれる場所を表示しましょう。

これですね

まだなにもぷよが置かれていないので、一番下に表示されるはずですね!

ですが次にぷよが置かれているときを考えるため、forループを使ってこのように書きましょう!

function drawDropPuyo() {
  for (let i = Math.ceil(position[1]); i < 12; i++) {
    if (i >= 11 || (i + child[1]) >= 11) {
      CONTEXT.beginPath();
      CONTEXT.arc(position[0] * 50 + 25, i * 50 + 25, 5, 0, 2 * Math.PI);
      CONTEXT.fill();
      CONTEXT.beginPath();
      CONTEXT.arc((position[0] + child[0]) * 50 + 25, (i + child[1]) * 50 + 25, 5, 0, 2 * Math.PI);
      CONTEXT.fill();
      break;
    }
  }
}

*表示する丸の大きさは少し小さくするので、半径の大きさを「5」に設定しました!

まずは、ぷよの位置のy座標を知りたいので、「Math.ceil(position[1])」で(ceilは切り上げ)を「i」に入れて繰り返しを始めました!

そして、その「i」が1つ1つ増やしていき(y座標が増えていくので、画面でいう下のほうになっていく)、下に着いたらそこに表示させるようにしています!

また、「break;」という新しいものが出てきましたね!

「break」というものを書くと、forループを途中でやめて抜け出すことができます!

この状況では必要ないのですが、続きのコードを書いていくうえで必要になってくるので、今は「break」というものがあるということだけ覚えておいてください!

さらに、このままでは色の設定がうまくいってないので、switch文を使って色の設定をしないとだめですね!

function drawDropPuyo() {
  for (let i = Math.ceil(position[1]); i < 12; i++) {
    if (i >= 11 || (i + child[1]) >= 11) {
      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.beginPath();
      CONTEXT.arc(position[0] * 50 + 25, i * 50 + 25, 5, 0, 2 * Math.PI);
      CONTEXT.fill();
      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.beginPath();
      CONTEXT.arc((position[0] + child[0]) * 50 + 25, (i + child[1]) * 50 + 25, 5, 0, 2 * Math.PI);
      CONTEXT.fill();
      break;
    }
  }
}

これでオッケーですね!


では次に2つ目以降のぷよについて考えていきましょう。

2つ目以降のぷよはすでに置かれているぷよがないかどうかを調べていかないといけないので、少し難しいです。

function drawDropPuyo() {
  for (let i = Math.ceil(position[1]); i < 12; i++) {
    if (i >= 11 || (i + child[1]) >= 11) {
      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.beginPath();
      CONTEXT.arc(position[0] * 50 + 25, i * 50 + 25, 5, 0, 2 * Math.PI);
      CONTEXT.fill();
      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.beginPath();
      CONTEXT.arc((position[0] + child[0]) * 50 + 25, (i + child[1]) * 50 + 25, 5, 0, 2 * Math.PI);
      CONTEXT.fill();
      break;
    }else if (field[i + 1][position[0]] > 0 || field[i + child[1] + 1][position[0] + child[0]] > 0) {
      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.beginPath();
      CONTEXT.arc(position[0] * 50 + 25, i * 50 + 25, 5, 0, 2 * Math.PI);
      CONTEXT.fill();
      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.beginPath();
      CONTEXT.arc((position[0] + child[0]) * 50 + 25, (i + child[1]) * 50 + 25, 5, 0, 2 * Math.PI);
      CONTEXT.fill();
      break;
    }
  }
}

とても長くなりましたが、一番大事なのはelse ifの括弧の中です!

else if (field[i + 1][position[0]] > 0 || field[i + child[1] + 1][position[0] + child[0]] > 0)

親ぷよか子ぷよのどちらかの下にぷよがあるときに、その上に表示したいため、「i + 1」の場所(1つ下の場所)を調べて、そこにぷよがあるときにはその一個上に表示するといった形になっています!

ここは長くて非常にややこしいと思いますが、大体理解出来たら十分だと思います!

そしてこれで完成です!
完成イメージと同じように動作しているはずです!


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

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

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

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


今回はここまで!

というわけで続編の第一回はここまでとしたいと思います!

続編は前編より難しい内容となっているかもしれませんので、ゆっくり進めていきましょう!

次回は、ぷよが壁にぶつかって回せないときを無くせるようにしていきたいと思います!

というわけで長くなってしまいましたが、

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

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

第二回はこちらから!

第二回は製作中です。
もう少しお待ちください。