アニメ編(その一)

ページ名:tutorial_anime_1
戻る:基礎編(その十二)


誰もが陥る罠


今回から、エフェクトブースターを用いたアニメーションについて説明します。


技術的な観点からすると、エフェクトブースターで絵を動かすこと自体はさほど難しくありません。
厄介なのは副作用に如何に対処するかです。
これまで繰り返し述べてきたように、エフェクトブースターの仕様は斜め上で、非常にクセがあるために、予想もしなかったことが常について回るんですよね。


残像が残ったとか。
急に真っ暗になって終わったとか。
表示されるはずの画像が表示されなかったとか。


その他諸々の、不可思議な現象に悩まされた経験は、誰にもあるはずです。
ですからこのチュートリアルでは、今まであったエフェブのテキストのように「こうしてこうすれば絵が動く」というだけの観念的かつ表層的なものではなく*1、その副作用の原理と解決方法も込みで説明していきます。


一時描画の基本


ここまで無造作に「アニメ(ーション)」という言葉を用いてきましたが、エフェクトブースターでは画像を動かしたり、フェードしたりするなどの演出を実現するための機能を一時描画と言っています。
その詳しい解説は後ほど述べますが、一時描画のためのもっとも基本的なパラメータは以下の三つです。


パラメータ名機能設定値
animationセクションに対して一時描画を設定する0: 一時描画しない(デフォルト)
1: 一時描画し、次の一時描画時も消去しない
2: 一時描画し、次の一時描画の直前に消去
3: 一時描画し、次の一時描画と同時に消去
4: 一時描画しないが、ウェイトは発生する
animepostion一時描画時の座標を指定する画面左端からの水平距離(Left)と画面上端からの垂直距離(Top)をコンマで連結して指定する(単位:ピクセル)
wait一時描画時のウェイトを指定する単位:ミリ秒(1/1000 秒)*2

特に、既出の position とは別に animeposition が存在することは要注目です・・・が、その説明も後ほど。


実例


まずはこれらのパラメータを用いて、ごく簡単なアニメーションを作ってみましょう。とはいえ、多分に「副作用の検証」が出来るよう、少しアニメの前後を工夫することにします。アニメの仕様は下記の通り。


  1. アニメの開始前は特定の色(一色)を画面全体に表示する
    1. その状態で三秒程度のインターバルを設ける。可能ならば 3, 2, 1 とカウントダウンしても良い
  2. アニメ開始時に背景画像を表示する
    1. 画面最奥には CW 標準の地図画像(MapOfWirth.bmp)を表示する
    2. 前景として CW 標準の冒険者の宿画像(AdventurersInn.bmp)を表示する。位置は左から 116 、上から 15(つまりいつもの位置)
  3. アニメ自体の内容は「画面上部に宿の亭主の画像を左から右へ動かす」ものとする
    1. 宿の亭主の画像はゴブリンの宿から借用する(宿の亭主.bmp)
    2. 画像を動かす際は最低 50 ピクセル以上移動させる
    3. 画像を動かす際は最低 50 ミリ秒以上のウェイトを置く
  4. アニメ終了後は地図+冒険者の宿が表示されたままにする

この「アニメ仕様書」から実際の映像をイメージできますか?
言われてもなかなか難しいと思いますので、まずは模範回答を示すことにしましょう。作る人によって多少の違いはあると思いますが、やりたいことはおおむねこんな感じです。



随分とシュールな感じになってしまいましたが、とりあえずこんな感じのものが作れれば合格ということにします。
ちなみにこのケースでは移動距離が 50 ピクセルずつ、ウェイトが 250 ミリ秒で、わりと細かく動かしています。みなさんが実際に作るものではお好きなバランスに調整してもらってかまいません。
なお、定義ファイルの内容が大きくなりすぎる(つまり行数が増えて読みづらい)ので、後述するサンプルではもう少し動作の荒いものとします。ご了承下さい。


さて。
まずはアニメ以外の部分、つまりエフェブを表示するためのエリアとそのイベントを(ちゃちゃっと)作ってしまいましょう。色使いがハデなので一見ごまかされますが、実はそんなに大変なことはやっていません。


まず、エリアを作ります。背景は黒一色(black.bmp)にしてください。



次に、イベントビューでアニメ前のカウントダウン部分を作ります。背景変更コンテントでこんな風にセルを配置します。



画面いっぱいにカラーセルを配置し、中央にテキストで数字を配置しました。これで OK を押してコンテントを確定します。
その直後には空白時間挿入コンテント(時計ではなく砂時計アイコンの方)を置いて、空白時間を 1.0 秒にセットします。



これで一秒分のインターバルは確保できました。あとは同じことを二回繰り返せばいいだけです。私は赤→緑→青と背景色を変えましたが、あなたの好きな色にしてもいいですし、変えなくてもかまいません。
三秒のカウントダウンを設定したイベントビューはこんな感じになっているはずです。



まあ、そもそもの「アニメ仕様書」では「一色で三秒表示」というだけでしたので、基礎編でやったように「黒一色のまま三秒待つ」でも問題ありません。お好きなように。


次に、おなじみの地図+宿画像を表示します。これも背景変更コンテントで指定してやればいいだけの話で、特に難しいことはありません。



念のため、この状態で一度動作確認をしてみましょう。以前にも説明しましたが、最後まで作ってから動作確認するのは初心者と万年初心者のすることで、作業の品質と効率を悪化させるだけです。そんな作業のすすめ方をしているうちは、あなたの作ったもの(エフェブだろうがシナリオだろうが)からは一生不具合がなくなりません。



途中までですが、特に問題なく動いているようです。最後に「親父横移動アニメ」をエフェブで作り、重ねてやればいいわけですね。


では、先ほどの三つのパラメータ(animation, animeposition, wait)を用いて JPY ファイルを作ってみましょう。


  1: [init]
  2: 
  3: [Master_00]
  4: fileName=宿の亭主.bmp
  5: animation=3
  6: animeposition=0,0
  7: wait=250
  8: 
  9: [Master_01]
 10: fileName=宿の亭主.bmp
 11: animation=3
 12: animeposition=150,0
 13: wait=250
 14: 
 15: [Master_02]
 16: fileName=宿の亭主.bmp
 17: animation=3
 18: animeposition=300,0
 19: wait=250
 20: 
 21: [Master_03]
 22: fileName=宿の亭主.bmp
 23: animation=3
 24: animeposition=450,0
 25: wait=250
 26: 
 27: [Master_04]
 28: fileName=宿の亭主.bmp
 29: animation=3
 30: animeposition=600,0
 31: wait=250

似たような感じのセクションが続いていますが、animeposition の設定値(水平距離)が違っていて、順に 0, 150 300, 450, 600 となっています。つまり一時描画の実行によって 150 ピクセルずつ横に移動するというわけです。
ま、厳密に言うと「移動する」というわけではなく、「前の画像が消えて、横に少しずれた位置に表示される」を繰り返すわけですが、それの繰り返しによって移動したように見える、というのはアニメーションの基本的な原理ですので、いまさら説明しなくても大丈夫ですよね。
それではこの内容を JPY ファイルとして保存、WirthBuilder で先の背景変更コンテントに追加しましょう。



暗闇に親父の顔が浮かんでいますが、どういうことでしょうか。
何はともあれ、いちど実行して動作確認させてみましょう。



でました副作用。エフェブのアニメって、慣れないときはこんなんばっかですわ。
具体的に言いますと


  1. (先ほど表示することを確認したはずの)地図+宿画像が表示されず、青い画面のまま一時描画がスタートした
  2. 一時描画の終了後、画面が真っ黒になった
  3. 一時描画の終了後、画面の左上に親父の顔が表示された

この三つです。みなさんがエフェブというものを知り初めて作ったアニメにも、きっとこんな症状が現れたことでしょう。


でも、これらの現象がどうして起きるのか、ヘルプファイル(editor128.chm)を読んだだけでは絶対に分かりません。だってどこにも書いてませんから。
そしてこれまで私が知る限り、ヘルプ以外のどのテクストでも説明されたことがありません。
だからこそ、その「どこにも書いてない」ことをみなさんに説明するために、このチュートリアルがあるのです。


副作用の根源的原因


上記の三つの副作用の、その根源的原因は実のところただ一つです。それは


CW エンジンは全てのセクションで一時描画を行った後、改めて静止画として描画し直す


ということにあります。意味分かりますかね?
より正確で厳密な説明は後ほど行いますが、エフェクトブースターでの背景描画には二つのフェイズがある、と考えると分かりやすいはずです。そのことを先ほどの「親父横移動アニメ」を例にとって説明してみましょう。


フェイズ1は一時描画フェイズです。エフェクトブースターはまず animation パラメータによって一時描画を指定されたセクションを順次解釈し、一時描画を行います。この結果が、先にも見たように「亭主が横に移動する」アニメとして表示されるわけです。
ここまではいいでしょう。おそらくあなたの常識の範囲内の動作のはずです。


そしてフェイズ2は描画フェイズです。この描画は一時描画とまったく別物で、単なる画像として・・・つまりこのチュートリアルの基礎編でずっと見てきたような静止画として、全てのセクションを再解釈し、もう一回背景を描画し直します。


つまりエフェブ(というか CW エンジン)は、一個の JPY ファイルを二回描画するんです!
いやもう、実に斜め上というか何というか・・・ふつう予想できないですよね、そんなこと。


具体的説明


そのことを、もう少し具体的に説明してみましょう。先の「親父横移動アニメ」を例にとってみます。


まずフェイズ1、一時描画フェイズでは animation パラメータ等の指定によって一時描画が行われます。
これは既に動画で見たとおりで、親父が横移動するという点だけとってみれば、一応ちゃんと行われていたのが分かると思います。


そして問題のフェイズ2です。CW エンジンは先ほどの JPY ファイルを「静止画として」再解釈し、描画を行います。つまりこのフェイズにおいては、先ほどの定義ファイルはこういう意味を持っているわけです。


  1: [init]
  2: 
  3: [Master_00]
  4: fileName=宿の亭主.bmp
  5: 
  6: 
  7: 
  8: 
  9: [Master_01]
 10: fileName=宿の亭主.bmp
 11: 
 12: 
 13: 
 14: 
 15: [Master_02]
 16: fileName=宿の亭主.bmp
 17: 
 18: 
 19: 
 20: 
 21: [Master_03]
 22: fileName=宿の亭主.bmp
 23: 
 24: 
 25: 
 26: 
 27: [Master_04]
 28: fileName=宿の亭主.bmp
 29: 
 30: 
 31: 

どのセクションもファイル名が指定されていますから、その画像(宿の亭主)を表示するセクションとして解釈されます。
だから、アニメの実行後に親父の顔が表示されるんです。画面の左上に表示されてしまうのは、表示位置を指定するパラメータ position のデフォルト値が 0,0 、つまり画面左上に表示するのがデフォルトだからです。
親父の顔は一つしか表示されていませんが、実際には [Master_00] から [Master_04] までの五個分重なっているんですね。


そして、アニメ終了後に画面が真っ黒になるのも同じ理屈ですが、こちらが参照しているのは [init] セクションです。
背景を指定する [init] セクションにはパラメータが何も指定されていませんから、backcolor=$000000 というデフォルト値(つまり真っ黒)が表示されているのと同じことなのです*3


エフェクトブースターについて書かれたテキストの中には、[init] セクションについて「一時描画の実行後に表示される画面」と説明しているものがあります。ちょっと惜しい。
必ずしも間違いではないのですが、正確な説明とも言いかねます。なぜなら [init] セクションに限らず animation パラメータの指定がないセクションがあれば、それは一時描画の実行後に表示されるからです。


検証1


以上の説明を確認するために、先ほどの JPY ファイルに少し手を加え、動作を比較してみましょう。


  1: [init]
  2: backcolor=$ffffff
  3: 
  4: [Master_00]
  5: fileName=宿の亭主.bmp
  6: position=0,50
  7: animation=3
  8: animeposition=0,0
  9: wait=250
 10: 
 11: [Master_01]
 12: fileName=宿の亭主.bmp
 13: position=150,100
 14: animation=3
 15: animeposition=150,0
 16: wait=250
 17: 
 18: [Master_02]
 19: fileName=宿の亭主.bmp
 20: position=300,150
 21: animation=3
 22: animeposition=300,0
 23: wait=250
 24: 
 25: [冒険者の宿]
 26: fileName=AdventurersInn.bmp
 27: dirtype=2
 28: position=116,15
 29: transparent=0
 30: 
 31: [Master_03]
 32: fileName=宿の亭主.bmp
 33: position=450,200
 34: animation=3
 35: animeposition=450,0
 36: wait=250
 37: 
 38: [Master_04]
 39: fileName=宿の亭主.bmp
 40: position=600,250
 41: animation=3
 42: animeposition=600,0
 43: wait=250

変更点は主に三つです。


  • [init] セクションに backcolor パラメータを追加しました(2 行目)。$ffffff は白を意味します。
  • 一時描画を行う [Master_00] ~ [Master_04] セクションに position パラメータを追加しました。それぞれ表示位置を変えており、どのセクションが(一時描画ではなく)静止画として再描画されたか分かるようにしてあります。
  • 新規セクション [冒険者の宿] を追加しました(25-30行目)。これは animation パラメータを指定していないので、ただの静止画として扱われます。設定内容は「標準フォルダにある冒険者の宿の画像を Left = 116, Top = 15 の場所に表示する」という、おなじみのアレです。


これらの変更には、もちろん目的があります。
[init] に色を指定したのは、一時描画実行後の画面が [init] セクションの描画そのものであることを証明するためです。先ほどは黒($000000)だったものが白($ffffff)に変われば、それは [init] セクションの backcolor パラメータの働きによることが分かりますね。


また、各セクションに position パラメータを指定し、一時描画実行後に表示される場所を変えました。位置関係はそれぞれ見比べれば分かるように、一時描画の実行時よりも下の方に表示されるようにしてあります。
これによって、左上に表示された親父の亡霊の正体が「position パラメータを省略されたセクションが静止画として再描画されたもの」であることが分かるはずです。


さらに、冒険者の宿の画像をアニメの間に挟んだのも一つのポイントです。
つまり、既に説明したように「CW エンジンは一時描画を先に片付けてから静止画を描画する」のが正しいなら、この画像は定義ファイルのどこに置かれようとも一時描画実行後に表示されるはずでしょう。
それは [init] に限らず animation パラメータの指定がないセクションは一時描画の実行後に描画される、ということの証明になります。
しかしそうではなく、もし「一時描画も描画も区別されず、単に上から下に処理される」ものならば、冒険者の宿の画像表示は親父横移動の合間に行われるはず・・・ですよね?


では、以上の仮説の下に先ほどの JPY(を含む一連のコンテント)を実行してみましょう。



結果は明らかですね。これで三つあった副作用の内、二つは理解いただけたと思います。三つの副作用って何だっけ・・・という方のために再掲しますと


  1. (先ほど表示することを確認したはずの)地図+宿画像が表示されず、青い画面のまま一時描画がスタートした
  2. 一時描画の終了後、画面が真っ黒になった
  3. 一時描画の終了後、画面の左上に親父の顔が表示された

この三つですが、画面が真っ黒になったのは [init] セクションが一時描画の後で描画されたことによるもの( backcolor を指定したら真っ白になった)、そして左上に親父の顔が表示されたのは [Master_00] ~ [Master_04] セクションが重なって一時描画後に描画されたことによるもの(position を指定したらそれぞれの場所に描画された)だと分かります。
ちなみに変更後のバージョンでは [Master_01] および [Master_02] にあたる親父の顔は表示されていません。これは、それぞれのセクションより後に [冒険者の宿] セクションがある、つまり上から重なってしまったために見えなくなってしまったわけです。
この点は基礎編(その五)で説明した内容そのままで、「後から置かれたセクションが上に重ねられる」ということが忠実に実現されていることも分かります。


これで二件、いまだ問題解決とは行きませんが、どうしてそのような現象が起きたかの理解は出来ました。
残ったのはもう一件、一時描画の開始時点で地図+宿が表示されなくなってしまった、ということです・・・背景変更コンテントには依然として存在するにもかかわらず。


検証2


ずっと上の方で、エフェクトブースターで予期しない副作用が起きがちな原因として


CW エンジンは全てのセクションで一時描画を行った後、改めて静止画として描画し直す


という説明を行いました。
この理屈、実は JPY ファイルの外にまで及ぶのです。この理屈がどの範囲で適用されるかというと、背景変更コンテント の単位で行われるんです。またしても予想外の事態。


具体的に説明しましょう。
検証用に手を入れる前(つまり実行後真っ黒+左上に親父の亡霊)の状態ですが、エフェブを表示するためのエリアのイベントコンテントはこうなっていたはずです。



そして、エフェブ実行のところの背景変更コンテントはこんな設定になっています。



赤丸で示したとおり、このコンテントには三つの画像相当のファイルが指定されています。


  • 背景として地図の画像 MapOfWirth.bmp
  • セルとして冒険者の宿の画像 AdventurersInn.bmp
  • セルとしてアニメを定義した JPY ファイル effct\01Master001.jpy1*4

ここまではよろしいですか。
先ほどの「一時描画を行った後、改めて静止画として描画し直す」というのは、実はこのコンテントの画像全部、つまり地図と冒険者の宿にまで及ぶのです。
つまりこの場合、CW エンジンはこんな風に動作するんです。


  1. まず JPY ファイルの一時描画を実行する(親父の横移動)
  2. 残りの全ての画像を重ねて背景画像を描画する
    1. 一番下に地図
    2. その上に冒険者の宿
    3. その上に JPY を静止画として
      1. [init] セクションは真っ黒
      2. [Master_00] ~ [Master_04] セクションは画面左上に

つまり、地図も宿も描画されてないわけではないんですが、その上に [init] の真っ黒が全部重なってしまうんですね。それで描画されていないように見えてしまうのです。


それを確認するのは簡単なことです。件の JPY ファイルに Mask : ON を設定します。



この状態で実行すると・・・



一時描画の実行後、真っ黒ではなく下の画像(つまり地図+宿)が透けて見えるようになりましたね。左上に表示されている親父の亡霊も(透過色が有効になったため)ますます亡霊じみて表示されるようにはなりましたが、この問題は後々解決するとしましょう。
今は「カードワースではどのように背景描画がなされるか」というところを理解していただくのが先決です。


まとめとおさらい


ここまでの説明は如何でしたでしょうか。
エフェクトブースターが絡んだ CW の背景描画の仕様はかなり独特なため、説明と検証で話があっちこっちに飛んでしまい、分かりにくかったかもしれませんがご容赦下さい。


今回のポイントは、なんと言ってもこれに尽きます。


  • エフェクトブースターの背景描画は一時描画と(静止画の)描画、二回のフェイズがある
    • CW エンジンはまず一時描画を行った後、JPY のセクションとセルから背景画像を作り出す
    • 一時描画の優先性は JPY ファイル内に留まらず、背景変更コンテント内の全てのセルに及ぶ

今回新たに登場したパラメータは下記の通りです。


パラメータ名機能
animationセクションに対して一時描画を設定する
animepostion一時描画時の座標を指定する
wait一時描画時のウェイトを指定する

次回は、今回の説明を踏まえて副作用への対処法を示します。
今回と次回、二回の内容が理解できれば、ほぼエフェブは怖いものナシです。おかしな副作用に悩まされず、やりたいことがやれるようになるはずですよ。


戻る:基礎編(その十二)

*1 敢えて名指しはしませんが、明らかに副作用が起きる内容を提示して足れりとし、実際に動作させて検証していないことが明白な粗悪チュートリアルもあります
*2 ただし、現在普及している PC やディスプレイにはミリ秒単位で描画できるほどの性能がありません。たとえば画面のリフレッシュレート(描画更新頻度)が 60Hz なら、1/60 秒すなわち 17 ミリ秒程度の更新が限界です
*3 基礎編(その六)でも説明しましたが、backcolor についてのヘルプの記述は誤りで、デフォルトは白ではなく黒です
*4 ただしこの部分はどのようなファイル名で保存したかによって違うはずですので適宜読み替えてください

シェアボタン: このページをSNSに投稿するのに便利です。

コメント

返信元返信をやめる

※ 悪質なユーザーの書き込みは制限します。

最新を表示する

NG表示方式

NGID一覧