月別アーカイブ: 2024年4月

ぷよぷよプログラミングのソースコードを理解する

作りたい落ちゲーがあり、落ちゲーの作り方を調べていました。自分にとっての落ちゲーといえば、ぷよぷよ。そこで見つけたのが、公式のセガが提供している「ぷよぷよプログラミング」です。落ちゲーの作り方を学ぶため、ぷよぷよプログラミング」のソースコードを理解したいと思います。

ソースコードは以下の公式サイトからダウンロードできます。

https://puyo.sega.jp/program_2020

アプリ画面

以下は実際のアプリ画面です。←/→キーで左/右に移動でき、↑キーで左回転できます。右回転はできないようです。アプリを起動すると思わずやってしまいますね。やっぱりぷよぷよは楽しい。

ぷよぷよのゲーム画面

起動時の処理

www/src/game.jsで、Webページの読み込みが完了したときに initialize() と loop() を実行しています。initialize() はデータの初期化であったり、キーボード入力時の処理の登録を行っているようです。loop() でゲームを開始しています。

// 起動されたときに呼ばれる関数を登録する
window.addEventListener("load", () => {
    // まずステージを整える
    initialize();

    // ゲームを開始する
    loop();
});

loop() の最後の行で、requestAnimationFrame() を実行しています。これにより、loop() が繰り返し実行されます。1/60秒後に呼び出すとコメントがありますが、仕様によると、多くのブラウザではディスプレイのリフレッシュレートに合わせて呼び出されるようです。

loop() の繰り返しの中で行う処理を、modeの値に応じて切り替えています。

function loop() {
    switch (mode) {
        case "start":
            // 最初は、もしかしたら空中にあるかもしれないぷよを自由落下させるところからスタート
            mode = "checkFall";
            break;
        case "checkFall":
            // 落ちるかどうか判定する
            if (Stage.checkFall()) {
                mode = "fall";
            } else {
        ...中略...
    }
    frame++;
    requestAnimationFrame(loop); // 1/60秒後にもう一度呼び出す
}

modeの状態遷移

modeの値がどのように変化するのかわかりやすくするため、状態遷移図に起こしてみました。

modeの状態遷移図

アプリ実行時には、ぷよはステージ上に一つもありません。よって、start → checkFall → checkErase → newPuyoへと特に何も処理をせずに遷移します。newPuyo で新しいぷよを作成し、playing でプレイヤーの操作を受け付ける状態になります。操作がなければ playing のままですが、移動や回転操作があれば moving か rotating に変わります。操作するぷよがステージの床に着いたら fix になり、checkFall に戻ります。

checkFall では、自由落下するぷよがあるかを判定し、fall で自由落下の描画を行います。自由落下とは、下段のぷよを消して上段のぷよが降ってくるなどの状態のことです。checkErase では、削除するぷよがあるかを判定し、erasing でぷよの削除を行います。

newPuyo で新しいぷよが作成できないと gameOver になり、batankyu となってばたんきゅーという文字を画面に描画します。

今後やりたいこと

mode の状態遷移がわかったことで、全体としてどんな処理を行っているのかが理解できました。今回久しぶりにぷよぷよをやったのですが、またハマりそうです。せっかくソースコードを理解したので、機能を追加していくのも楽しいかなと思っています。