目パチ口パク用サンプルプロジェクト

注意:このサンプルはかなり古くやっつけなものなので、お気を付けください。

他の方が配布されているプラグインの方が分かりやすいので、そちらのご利用を推奨します。リンクは下記。

目パチ・口パクプラグイン

俺たちのギャルゲ」で作った目パチと口パク機能を、あかねちゃんにやってもらいました。あかねちゃん画像以外は改造再配布自由のプロジェクトです。目パチ・口パク部分はやっつけがひどいので誰にでも使っていただけるというものではありませんが、こういうやり方もできるという感じで見ていただけますと幸いです。

ver.4.61(2018/01/29更新)

ゲームのデータ(zipファイル)

サンプルプロジェクト内でもあかねちゃんに説明してもらっていますが、それにまとめる前に長々と書いた話が以下になります。細かいです。

この目パチ口パクアニメは、CSSアニメをもったクラスをつけ外しすることで実装しました。アニメ自体はスプライト画像を利用したCSSのstepアニメーションですね。なぜそうしたかというと、「一枚の画像(連結)で済む」「処理が軽そう」という理由です。こちらのティラノスクリプトのbuttonタグのホバー画像仕様は、吉里吉里と違ってメモリを消費するという記事などから、新たに画像を表示するよりは連結画像の方が負荷が軽いのかなーと。jQueryでDOM操作やってるんでこの辺どうなんだという感じもしないでもないですが、描画負荷は抑えられるんじゃないかと思います。多分。あとはCSSファイルでの記述が可能なので、個人的に変更のしやすさもありました。

ただCSSのスプライトアニメーションを使うためには、background-imageで画像を表示する必要があります(と言い切っちゃいましたが他の方法もあるんでしょうか)。
ティラノのキャラ表示は(imageもですが)imgタグで行われているので、これをdivのbackground-imageにする改造をしました。具体的にはchara_showで生成されるimgオブジェクトをdivにして、そのbackground-imageにキャラの画像を入れるようにしました。
最初はこれを体と目・口・眉のパーツごとに個別に生成していたのですが、そうするとどうしても表示・消去でラグが出るので、体のdivを親として、それ以下に目・口・眉を格納するようにしています。逆に頬染めや汗などは個々で表示・消去をするので、体と同じ階層に作りました。表示方法についてはそんな感じです。

ただその表示をさせる前に、まずパーツごとに表情とファイル名を登録する必要があります。そのためchara_newを改造し、それぞれのキャラごとにeye・kuti・mayu・body・ase・namidaという配列を新たに挿入しました。そしてchara_faceにてeye・kuti・mayuの配列に表情を登録できるようにしました。しかしこれだけだとアニメさせるのに必要な情報が取得できない。というわけで、表情にプラスしてtopとheightも入れています。topは縦に連結させた画像を使うのでその位置を指定するため、heightは切り出しサイズですね。これの配列への入れ方が無駄な感じもありますが、とにもかくにもこれでアニメをさせる準備が整いました。

余談ですがchara_modで表情を変更する時に、目・眉・口のパーツをまとめて変更するマクロを作ってやってみたところ、変更前と同じ表情でも読み込み直しがされるようになったので、変更前パーツ名を格納する変数を作って変更後が同じかどうかチェックするようにしました。したような気がする。うん。あとshow前の表情適応も何かやったような気がしますがこれは公式の機能をそのまま使っただけかもしれない。またこの表情変更の際にchara_modでは完了を待たないことができなくてうおおおとなったのですが、開発者さんがwaitを入れてくださったのでとても助かりました。

アニメをつけるぞ!

アニメの方法はCSSのstepアニメーションです。topは上記で指定したので、keyframesのtoで縦ファイルサイズ限界のbackground-position位置を指定して、animationのstepで連結数を指定する、という形になります。これはキャラごとに同じサイズにすれば使い回せるので、作ってしまえば楽ですね。今回はopen_mouseで口パク、blinkで目パチするクラスとしました。ただ画像名をkutiとしてるのにここでmouseを使ったりアニメ名はeyeにしてクラス名はblinkにするとかこの辺の不規則性がアレですね。改造推奨部分です。
なお口パク用のアニメは回数をinfinite、目パチ用のアニメは1回としています。口パクはセリフ表示中はずっと口を動かさないとおかしくて、目パチは毎回ランダムにつけ外すことにしたからです(方法は後述)。

さてアニメはさせられるようになった、ではどうやって目パチ・口パクアニメのクラスをつけ外すか。これはもう無理にやりました。ゴリ押しです。

まずキャラが存在するか(表示されているか)どうかをチェックするゲーム変数(f.chara_show)(この変数名はタグ名と被るので微妙かも)を作り、chara_showとchara_hideでtrueとfalseを切り替えます。で、もう一つゲーム変数(f.kuti)(文字列)を作り、セリフを喋っている人間の名前をこの変数にchara_ptextタグ中で保存します。そしてキャラが表示されている時(f.chara_show==trueの時)は、div内でこのf.kutiの名前を持つ口パーツ(#kuti)に、open_mouseという口パク用クラスをつけるというわけです。これを新たに作った口パクをon.offするタグ([kutipaku_on][kutipaku_off])で行い、showMessageでキャラが存在して"「"か"…"でなければ、onを呼び出し、[p]及び[l]でoffにする、というわけです。

ちなみに俺たちのギャルゲではchara_name_area内の文字と0_foreレイヤーに表示されているdiv内のキャラ名が一致する場合にonしてましたが、よく考えなくてもptextから持ってきた方が楽だと最近気付いたので、サンプルの形となりました。これなら同時にキャラが登場しても大丈夫だぞ! と思いきや、目パチが壁です。

ちなみにパート2、俺たちのギャルゲでは目パチで上記の方法でキャラ名を取得してクラス名をつける形にしてたのですが、これもよく考えなくてもchara_show時に格納した方が楽だとさっき気付いたのでゲーム変数作ってそうしました。ただこの方法でも同時登場はダメですね。何か他にやり方ある気がします。

目パチ

目パチはランダムでさせたかったのもあり、今のような「一人しか出せない」仕様となりました。これをもし一定間隔でループさせるなら、そもそものCSSアニメの回数をinfiniteにして時間をある程度長く取り、つけ外しナシで目のクラスでそのまま行うようにすればいいんじゃないかと思います。その方が楽ですね。同時登場もいけそうです。ただ一定の間隔だと何かこう一定だなーという感じで、俺たちのギャルゲではランダムにしてみたくなったのです。

で、目パチ間隔をランダムにするにはどうしたらいいのかと。Javascriptで動的にCSSアニメを実行する方法もあると思うのですが、よく分からないのでクラスつけ外しをランダムにさせてみようと。そうするとループさせないといけないけれど、どうすりゃいいんだろうとググりまくった結果、setTimeoutループでtimeをランダム化するという方法に辿りつきました。それで最初は何となくうまくいったのですが、セーブ・ロードを挟むと目パチが二重に実行される。clearTimeoutされてないからですね。ということはセーブ時にタイマーIDを保存してロード時にclearしなければならない。というわけで、loadGameDataを改造してタイマーIDをゲーム変数で保存して、make.ksでその変数をclearTimeoutするようにしました。chara_hide時にも行うようにしています。これで一応俺たちのギャルゲではうまく動くようになりました。

ただこの方法の難点として、キャラを何人も出すとclearTimeoutがヤバイんじゃないかということです。俺たちのギャルゲだと一シナリオに一人のみの登場だったので問題なかったのですが(おまけ裏話はローディング画面に表示させたミニキャラを流用してます)、普通の作品だと厳しいかなあと。複数名のキャラを出す場合にはCSSアニメを一定間隔にするか、setInterval使うかとかですかね。setTimeoutは非同期処理的に良さそう(漠然)なので使ってみたのですが、ランダムループには向かないかもしれないなーという感じです。なぜならググっても記事があまり見つからなかった! 他に効率の良い方法をご存知の方は、バシバシ改造していただけると嬉しいです。