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

2020年11月5日

今回も、前回までと同様にメモ帳だけを使って、あの有名なパズルゲーム「ぷよぷよ」を作っていきたいと思います!

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


今回作るもの

前回は、ぷよぷよの醍醐味といえる「連鎖」のコードを組みましたね!

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

そして今回は、最終回として、次のぷよが何色かが見える「ネクスト」というシステムなどを導入したり、ぷよの形を丸にしたりするなど、

ぷよぷよとしての完成度を上げたいと思います!

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

次のぷよが何かわかるようになると、連鎖が組みやすくなり面白くなりますよ!

ぜひ最後まで読んで、ぷよぷよを完成させちゃいましょう!


コードを書いていこう!

今回も前回までと同様にメモ帳にコードを書いていきましょう!

今回のコードは前回に比べてめちゃくちゃ簡単です!
(前回がむずすぎましたね)

なので今回はゆっくり進めていきましょう~!


変数と関数を作る

まず初めに、今回使う「ネクスト」のためのコードを作るのに必要な変数を作っていきましょう

…
let child =  [0, -1];

let next_puyo = [Math.floor(Math.random() * 4 + 1), Math.floor(Math.random() * 4 + 1)];
let next_next_puyo = [Math.floor(Math.random() * 4 + 1), Math.floor(Math.random() * 4 + 1)];

let color = [Math.floor(Math.random() * 4 + 1), Math.floor(Math.random() * 4 + 1)];
let direction = 90;
…


真ん中の二つですね。

ぷよぷよには、次のぷよである「ネクスト」と、その次のぷよである「ネクネク」というのがあって、それをしまうための変数が「next_(next_)puyo」となっています。

そして、その変数たちに次のぷよの色の数字を入れておくようにします。

次に今回ネクストを表示させるための新しい関数を1つ作ります。

function nextPuyo() {
…省略…
}

function drawNextPuyo() {

}

function movePuyo(e) {
…省略…
}

「drawNextPuyo」と名前にある通り、ネクストやネクネクを表示させるコードはこの関数に書いていきます!


ぷよの形を丸にする

今までの第六回目まではずっとぷよの形が四角形でカクカクしてましたね。

もう少し本家に寄せるために、円を描く処理を使って丸にしたいと思います。

円を描くコードは、

CONTEXT.beginPath();
CONTEXT.arc(円の中心のx座標, 円の中心のy座標, 半径, 0, 2 * Math.PI);
CONTEXT.fill();

のように書きます。

なので、今までの「drawField」の関数はこのようになりますね!

function drawField() {
  CONTEXT.clearRect(0, 0, 300, 600);

  if (stop == false) {
    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, (position[1] + child[1]) * 50 + 25, 25, 0, 2 * Math.PI);
    CONTEXT.fill();
    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, position[1] * 50 + 25, 25, 0, 2 * Math.PI);
    CONTEXT.fill();
  }

  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.beginPath();
        CONTEXT.arc(j * 50 + 25, i * 50 + 25, 25, 0, 2 * Math.PI);
        CONTEXT.fill();
      }
    }
  }
}

こんな感じですね!

これで実行すれば、ぷよの形が丸になっているはずです!


ネクストが表示できるスペースを作る

では次に、前回のままでは、キャンバス(=ゲーム画面)にぷよを表示するスペースがないので、少し右側を開けてスペースを確保したいと思います。

また、ついでなんですが、今ゲーム画面が左上にあるんですが少し見栄えをよくするために真ん中に来るようにしたいと思います。

キャンバスの大きさを少し上げて、ゲーム画面を真ん中にするには、第一回で書いたHTMⅬの部分を少しいじりましょう。

<center><canvas width="400" height="600" id="canvas" style="border:1px solid black"></canvas></center>

まずは普通に、300:600だったのを400:600に変えます。

そして次にcanvasのタグを囲むように「center」というもので囲みます。

これをすることで画面がど真ん中に来るようになるはずです!

そして、これによって画面を一度消すという処理があったんですが、この部分も少し変えなければいけません。

それは、「drawField」の中にある「clearRect」という処理です。

function drawField() {
  CONTEXT.clearRect(0, 0, 400, 600);

単にx座標の数字を400にするだけですが、忘れないようにしましょう。

これでキャンバスの設定はおしまいです。


関数「nextPuyo」の処理を変える

今までぷよが置かれた後に次のぷよに変える処理は「nexPuyo」に入れていましたが、ネクストが増えたことによって少し変えなければいけなくなったので、必要な箇所だけ少し変更します。

function nextPuyo() {
  color = next_puyo;
  next_puyo = next_next_puyo;
  next_next_puyo = [Math.floor(Math.random() * 4 + 1), Math.floor(Math.random() * 4 + 1)];

  position = [2, 1];
  child = [0, -1];
  direction = 90;
}

ぷよが置かれたときは、ネクストにあるぷよを次に落とすぷよ、ネクネクにあるぷよをネクストのぷよのように動かします。

そして、ネクネクはランダムな色で生成すればOKですね。


ネクストを表示する

では本題の、ネクストを表示していきましょう、と言いたいところですが、その前に完成イメージにもあるように、ネクストとフィールの間に一本線を引きましょう。

これがないとどこまでがフィールドなのかわからなくなってしまいますからね💦

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

  drawNextPuyo();

  if (stop == false) {
…

メモ帳プログラミングのスライドパズル編を読んでくださればmoveToなどの詳しい解説は載っていますが、ここでは簡単に説明します。

「beginPath」でこれから線を引き始めるという合図を出し、「moveTo」で線を引き始める点を決めて、「lineTo」で線を引き終える点を決めて、最後の「stroke」で線を引いているといったところです。

また、drawFieldと一緒にネクストが表示させる処理も呼び出したいので、「drawNextPuyo」もここに書いています。

ということでここからが本題のネクストを表示させる処理です。

まずは、画面に「Next」と「NextNext」と表示させるコードを書きましょう。

function drawNextPuyo() {
  CONTEXT.fillStyle = "black";
  CONTEXT.fillText("Next", 340, 50);
  CONTEXT.fillText("NextNext", 330, 250);
}

fillText(表示する文字, x座標, y座標);

といった使い方をするので、上のようなコードになりますね。

そして次に肝心のぷよを表示させるのですが、ぷよを表示させるコードというのは第一回で書きましたね!

switch文を使って色を指定し、表示させるコードをコピペするなどして持ってきて、必要な部分だけ変えればOKです。

いきなりですが答えを書くので、考えたい方は一度スクロールをとめて考えましょう!

function drawNextPuyo() {
  CONTEXT.fillStyle = "black";
  CONTEXT.fillText("Next", 340, 50);
  CONTEXT.fillText("NextNext", 330, 250);

  switch (next_puyo[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(350, 100, 25, 0, 2 * Math.PI);
  CONTEXT.fill();

  switch (next_puyo[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(350, 150, 25, 0, 2 * Math.PI);
  CONTEXT.fill();

  switch (next_next_puyo[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(350, 300, 25, 0, 2 * Math.PI);
  CONTEXT.fill();

  switch (next_next_puyo[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(350, 350, 25, 0, 2 * Math.PI);
  CONTEXT.fill();
}

非常に長いコードですね。

これも繰り返しを使えばうまくまとめることができますが、ここではしないので、ぜひ自分でチャレンジしてみましょう!

これでなんと完成です!


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

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

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

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

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

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


完成!

ということで、これで「ぷよぷよ」の完成です!

ぷよぷよとして遊べるゲームが完成しましたね!

ネクストができたことにより、やりやすくなり時間を忘れちゃうぐらい面白いですね!

是非、ゲームのスクリーンショットなどと共に感想を聞かせてください!

コメントやTwitterにどんなことでもいいので、ご感想いただけたらすごく喜びます!

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

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

ぷよぷよ編の続編もあります!
「もっとぷよぷよとして完成度を上げたい!」と考えている方は是非読んでみてください!

このブログでは、ぷよぷよ以外にも様々なゲームの作り方をご紹介しているので、ぜひ読んでみてください!

おすすめ記事:

【超おすすめ】あまり知られていない隠れた神ゲー〈3選〉

みなさんはゲームは好きですか? このブログの運営主のただの大学生は、ゲームが大大好きです。 今まで様々なハードで様々なゲームをプレイしてきました! なので、メチャクチャ有名なゲームから、意外と知られていない無名のゲームを […]

また、ほかにもメモ帳を使ったプログラミングをお探しの方は、まとめたページがあるので、そちらもぜひ見てください!

クリックで飛べますメモ帳プログラミング一覧