ボタンと条件分岐

ノベルゲームでは、プレイヤーの選択やフラグの状態に応じてシナリオを分岐させることがあります。

Ponkanで分岐処理を実現する方法は2通りあります。

  • ボタンを利用する方法
  • 変数(JavaScript)の値によって分岐する方法
  • ifコマンド
  • condパラメータ

ボタンによる分岐

ボタンを押下したときに 任意のシナリオの位置へジャンプさせたり、 サブルーチンを呼び出すことができます。 また、押下時に任意のJavaScriptを実行することもできます。

ボタンには、

-テキストと背景色のみ指定できる「テキストボタン」 -画像を用いて自由に作成できる「画像ボタン」

の2種類があり、 それぞれtextbuttonコマンドと imagebuttonコマンドで表示できます。

テキストボタンの表示

以下のスクリプトは、画面に「テキストボタンのサンプル」というボタンを表示する例です。

;textbutton {
  lay: 0,
  text: "テキストボタンのサンプル",
  x: 100,
  y: 100,
  width: 500,
  height: 40,
  bgcolors: [0x33B6FF, 0x3D82FF ,0x474FFF],
  bgalphas: [1.0, 1.0, 1.0],
  align: "center",
  onclick: "console.log('テキストボタンを押した')",
  jump: true,
  file: "jump_target_file.pon",
  label: "onclick_textbutton",
}
;unlockbuttons
;s

ボタンを表示した直後は、まだボタンを押すことはできません。 unlockbuttons コマンドを実行して、初めてボタンが押下可能になります。 また、ボタンが押されるのを待っているときはスクリプトを停止しておくべきなので、 必ず s コマンドを書くようにしてください。

この例ではjumpfilelabelパラメータを指定しているので、 fileで指定したスクリプトのlabelの位置へジャンプします。 もしjump: trueではなくcall: trueとパラメータを指定していたら、サブルーチンとして呼び出します。 また、jumpコマンドやcallコマンドと同じように、ファイル名やラベル名を省略することもできます。

onclickパラメータは、ボタン押下時に実行するJavaScriptです。 この場合はコンソールに「テキストボタンを押した」と出力されます。

画像ボタンの表示

以下のスクリプトは、画面に画像ボタンを表示する例です。

;imagebutton {
  lay: 0,
  imagefile: "image/image_button.png",
  direction: "horizontal",
  x: 100,
  y: 100,
  onclick: "console.log('画像ボタンを押した!')",
  call: true,
  file: "call_target_file.pon",
  label: "onclick_imagebutton",
}

画像ボタンでは、ボタンとして表示するための画像ファイルが必要です。 ボタン用の画像は、「通常時」「マウスオーバー時」「マウス押下時」を並べた一枚画像にします。 たとえば次のような画像です。あくまでも一枚の画像であることに注意してください。

ボタン画像の例

横に並べると見づらい場合は、縦方向に並べた画像にして、 directionパラメータにverticalを指定してください。

ボタン画像の例2

;imagebutton {
  lay: 0,
  imagefile: "image/image_button.png",
  direction: "vertical",
  x: 100,
  y: 100,
  call: true,
  label: "onclick_imagebutton",
}

変数(JavaScript)による分岐

ifコマンドは、指定したJavaScriptの評価結果がtrueの場合のみ、 endifコマンドまでの間を実行します。

以下の例では、tv.scenarioNumの値が1なので「現在はシナリオ1です。」と表示されます。

- tv.scenarioNum = 1;

;if exp: "tv.scenarioNum == 1"
  現在はシナリオ1です。
;endif

結果がfalseの場合にも処理を実行したい場合は、elseコマンドを使用してください。

以下の例では、tv.scenarioNumの値が2なので「シナリオ1ではありません。」と表示されます。

- tv.scenarioNum = 2;

;if exp: "tv.scenarioNum == 1"
  現在はシナリオ1です。
;else
  シナリオ1ではありません。
;endif

結果がfalseのとき、さらに追加の条件で判定したいときは、 elsifコマンドを使用してください。

以下の例では、tv.scenarioNumの値が3なので「シナリオ1ではなくて、シナリオ3ですね。」と表示されます。

- tv.scenarioNum = 3;

;if exp: "tv.scenarioNum == 1"
  現在はシナリオ1です。
;elsif exp: "tv.scenarioNum == 3"
  シナリオ1ではなくて、シナリオ3ですね。
;else
  シナリオ1でも、シナリオ3でもありません。
;endif

条件式に任意のJavaScriptを使う

ここまでの例ではifelsifの条件に変数を使ってきましたが、 条件式は任意のJavaScriptが記述できますので、以下の例のようなことも可能です。 (あくまで例なので、あまり意味のある処理にはなっていないことに注意。)

- tv.scenarioNum = 4;

---
tv.randomJudge = function() {
  if (tv.scenarioNum != 4) {
    return false;
  } else {
    return Math.random() < 0.5;
  }
};
---

;if exp: "tv.randomJudge()"
  君は運がいい。
;endif

condパラメータ

一つのコマンドに対してだけ条件分岐を行いたいときは、condパラメータを使用すると良いでしょう。

すべてのコマンドにはcondパラメータが用意されています。 コマンドの実行前にパラメータがJavaScriptとして実行され、値がtrueの場合のみ、コマンドが実行されます。 falseだったときは、コマンドを実行しません。

# すべてのシナリオをクリアしていたら、true_ending.ponへジャンプする。
# まだクリアしていなかったら、このままスクリプトを続行する。
;jump file: "true_ending.pon", cond: "sv.all_clear"

ifコマンドよりも簡単に記述できるので、 複数のコマンドをまとめて制御したいときはifコマンド、 単一のコマンドを制御するときはcondパラメータ、という風に使い分けると良いでしょう。