Edited at

"ティラノスクリプト"のラベル・ジャンプ操作をStateGoで省力化する


はじめに

本投稿は、詳解「StateGoの"ティラノスクリプト"サンプル動作と変更事例」の続きになります。

ティラノスクリプトを使う上で面倒で苦労する『ラベル・ジャンプ操作系命令』について、StateGoで簡単に記述する方法を説明します。

本投稿の題目は以下の通りです。


ティラノスクリプトのラベル・ジャンプ操作系命令について

ノベルゲームにおける選択肢は必須の機能です。

そして、最も使用頻度が高い命令です。

ティラノスクリプトでは、選択肢に使用される命令を『ラベル・ジャンプ操作系命令』と呼んでいます。

以下は命令一覧になります。


ティラノスクリプトのラベル・ジャンプ操作系命令一覧

命令
内容
詳細

link
文字列を選択可へ&クリック時ラベルへ遷移
https://tyrano.jp/tag/#link

glink
ボタン表示し選択可へ&クリック時ラベルへ遷移
https://tyrano.jp/tag/#glink

button
画像ファイルを表示し選択可へ&クリック時ラベルへ遷移
https://tyrano.jp/tag/#button

clickable
クリック可能領域を指定&クリック時ラベルへ遷移
https://tyrano.jp/tag/#clickable

記述の一番シンプルなのがlink命令で、公式サイトでは次のサンプルコードが掲げてあります。


公式サイトでのlinkの実装例

選択肢を表示します[l][r][r]

[link target=*select1]【1】選択肢 その1[endlink][r] <color=red>s</red>
[link target=*select2]【2】選択肢 その2[endlink][r]

[s]

*select1
[cm]
「選択肢1」がクリックされました[l]
@jump target=*common

*select2
[cm]
「選択肢2」がクリックされました[l]
@jump target=*common

*common
[cm]

共通ルートです

上記サンプルの ラベル・ジャンプ命令実装は以下のように行われています。

【1】linkの記述


  • [link]命令内にクリック時のジャンプ先ラベルをtargetにて指定

  • テキストを記述

  • link命令の終了用のタグ[endlink]を追加

【2】ジャンプ先ラベルの記述


  • 先の[link]命令で指定したラベルを宣言

  • 処理を記述

  • 次のラベルへジャンプ

選択肢を追加するたびに上記の【1】と【2】を記述していきます。

なかなか面倒な記述です。

link命令はパラメータがジャンプ先ラベルの指定だけでしたが、他の命令(glinkbuttonclickable)ではさらに多数のパラメータを設定する必要があります。

もちろんティラノスクリプトにも、引数によるサブルーチンコールやマクロが用意されており、省力化を図ることが出来ます。

それでも、アセンブラに似たラベル式の記述はミスを誘引しやすく、大変面倒です。


StateGo"ティラノスクリプト"サンプルによるラベル・ジャンプ操作系の命令について

翻って、StateGo"ティラノスクリプト"サンプルではラベル・ジャンプ操作系命令と同じ名前の(テーブル内の)該当項目に必要なパラメータを記述するだけです。

たとえば、S_MUSICステート(クリックでステートの場所確認可)のlink命令は、下図のように【link】項目に記入します。

link命令のフォーマットは以下の通りです。


識別ID,"テキスト",【オプション】(例:[r])

S_MUSICでは、以下のように設定してあります。


play,"【1】うん。再生してください",[r]
noplay,"【2】いや。今は再生しないで!"

1行が一つの選択肢に対応しており、サンプルは2つの選択肢をもちます。

そしてStateGoでは、先に説明にした【1】と【2】の部分を自動で実装します。

次にそれぞれの変換について説明します。


link命令へ自動変換・・・【1】に相当

ジャンプ先ラベルはステート名とID識別子から生成して、他のパラメータから以下のように出力されます。


出力:



[link target="S_MUSIC___linklabel_play"] 【1】うん。再生してください [endlink] [r]


ジャンプ先ラベル処理を自動出力・・・【2】に相当

ジャンプ先ラベル処理では、link命令用に用意された f.lnkValにID識別子をセットします。

その後、ステートの分岐命令先頭ラベルへジャンプします。


出力:



*S_MUSIC___linklabel_play
[iscript]
f.lnkval = 'play';
[endscript]
[jump target="S_MUSIC___branch"]


ステートの分岐編集について

ジャンプ先ラベル処理にて、ID識別子を変数に格納しました。

その変数とID識別子を比較することでステートの分岐部分を作成します。

S_MUSICステートのクリックメニューより、分岐編集を選択し、link用のID格納変数 'f.glnkval'と識別IDの比較の分岐を用意します。

サンプルでは、以下のように分岐の遷移先が決定しています。


  • f.glnkval=='play'時はS_PLAYMUSICへ

  • f.glnkval=='noplay'時はS_PLAYMUSICへ


変換結果

最終的に、S_MUSICのデータは以下のように変換されます。


;------------------------------
; S_MUSIC
;
*S_MUSIC
[iscript]
f.curstate = 'S_MUSIC';
f.nextstate ='';
f.yesno=0;
[endscript]
[iscript]
f.lnkval='';
[endscript]
[link target="S_MUSIC___linklabel_play"] 【1】うん。再生してください [endlink] [r]
[link target="S_MUSIC___linklabel_noplay"] 【2】いや。今は再生しないで! [endlink]
[s]
*S_MUSIC___branch
;
; BRANCH
;
[iscript]
if ( f.lnkval == 'play' ) { f.nextstate='S_PLAYMUSIC'; }
else if ( f.lnkval == 'noplay' ) { f.nextstate='S_NOPLAYMUSIC'; }
[endscript]
[jump target=&f.nextstate]
;
; LINK LABEL
;
*S_MUSIC___linklabel_play
[iscript]
f.lnkval = 'play';
[endscript]
[jump target="S_MUSIC___branch"]
*S_MUSIC___linklabel_noplay
[iscript]
f.lnkval = 'noplay';
[endscript]
[jump target="S_MUSIC___branch"]
;
; END OF S_MUSIC
;


 実行

S_MUSICステートの実行は以下のようになります。

(クリックでGIF再生)




まとめ

ティラノスクリプトのラベル・ジャンプ操作系命令を、StateGoの機能により必要最低限の記述にて実装することが出来ます。

遷移先はGUIで決定されるため、ソースエディタ上でのラベル操作の必要がありません。


変更事例

新規選択肢を作成する様子を動画にしました。

動画-youtube

実行-gif


【資料1】StateGo"ティラノスクリプト"サンプルのラベル・ジャンプ操作系命令仕様


テーブル項目

ラベル・ジャンプ操作系命令のフォーマットと格納変数、および、サンプルでの実装箇所となります。

テーブル項目
フォーマット
変数
サンプルでの実装箇所

link
識別ID,"テキスト",【オプション】(例:[r])
f.lnkval
/MUSIC/S_MUSIC

glink
X座標,Y座標,幅,フォントサイズ,識別ID,テキスト
f.glkval
/S_QUESTION
/BTNLINK/S_BTNLINK1

button
X座標,Y座標,画像ファイル,識別ID
f.butval
/S_TITLE

clickable
X座標,Y座標,幅,高さ,識別ID
f.clkval
該当なし


【資料2】glinkの実装サンプル

実装箇所: /S_QUESTION


入力



init.

#あかね

もしかして、ノベルゲームの開発に興味があるの?[p]


glink.

260,100,400,20,YES,"はい。興味あります"

260,170,400,20,OFCOUSE,"興味あります!"
260,240,400,20,MAYBE,"どちらかと言うと興味あり"


wait.

[s]




変換結果



;------------------------------
; S_QUESTION
;
*S_QUESTION
[iscript]
f.curstate = 'S_QUESTION';
f.nextstate ='';
f.yesno=0;
[endscript]
#あかね
もしかして、ノベルゲームの開発に興味があるの?[p]
[iscript]
f.glkval='';
[endscript]
[glink color="blue" x=260 y=100 width=400 size=20 target="S_QUESTION___glinklabel_YES" text="はい。興味あります" ]
[glink color="blue" x=260 y=170 width=400 size=20 target="S_QUESTION___glinklabel_OFCOUSE" text="興味あります!" ]
[glink color="blue" x=260 y=240 width=400 size=20 target="S_QUESTION___glinklabel_MAYBE" text="どちらかと言うと興味あり" ]
[s]
*S_QUESTION___branch
;
; BRANCH
;
[iscript]
if ( f.glkval == 'YES' ) { f.nextstate='S_INTREST'; }
else if ( f.glkval == 'OFCOUSE' ) { f.nextstate='S_INTREST'; }
else if ( f.glkval == 'MAYBE' ) { f.nextstate='S_INTREST'; }
[endscript]
[jump target=&f.nextstate]
;
; GLINK LABEL
;
*S_QUESTION___glinklabel_YES
[iscript]
f.glkval = 'YES';
[endscript]
[jump target="S_QUESTION___branch"]
*S_QUESTION___glinklabel_OFCOUSE
[iscript]
f.glkval = 'OFCOUSE';
[endscript]
[jump target="S_QUESTION___branch"]
*S_QUESTION___glinklabel_MAYBE
[iscript]
f.glkval = 'MAYBE';
[endscript]
[jump target="S_QUESTION___branch"]
;
; END OF S_QUESTION
;


【資料3】buttonの実装サンプル

実装箇所 : /S_TITLE


入力

テーブルのbuttonの項目に、フォーマットに従い以下を記述します。



button.

100,250,title/button_start.png,START


規定外の記述については、prewaitに直書きします。


prewait.

[button x=100 y=320 graphic="title/button_load.png"  role="load" ]

[button x=100 y=390 graphic="title/button_cg.png" storage="cg.ks" ]
[button x=100 y=460 graphic="title/button_replay.png" storage="replay.ks" ]
[button x=100 y=530 graphic="title/button_config.png" role="sleepgame" storage="config.ks" ]


wait.

[s]




変換結果



;------------------------------
; S_TITLE
; タイトル表示
*S_TITLE
[iscript]
f.curstate = 'S_TITLE';
f.nextstate ='';
f.yesno=0;
[endscript]
@bg storage="title.jpg"
[iscript]
f.butval='';
[endscript]
[button x=100 y=250 graphic="title/button_start.png" target="S_TITLE___buttonlabel_START"]
[button x=100 y=320 graphic="title/button_load.png" role="load" ]
[button x=100 y=390 graphic="title/button_cg.png" storage="cg.ks" ]
[button x=100 y=460 graphic="title/button_replay.png" storage="replay.ks" ]
[button x=100 y=530 graphic="title/button_config.png" role="sleepgame" storage="config.ks" ]
[s]
*S_TITLE___branch
;
; BRANCH
;
[iscript]
if ( f.butval == 'START' ) { f.nextstate='S_SCENE_1'; }
[endscript]
[jump target=&f.nextstate]
;
; BUTTON LABEL
;
*S_TITLE___buttonlabel_START
[iscript]
f.butval = 'START'
[endscript]
[jump target="S_TITLE___branch"]
;
; END OF S_TITLE
;

以上