memo

ゲーム制作やデザインについての個人的メモ

【お知らせ】

おばけくんをひたすらクリックするだけのゲーム「おばけアタック!」を公開しました。
ティラノゲームフェス2017にも参加しています。1プレイ30秒程度なのでお気軽にプレイしてみてください!
プレイ&ダウンロードページ→http://novelgame.jp/games/show/508?fes=1

【ティラノスクリプト】タイプライター風に文字を表示するマクロ

DEMO(タイプライター風テストを選択/※効果音が鳴るので注意)

効果音素材配布元:On-Jin ~音人~http://on-jin.com/)様

自分が欲しいのでつくってみたシリーズ。正確にはタイプライターのように一文字ずつ音を出すためのマクロですね。

①気軽にやる

短い単語にしか使わないとか、一か所しか使わないということであれば、単純に一文字ごとに効果音を入れればそれっぽくなります。かなり力技ですが難しいことはなにもありません。

[macro name="key"]
[playse storage="key.ogg"]
[wait time="200"]
[endmacro]

タ[key]イ[key]プ[key]ラ[key]イ[key]タ[key]ー[key]風[key]に[key]文[key]字[key]を[key]表[key]示[key]す[key]る[key]よ[key]。[key]

②ちょっと工夫する

前述の方法だと一文字ごとにマクロを入れなきゃいけないし、細かい指定もできないし、おまけにバックログを見ると一文字ごとに改行されてるしであまり使い勝手が良くありません。

そこでちょっと工夫してマクロをつくってみました。

[macro name="key_type"]

[glyph fix=true top=-100]

*loop
[eval exp="mp.text_count = 0" cond="mp.text_count == null"]

[eval exp="moji = mp.text[mp.text_count]"]

[if exp="moji == '、' || moji == '。' || moji == '!' || moji == '?'"]
[eval exp="mp.volume = 100"]
[else]
[eval exp="mp.volume = Math.floor(Math.random() * 21 + 30)"]
[endif]
[playse storage="key.ogg" volume="&mp.volume"]

[glyph cond="mp.text_count == mp.text.length - 1"]
[emb exp="moji"]

[iscript]
tf.system.backlog.pop();
[endscript]

[if exp="moji == '。' || moji == '!' || moji == '?'"]
[eval exp="mp.wait = 800"]
[elsif exp="moji == '、'"]
[eval exp="mp.wait = 600"]
[else]
[eval exp="mp.wait = Math.floor(Math.random() * 201 + 200)"]
[endif]
[wait time="&mp.wait"]

[eval exp="mp.text_count = mp.text_count + 1"]
[jump target=*loop cond="mp.text_count < mp.text.length"]

[iscript]
TG.pushBackLog(mp.text);
[endscript]

[endmacro]

[key_type text="タイプライター風に文字を表示するよ。"]

わかりにくい感じになってしまったので上からひとつずつ解説していきます。

[glyph fix=true top=-100]

そのままだとクリック待ち画像が一文字ごとに表示されてしまうので、最後の文字まではクリック待ち画像が見えないように画面の外へ放り出してます。-100の数値は見えない位置ならなんでもいいです。

*loop

処理をループさせるためのラベルです。(ところでマクロ内でラベルって使ってもいいんですかね…?あまり見かけないので不安になってきました…。callでサブルーチン呼び出した方がいい?)

[eval exp="mp.text_count = 0" cond="mp.text_count == null"]

一番最初だけmp.text_countというローカル変数に0を代入しています。この数字が文字列の配列と対応しています。(mp.text_countが0ならmp.text[0]の文字を表示する)

[eval exp="moji = mp.text[mp.text_count]"]

mp.text[mp.text_count]は現在表示される文字です。なんだかごちゃっとしてるので見やすいようmojiという変数に代入して使います。

[if exp="moji == '、' || moji == '。' || moji == '!' || moji == '?'"]
[eval exp="mp.volume = 100"]
[else]
[eval exp="mp.volume = Math.floor(Math.random() * 21 + 30)"]
[endif]
[playse storage="key.ogg" volume="&mp.volume"]

ここで効果音を鳴らしています。句読点と!と?の部分は音量を100に、その他の部分は音量を30~50の間でランダムに設定しています。音量に差をつけるとリアルさとリズム感が出ていいかな~と思ったのですが、ここは好みの問題ですね。単純に[playse]だけでもいいと思います。

[glyph cond="mp.text_count == mp.text.length - 1"]
[emb exp="moji"]

ここで実際に文字を表示させています。[glyph]は最後の文字を表示するときだけクリック待ち画像をデフォルト設定に戻す(見えるようにする)ために記述しています。最後までクリック待ち画像を表示させない場合は[glyph]をまるっと削除して、別の場所(通常の文章に戻る場所)で[glyph]を置いておけばOKです。

[iscript]
tf.system.backlog.pop();
[endscript]

このまま文字を表示していくとバックログで表示したときに一文字ずつ改行されてしまうので、一度文字をバックログから削除しています。後で文章ごとまとめて収納します。

[if exp="moji == '。' || moji == '!' || moji == '?'"]
[eval exp="mp.wait = 800"]
[elsif exp="moji == '、'"]
[eval exp="mp.wait = 600"]
[else]
[eval exp="mp.wait = Math.floor(Math.random() * 201 + 200)"]
[endif]
[wait time="&mp.wait"]

次の文字を表示するまでの待ち時間です。文字が句点と!と?の場合は800、読点の場合は600、その他の場合は200~400の間でランダムに設定しています。こちらも効果音の音量と同じくメリハリをつけるため多少大げさに差をつけていますが、お好みで変更してください。[wait]のみでもいいと思います。

[eval exp="mp.text_count = mp.text_count + 1"]

次の文字を表示させるためにmp.text_countに1を足しています。

[jump target=*loop cond="mp.text_count < mp.text.length"]

mp.text_countが文章の文字数と同じになるまで*loopにジャンプして処理をループさせています。

[iscript]
TG.pushBackLog(mp.text);
[endscript]

最後に文章をまとめてバックログに収納しています。

で、実際にマクロを使用するときは

[key_type text="タイプライター風に文字を表示するよ。"]

これだけでいいので楽ですね。

うーん、改めてみるとちょっと詰め込み過ぎた感がありますね…。適宜削ってご利用ください。なんか間違ってたら優しく教えていただけるととってもありがたいです。このマクロを使えばレトロゲーム風に一文字ずつ音も出せるけど、常時使うには処理の重さとか気になるところもあるので、やっぱりアクセント的に時々使う感じが良いと思います。

実は私、今までmpのことをよくわかってなかったのですが、調べたりしてるうちにちょっとだけ仲良くなれました。すごいぜmp。何気に万能だぜmp。