「涼宮ハルヒの憂鬱キャラセリフかるた集」読み上げソフトをPi STARTERで作っちゃいました!
新年早々に緊急事態宣言とか出ちゃいました。ここはひとつステイホームで遊びますかねっ!
ということで我が国を代表する新年のアナログゲームと言えばかるた取り。
我が家は(互いに趣向は違えども)一家全員がアニメファンなので、こんなカルタで遊んでいます。
この製品は「涼宮ハルヒの憂鬱」のアニメ制作会社である京都アニメーションがリリースしているもので、同作品のセリフ100種類をかるたカードにし、さらにアニメシーンそのままのボイスをCD読み上げにしているという(私のような)ファンにはたまらない逸品。
…なのですが、この手の製品の常として、
・CDボイスを有効に使うためにはランダム再生できる機器が必要
・そしてそれは誰かが操作しなきゃならない
・操作者はスタート/ストップ/もう1回再生などに対応しなきゃならず、その操作がかなり煩雑になりがち
・ランダム再生とはいえ同じ札が何度も読まれるのは避けられない
(機器によってはそうじゃないのもあるかもしれないけど)
といった数々の問題があって、実際機器の操作をしながら遊んだ私は家族で一番ハルヒに詳しいにもかかわらずボロ負けでした(泣)。
(↓↓ ハルヒについてより詳しく知りたい方はこちらも見てね ↓↓)
なんとかなんないかなーと思いつつこの手のアプリとか検索してみたけど、そういうピンポイントな要望に応えるのってなかなかないんだよね。
…ん、まてよ?
このくらいだったらプログラミングで作れちゃうんじゃね?
ふとひらめいた私は脳内で簡単なフローチャートを書いてみる。
(あれがこーなって、この処理はこうして…あとはPi STARTERで音源さえ再生できれば…)
できるっ!!
そうと決まれば善は急げ。
お正月期間中に遊べるようにLet's プログラミングだっ!
(お正月期間とはいったいいつまでなのか)
要件定義:
・キーを押すと100種類ある音声ファイルをランダムで再生する
・その際に1度再生したファイルは除外すること
・100種類すべてを再生し終えたら終了する
・入力待ち時、直前に再生したファイルの繰り返し再生に対応する
まぁ最低限こんなとこかな。
ということで久々に出動ですPi STARTER!
(他の言語でも良かったんですが、何せ思いついてすぐに作り始めたので、自分が一番わかるやつでとりあえずやってみることにしました)
Pi STARTERって何?という方はこちらをどうぞ。
(ひとことで言うと、ラズベリーパイでSmile BASICという言語を使えるようにしたパッケージです)
ここからはコード交じりで説明しますね。
Pi STARTERのSmile BASIC場合、音声は「.ogg」という形式になっていれば再生可能とのこと。それをユーザー定義用の曲番号(128~255)に振り分けていくんだって。
'おんせい ナンバリング
BGMSETF 128,"/HARUHI/HARUHI_SOUND/T01.ogg"
BGMSETF 131,"/HARUHI/HARUHI_SOUND/H01.ogg"
BGMSETF 132,"/HARUHI/HARUHI_SOUND/H02.ogg"
BGMSETF 133,"/HARUHI/HARUHI_SOUND/H03.ogg"
ちなみにこの「BGMSETF」にあたる命令はSmileBASICの本家であるプチコンには搭載されていない模様(3号で確認)。やっぱりそうか、あれはPCからデータ持ち込ませない作りになってるからなー。こういうときはラズパイで良かったと思うよ本当にっ!
札をめくるアクションはモチのロン、RND関数を使うのです。
1から100を無作為に選ぶサイコロです。
(下のコードで+1してるのは、そのままだと0~99になっちゃうから)
'ふだ を めくる
@DRAW
X=RND(100)+1
んで札を読むのは「BGMPLAY」文で。
'ふだ を よむ
@CALL
IF X==1 AND CARD[1]==0 THEN
BGMPLAY 0,131,127
GOSUB @PLAY
CARD[1]=1
ENDIF
ところで、今回の要件定義には「1度再生したファイルは除外する」というのがあります。これを実現するため、変数としてDIM文で「CARD[●]」という入れ物をCARD[1]~CARD[100]まで用意しました。
(DIM文は0からカウントするため、1~100の入れ物が欲しいときは「101」としておき、CARD[0]は使用しないことにしています)
'よみふだ チェックよう へんすう
DIM CARD[101]
CARD[1]~CARD[100]の変数はどう使っているかというと、中身が「0」なら未読、中身が「1」なら既読としています。
そして読み上げる際にこの条件分岐を通しています。
IF X==1 AND CARD[1]==0 THEN
これは何をやっているかというと、RND関数(サイコロ)で出た値(X)が未読(0)か、それとも既読(1)かを判断し、既読なら読まずにスルーする(シャレじゃないよ!)処理を入れています。
これを札100枚分繰り返し、最後まで行って何も読まなれてなかったらまたサイコロを振るところに戻ってやり直すってわけ。こうすれば既読の札をはねて未読の札だけ読むランダム再生が成り立つわけです。
もっと要領のいいやり方あるかも知れませんが、私はこのやり方しかすぐに思いつきませんでした…。
札を読んだ後は、「次の札を読む」/「いまの札を繰り返し再生する」の選択をさせなくてはなりません。
これは次のようなコードで行ないました。
@PLAY'(中略。要件定義にはありませんが、キャラ画像を出す処理を入れています)
K$=INKEY$()
IF K$==CHR$(29) OR K$==CHR$(30) OR K$==CHR$(32) THEN @CALL
IF K$==CHR$(28) OR K$==CHR$(31) OR K$==CHR$(13) THEN
SUM=SUM+1
IF SUM>99 THEN RETURN
LOCATE 0,5
COLOR RGB(0,255,0)
PRINT SUM+1;" まいめ"
COLOR RGB(255,255,255)
RETURN
ENDIF
GOTO @PLAY
このへんはざっといきます。
K$=INKEY$()っていうのは、カーソルキーやスペースキー、エンターキーによる入力を読み取るのに使っており、ここで何が押されたかで「@CALL」に飛ぶ(繰り返し再生)か、「RETURN」で元の位置に戻って処理続行(次の札を読む)かを決めています。
なお「SUM」という変数で何枚読まれたかをカウントしており、SUMの値が100を越えたらゲームが終わるようにしています。
'すべて の ふだ を めくった?
IF SUM==100 THEN
LOAD"GRP0:/HARUHI/HARUHI_GRP/HARUHIKARUTA.png"
LOCATE 0,19
PRINT "これにて ゲーム しゅうりょう"
PRINT "おつかれさま でした"
END
ENDIF
プログラムの根幹としてはこれだけです。
あとは作っていくうちに例によって止まらなくなり(笑)、画面レイアウトを整えたりキャラ画像を入れたりしています。
(著作権って何だろう…)
最終的に出来上がった成果物はこんな感じ。
登場人物である谷口によるのゲーム説明やラズパイの音声出力切り替えまで実装しました。
ちなみにこの製品のかるたカードボイス内訳は、
・涼宮ハルヒ(声:平野綾)23枚
・キョン(声:杉田智和)25枚
・ハルヒ&キョン 1枚
・長門有希(声:茅原実里)17枚
・朝比奈みくる(声:後藤邑子)18枚
・古泉一樹(声:小野大輔)18枚
で合計100枚となっているのですが、CDは機能上99トラックまでしか持てないうえに、CD内には谷口(声:白石稔)による説明トラックもあるため、3トラック分に何と2つの声が入っていたりします。これ機器で操作してたら止めるの無理ゲーやん!
ということで、おうちで個人的に遊びたいだけのために作っちゃったこのプログラム。ソースコードだけは興味ある方(いないと思いますが)のためにダウンロードできるようにしておきますが、使用した音声や画像は著作権に配慮して禁則事項とさせていただきますので、そこのところご理解願います(つまるところ入手しても一切遊べませんので、あくまで参考です)。
涼宮ハルヒの憂鬱キャラセリフかるた読み上げソフト
ソースコードのみ、ダウンロードはこちらから
http://www.ne.jp/asahi/chitose/net/download/haruhi/HARUHI
いかがでしょうかPi STARTERによるプログラミング。
こういうのが私みたいなド素人でも思い付きでちゃちゃっと作れちゃうんですから、Pi STARTERマジでおすすめですよ!
当方も過去にこんなの作っています。
Pi STARTER持っている方はよろしければぜひ!
Pi STARTER(ラズベリーパイ用BASIC言語パッケージ)版
ひとりで遊べるゲームシリーズ
人狼ゲーム&ガイスターを公開中(要ラズパイ&Pi STARTER)
http://www.ne.jp/asahi/chitose/net/download/
ということでPi STARTERへの愛を語りつつ今日はこの辺でおひらきに。
…え?Pi STARTERでの新作いつ作るのかって?
それはどの時間平面における話でしたでしょうかね?