RPGツクールMZ|鉄板のパズルミニゲーム「ライツアウト」の作り方

当ページのリンクには広告が含まれています。

今回は、フリーゲームでも定番のパズルミニゲーム「ライツアウト」をRPGツクールMZで作る方法を解説します。

ライツアウトは、ボタンを押すとそのマスと上下左右のマスが反転し、すべての色をそろえるとクリアになるパズルです。この記事では3×3の9マスを用意し、すべて赤になったら扉が開くイベントを作ります。

3×3のライツアウトとリセットレバーの完成画面

作り方は次の2通りです。

  1. イベントコマンド版:処理を画面上で追いやすく、初心者向け。ただし管理とデバッグの手間が多い
  2. スクリプト版:コードを使う代わりに、必要なスイッチや変数を大きく減らせる

まずは仕組みを理解しやすいイベントコマンド版から見ていきます。記事の後半には、そのままコピーできるJavaScriptも掲載しています。

チャプター

1. ライツアウトの仕組み

今回の完成条件は「9マスすべてが点灯していること」です。

各マスにはON/OFFの状態を持たせます。ボタンを押したときは、押したマスだけでなく上下左右も確認し、それぞれの状態を反転させます。

同時に、現在ONになっているマスの数を変数「点灯数」で管理します。

  • OFFからONになったマス:点灯数を1加算
  • ONからOFFになったマス:点灯数を1減算
  • 点灯数が9以上:ゴールの扉を開く

この「マスの状態」と「点灯数」をずれないように更新するのが、ライツアウト作りの中心です。

2. 2つの作り方はどちらを選ぶべき?

作り方向いている人メリットデメリット
イベントコマンド版スクリプトに慣れていない人画面上で処理を追いやすいスイッチ・変数・条件分岐が増え、番号の確認が大変
スクリプト版JavaScriptに抵抗がない人処理が短く、セルフスイッチで管理できるコードの内容が分からないと修正しにくい

初心者は、まずイベントコマンド版で仕組みを理解するのがおすすめです。完成後にスクリプト版と見比べると、「イベントコマンドで組んだ長い処理を、コードではどうまとめるのか」が見えてきます。

3. 事前に用意するイベント・スイッチ・変数

マップ上には次のイベントを配置します。

  • 3×3に並べたボタンイベント:9個
  • クリア時に開くゴールの扉:1個
  • 初期状態へ戻すリセットレバー:1個

イベントコマンド版では、9マスに対応する通常スイッチも用意します。スイッチのデータベース番号はどこでも構いません。名前を「1」から「9」にしておくと、マスとの対応が分かりやすくなります。

1から9までの通常スイッチを用意する画面

さらに、次の5つの変数を用意します。

変数名役割
点灯数現在ONになっているマスの数
このイベントのX押したイベントのX座標
このイベントのY押したイベントのY座標
イベントID指定した座標にあるイベントのID
ループ自分・左・右・上・下を順番に調べるためのカウンター
イベントコマンド版で使う5つの変数

なお、ボタンイベントのIDとマス番号を対応させる必要があります。今回の例では、ボタン1から9のイベントIDも1から9です。別のイベントを先に作ってIDがずれている場合は、後述する条件分岐側を実際のイベントIDに合わせてください。

4. ゴールの扉を作る

ゴールイベントは3ページ構成にします。

4-1. 1ページ目:閉じた扉

1ページ目には閉じた扉の画像を設定します。実行内容は空でも構いません。画像の向きが勝手に変わらないように「向き固定」を有効にしておきます。

4-2. 2ページ目:点灯数9以上で開く

2ページ目の出現条件を「変数:点灯数が9以上」にし、トリガーを「自動実行」にします。

点灯数が9以上になったら自動実行するゴールイベント

実行内容には扉を開く移動ルートを設定します。

RPGツクールMZの扉画像は、キャラクターの向きを「左→右→上」と変えることで、徐々に開くように見せられます。手作業が面倒な場合は、空の場所を右クリックし、「イベントの簡単作成」から扉イベントを作って、その開閉処理をコピーしても構いません。

扉が開いたらセルフスイッチAをONにします。

4-3. 3ページ目:開いた後の移動処理

3ページ目の出現条件をセルフスイッチAにします。画像は開いた扉、トリガーは「プレイヤーからの接触」にし、マップ移動などクリア後の処理を入れます。

動画内の例では確認しやすいようにゲームオーバーを実行していますが、実際のゲームでは次の部屋への移動や報酬イベントに置き換えてください。

5. イベントコマンドだけで9つのボタンを作る

まず、ボタン1のイベントを作り、それを複製して2から9を作ります。

ボタンイベントの基本設定は次のとおりです。

  • オプション:向き固定
  • プライオリティ:通常キャラの下
  • トリガー:決定ボタン
  • 1ページ目:OFF状態の画像
  • 2ページ目:ON状態の画像

「通常キャラの下」にしないと、プレイヤーがボタンの上に乗れません。床スイッチとして使う場合は忘れずに設定してください。

5-1. ループを作り、自分の座標を取得する

イベントコマンド1ページ目の「フロー制御」から「ループ」を作ります。

ループの先頭で、変数「このイベントのX」と「このイベントのY」に現在のイベントの座標を代入します。

「変数の操作」でオペランドを「ゲームデータ」にし、次の値を選びます。

  • キャラクター → このイベント → マップX
  • キャラクター → このイベント → マップY
このイベントのX座標を変数へ代入する画面

5-2. 指定位置の情報取得でイベントIDを調べる

イベントコマンド3ページ目の「指定位置の情報取得」を使います。

設定は次のとおりです。

  • 代入先の変数:イベントID
  • 情報タイプ:イベントID
  • 場所:変数で指定
  • X:このイベントのX
  • Y:このイベントのY
XとYで指定した場所のイベントIDを取得する画面

これで、現在調べている座標にあるイベントのIDを変数へ入れられます。

5-3. イベントIDごとにスイッチと点灯数を反転する

取得したイベントIDが1だった場合、通常スイッチ「1」の状態を確認します。

◆条件分岐:イベントID = 1
  ◆条件分岐:スイッチ「1」がON
    ◆スイッチの操作:「1」= OFF
    ◆変数の操作:点灯数 -= 1
  :それ以外のとき
    ◆スイッチの操作:「1」= ON
    ◆変数の操作:点灯数 += 1
  ◆分岐終了
◆分岐終了
スイッチを反転しながら点灯数を増減する条件分岐

同じ条件分岐をイベントID2から9まで作ります。変更する場所は次の4箇所です。

  1. 外側の条件分岐で比較するイベントID
  2. 内側の条件分岐で確認するスイッチ
  3. ONからOFFにするスイッチ
  4. OFFからONにするスイッチ

たとえばイベントID5なら、4箇所すべてをスイッチ「5」に合わせます。ここが1つでもずれると、見た目と点灯数が食い違います。

5-4. 自分・左・右・上・下を5周で判定する

ライツアウトでは、押したマスだけでなく上下左右も反転させます。

そこで変数「ループ」を使い、同じ判定を5周させます。

ループの値調べる場所座標の変更
0押したマス自身変更なし
1Xを1減算
2Xを1加算
3Yを1減算
4Yを1加算

ループの先頭では毎回、このイベント自身のX/Yを取得し直します。その後、ループの値に応じてXまたはYをずらしてから、指定位置のイベントIDを取得します。

ループの値に応じて左・右・上・下を判定するイベント

イベントID1から9の判定が終わったら、変数「ループ」を1加算します。続けて条件分岐を置き、「ループが5以上」なら「ループの中断」を実行します。

ループを抜けた直後には、必ず変数「ループ」に0を代入してください。0へ戻さないと次にボタンを押した時も値が5以上のままなので、処理がすぐに終了してしまいます。

最後にボタンを押したことが分かるSEを鳴らしておくと、操作感も良くなります。

5-5. 2ページ目へ処理をコピーする

作成した処理は、ボタンイベントの2ページ目にもコピーします。

2ページ目の出現条件は、ボタン番号に対応する通常スイッチです。ボタン1ならスイッチ「1」がONのときに赤い画像を表示します。

1ページ目と2ページ目の両方に同じ反転処理が必要です。2ページ目が空だと、一度ONにしたボタンをもう一度押してOFFへ戻せません。

ボタン1が完成したら8個複製し、2ページ目の出現条件だけをスイッチ「2」から「9」へ変更します。

5-6. テストプレイする

中央を押したときは十字型に5マス、角を押したときは3マス、端を押したときは4マスが反転すれば成功です。

テストプレイで押したマスと上下左右が反転した画面

次の短いアニメでは、押した結果が連動して変わる様子を確認できます。

ライツアウトのボタンを押すと周囲が反転するアニメ

テスト時はF9キーで変数「点灯数」も確認しましょう。赤いマスの数と変数の値が一致していれば、ON/OFF処理が正しく組めています。

6. リセットレバーを作る

リセットレバーでは次の2つを実行します。

  1. 変数「点灯数」に0を代入
  2. 9マスに対応する通常スイッチをすべてOFF
点灯数を0にして9つのスイッチをOFFにするリセット処理

リセットは必須ではありませんが、初期配置によっては解法が分からなくなるプレイヤーもいます。パズルの近くに「リセットする/やめる」の選択肢を置いておくと親切です。

7. JavaScriptでライツアウトを作る方法

スクリプト版では、通常スイッチ9個と座標計算用の変数4個が不要です。

必要なのは次の2つだけです。

  • 点灯数を入れる変数1個
  • 各ボタンのセルフスイッチA

7-1. ボタンのメモ欄へタグを入れる

ライツアウトの対象にする9個のボタンすべてで、メモ欄に次のタグを入力します。

<LightsOut>
メモ欄のLightsOutタグと上下左右の座標配列

このタグがあるイベントだけをスクリプトの対象にするため、同じ座標の近くに別のイベントがあっても誤操作しにくくなります。

7-2. ボタンイベントへ反転スクリプトを入れる

イベントコマンド3ページ目の「上級」から「スクリプト」を選び、次のコードを貼り付けます。

const me = $gameMap.event(this._eventId);

if (me) {
    // 自分+上下左右
    const dirs = [
        [0, 0],  // 自分
        [0, -1], // 上
        [1, 0],  // 右
        [0, 1],  // 下
        [-1, 0]  // 左
    ];

    for (const [dx, dy] of dirs) {
        const x = $gameMap.roundX(me.x + dx);
        const y = $gameMap.roundY(me.y + dy);

        const events = $gameMap.eventsXy(x, y);

        for (const ev of events) {
            // <LightsOut> がないイベントは無視
            const note = ev.event().note || "";
            if (!note.includes("<LightsOut>")) continue;

            const key = [$gameMap.mapId(), ev.eventId(), "A"];
            const isOn = $gameSelfSwitches.value(key);

            // Aを反転
            $gameSelfSwitches.setValue(key, !isOn);

            // ON数を変数1で管理
            const value = $gameVariables.value(1);
            $gameVariables.setValue(
                1,
                value + (isOn ? -1 : 1)
            );
        }
    }
}
セルフスイッチAの反転と点灯数の増減を行うスクリプト

このコードは変数ID1を「点灯数」として使っています。別の変数IDを使う場合は、$gameVariables.value(1)setValue の第1引数にある 1 を、実際の変数IDへ変更してください。

ボタンイベントは2ページ構成にします。

  • 1ページ目:OFF画像。スクリプトの後でセルフスイッチAをON
  • 2ページ目:出現条件をセルフスイッチAにしてON画像。スクリプトの後でセルフスイッチAをOFF

両ページのプライオリティは「通常キャラの下」、トリガーは「決定ボタン」にします。ゴールイベントの作り方はイベントコマンド版と同じです。

8. スクリプト版のリセット処理

スクリプト版では、別イベントのセルフスイッチをイベントコマンドだけでまとめてOFFにできません。そのため、リセットレバーには次のコードを入れます。

for (const ev of $gameMap.events()) {
    // メモ欄に <LightsOut> があるイベントだけ対象
    if (ev.event().meta.LightsOut !== undefined) {
        const key = [$gameMap.mapId(), ev.eventId(), "A"];
        $gameSelfSwitches.setValue(key, false);
    }
}

// 点灯数も0に戻す
$gameVariables.setValue(1, 0);
LightsOutタグ付きイベントのセルフスイッチAをOFFにするリセットコード

ここでも、点灯数に使っている変数IDが1以外なら、最後のsetValue(1, 0)を変更してください。

9. うまく動かないときのチェックリスト

押したマスの上を歩けない

ボタンイベントのプライオリティを「通常キャラの下」にします。

ONにはなるがOFFへ戻せない

イベントの2ページ目にも、1ページ目と同じ反転処理が入っているか確認します。

違うマスが反転する

イベントコマンド版では、イベントIDと通常スイッチの対応を確認します。ID5の条件分岐なら、確認・ON・OFFするスイッチもすべて「5」です。

数回押すと反応しなくなる

ループ終了後に変数「ループ」を0へ戻しているか確認します。

見た目の点灯数と変数が合わない

ONにするときは点灯数を1加算、OFFにするときは1減算です。どちらかの符号が逆になっていないか確認してください。

スクリプト版で一部のマスだけ反応しない

反応しないイベントのメモ欄に<LightsOut>が入っているか確認します。全角の山括弧やスペル違いにも注意してください。

まとめ

RPGツクールMZでライツアウトを作るポイントは次のとおりです。

  • 押したマスと上下左右の状態を反転する
  • ONの総数を変数「点灯数」で管理する
  • 点灯数が9以上になったらゴールの扉を開く
  • イベントコマンド版は、X/Y座標とイベントIDを使って対象マスを探す
  • ループを0から4まで回し、自分・左・右・上・下の5マスを判定する
  • スクリプト版は<LightsOut>タグとセルフスイッチAで管理する
  • プレイヤーがやり直せるリセット処理を用意する

仕組みを一度作ってしまえば、4×4や5×5へ広げたり、色ではなく床・石像・照明のON/OFFへ置き換えたりできます。

まずは3×3で完成させ、点灯数と各マスの状態がずれないことを確認してから、自分のゲームに合う見た目や演出へ変えてみてください。

SNSのネタにどうぞ

作者

ゲーム作ってる人。主にRPGツクールでのゲーム制作に役立つスキルを発信している

座右の銘:インドカレー
将来の夢:インドカレーになること

チャプター