Archive for 2月, 2013

親子にする

十回近くにわたって手を入れたかいもあって「動く漫画」もずいぶんさまになってきた。
しかしよくよく演出を見てみると「クククク…」の吹き出しが出てくるのが
どーにもワンテンポ遅いかんじがする。

すると言ったらする!

どうやらコマの表示が終わるのをキッチリ最後まで待っているのが原因のようだ。
ここはひとつコマの表示が終わる前に吹き出しを表示し始めることにしよう。

けれども問題はそう簡単ではない。
コマは拡大しながら表示されるので、コマの表示が終わる前に吹き出しを表示させると
吹き出しの尾がコマの中のキャラクターの口もとから離れてしまうのだ。
それはちょっと具合が悪い。

コマの拡大に合わせて吹き出しも拡大させればいいと思うかもしれない。
しかしそうするとまた新たな問題にぶつかる。
コマの中のキャラクターの口もとの位置は、拡大によって移動していくので、
吹き出しの尾の位置を口もとの位置にきっちり合わせて動かすのが至難の技なのだ。
がんばればなんとかなることはなるが…なんとも泥臭い。
もっとスマートに実現したいところだ。

ではどうすればいいと言うのか。
ズバリ

吹きだしをコマにくっつけてしまえばいい。

吹きだしをコマにくっつけて、吹きだしとコマが一緒に動くようにすればいいのだ。
実はデーカーには他のデーカーをくっつけることができる機能がある。
この時、くっつけられる方を『親』、くっつける方を『子』と呼ぶ。
またこのようにデーカーをくっつけることを、デーカーを『親子にする』と言う。

親子とはプログラマにとっては馴染み深い言葉であるが、一般的にはわかりにくい言葉かも知れない。
ここで言う『親子』とは、人間の親・子とは意味がちょっと違う。
賭け事の親・子でもない。構造的な関係を表す比喩的な言葉だ。
それはこの関係構造を図で表すと木が枝を伸ばしたような図になり
それがある種の家系図のように見えるからだ。

──────ややこしい話はともかく
どうやってデーカーを親子にするのかサンプルを見てみよう。


method Main()
{
  CreateImage(name="親", image="親.png", x=100, y=100);
  CreateImage(name="親/子1", image="子.png", x=50, y=50);
  CreateImage(name="親/子2", image="子.png", x=50, y=50);
  CreateImage(name="親/子3", image="子.png", x=50, y=50);
  Enter(to="親");
  Enter(to="親/子1");
  Enter(to="親/子2");
  Enter(to="親/子3");
}

あるデーカーを子にしたい場合、nameパラメータに”親の名前/子の名前”という形で名前を指定する。
これだけでそのデーカーを子にすることができる。
このサンプルでは”親”に、”子1”、”子2”、”子3”の3つのデーカーを子として作成している。
toパラメータで子のデーカーを指定する場合も、同様に親の名前を書く必要があることに注意しよう。

“子1”、”子2”、”子3”の位置は”親”からの相対位置になる。
子は親が移動すれば一緒に移動し、親が拡大すれば一緒に拡大する。
完全に親の動きに追従するので、ある意味子は親の一部になっているとみなせる。

とまぁ…説明が長くなったけれど…やることは単純だ。
それでは組み込んでみよう。
子は親からの相対位置になるのでx, yパラメータの修正も忘れずに。


style 普通 { face="MS ゴシック", size=32 }
style 小 { size=24 }
style つぶやき { interval=100, speed=250, effect="Rise" }

method Main()
{
  CreateImage(name="背景", image="背景.png"
    , x=0, y=0);

  CreateFrame(name="コマ1", image="コマ1.png"
    , x=440, y=0
    , outline_shape="Fade", outline_color=RGBA(0,0,0,64), outline_thick=8);
  CreateFrame(name="コマ2", image="コマ2.png"
    , x="OutRight", y=65
    , outline_shape="Vivide", outline_color=white, outline_thick=8);
  CreateFrame(name="コマ3", image="コマ3.png"
    , x=407, y=505, ox="Center", oy="Middle", sx=0%, sy=0%
    , outline_shape="Vivide", outline_color=black, outline_thick=8);

  CreateBalloon(name="台詞1"
    , style="普通", text="それにしても...<BR>腹(はら)が減(へ)った"
    , x=585, y=65, shape="Dumpling", w=300, h=185, tail=-30);
  CreateBalloon(name="コマ3/台詞2"
    , style="小", text="<FONT style='つぶやき'>クククク…"
    , x=63, y=15, shape="Rock", w=220, h=125, tail=160);

  CreateColor(name="幕", color=white, w=1280, h=720, blend="Add");

  Enter(to="背景");
  Enter(to="コマ1");
  Enter(to="幕");
  wait 500;

  Opaque(to="幕", time=1000, alpha=0%, step="DecSin");
  WaitDecor();

  Enter(to="コマ2");
  Move(to="コマ2", time=800, x=780, step="Dec3");
  WaitDecor();

  Enter(to="台詞1", effect="Bound");
  WaitDecor();

  Enter(to="コマ3");
  Zoom(to="コマ3", time=1000, sx=100%, sy=100%, step="AccSig");
  wait 600;

  Enter(to="コマ3/台詞2", effect="Expand");
  WaitDecor();
}
YouTube Preview Image

吹き出しがコマにくっついているかんじになった!
うん…ちょっと効果がわかりにくいカモシレナイ。


合成モードを指定する

前回はフェードインを実装した。
白い幕がうっすらと消えていき「霞の中から景色が現れる」ような演出だったが
今回はそれを「まばゆい光の中から景色が現れる」カンジにしてみよう。

なんだか難しいことを言ってるかんじだが…
まったく難しくはない。

『合成モード』を変更するだけだ。

合成モードとは画像をどのように画面に合成するかという指定である。
画像処理ソフトとして有名なAdobe Photoshopのレイヤーのブレンドモードとほぼ同じものだ。

合成モードを指定するには blend パラメータを使う。
合成モードの指定はイメージデーカーだけでなく、
何かを表示する機能を持つ全てのデーカーに対して行うことができる。


CreateColor(name="幕", color=white, w=1280, h=720, blend="Add");

blend パラメータには合成モードの名前を指定する。
いままでイメージデーカーを作る際に特に合成モードの指定などはしていなかったが
自動的に通常合成(Normal)で合成が行われていた。

通常合成は、画像をそのままの見た目で画面に合成する合成モードだ。
他に加算合成、乗算合成などなど様々な合成モードがある。
FoooではPhoshopのレイヤーのブレンドモードに相当する全てのモードをサポートしている。
いくつか紹介しておこう。

Blend_Normal Blend_Add Blend_Sub
Normal
(通常)
Add
(加算)
Sub
(減算)
Blend_Multiply Blend_Screen Blend_Overlay
Multiply
(乗算)
Screen
(スクリーン)
Overlay
(オーバーレイ)

このように同じ画像でも合成モードを変えると印象ががらっと変わる。
幕をまばゆい光のようにするには、合成モードを”Add”(加算合成)に変更すれば良さそうだ。
それでは組み込んでみよう。


style 普通 { face="MS ゴシック", size=32 }
style 小 { size=24 }
style つぶやき { interval=100, speed=250, effect="Rise" }

method Main()
{
  CreateImage(name="背景", image="背景.png"
    , x=0, y=0);

  CreateFrame(name="コマ1", image="コマ1.png"
    , x=440, y=0
    , outline_shape="Fade", outline_color=RGBA(0,0,0,64), outline_thick=8);
  CreateFrame(name="コマ2", image="コマ2.png"
    , x="OutRight", y=65
    , outline_shape="Vivide", outline_color=white, outline_thick=8);
  CreateFrame(name="コマ3", image="コマ3.png"
    , x=407, y=505, ox="Center", oy="Middle", sx=0%, sy=0%
    , outline_shape="Vivide", outline_color=black, outline_thick=8);

  CreateBalloon(name="台詞1"
    , style="普通", text="それにしても...<BR>腹(はら)が減(へ)った"
    , x=585, y=65, shape="Dumpling", w=300, h=185, tail=-30);
  CreateBalloon(name="台詞2"
    , style="小", text="<FONT style='つぶやき'>クククク…"
    , x=470, y=520, shape="Rock", w=220, h=125, tail=160);

  CreateColor(name="幕", color=white, w=1280, h=720, blend="Add");

  Enter(to="背景");
  Enter(to="コマ1");
  Enter(to="幕");
  wait 500;

  Opaque(to="幕", time=1000, alpha=0%, step="DecSin");
  WaitDecor();

  Enter(to="コマ2");
  Move(to="コマ2", time=800, x=780, step="Dec3");
  WaitDecor();

  Enter(to="台詞1", effect="Bound");
  WaitDecor();

  Enter(to="コマ3");
  Zoom(to="コマ3", time=1000, sx=100%, sy=100%, step="AccSig");
  WaitDecor();

  Enter(to="台詞2", effect="Expand");
  WaitDecor();
}
YouTube Preview Image

幕がまばゆい光のようになった!
背景の絵がテキトーなのでちょっとわかりにくいけど…


フェードインする

画面がぱっと現れるのは味気ないので
白い画面からフェードインするようにしてみよう。
どのようにすればよいだろうか。
ここまで説明してきた内容を把握していれば簡単だろう。

画面サイズの真っ白な画像を用意し、
イメージデーカーを作成して表示させ、
Opaque命令でだんだん透明にするだけでいい。

しかしたかだかフェードインさせるためだけに
画像を用意しなくちゃいけないのは、いささか大きすぎる手間だ。
もうちょっと楽をしたい。

カラーデーカー

そんな時は『カラーデーカー』を使う。
カラーデーカーは、指定色で塗りつぶされた四角形を表示するデーカーだ。
フェードイン、フェードアウトなどの演出などを作りたい場合や
背景が単色でかまわない場合などに便利なデーカーである。

またプログラムの実行速度の面において、
イメージデーカーよりもずっと高速に動作するという特徴がある。
イメージデーカーと違って画像データを持たないからだ。
そういった理由から、使える場面ではできるだけカラーデーカーを使うことが望ましい。
実際カラーデーカーは非常によく使うデーカーの1つである。

CreateColor命令

カラーデーカーはCreateColor命令で作成する。


CreateColor(name="幕", color=white, w=1280, h=720);

color パラメータには塗りつぶし色を指定する。
w パラメータには横幅をピクセル単位で指定する。
h パラメータには縦幅をピクセル単位で指定する。

では組み込んでみよう。


style 普通 { face="MS ゴシック", size=32 }
style 小 { size=24 }
style つぶやき { interval=100, speed=250, effect="Rise" }

method Main()
{
  CreateImage(name="背景", image="背景.png"
    , x=0, y=0);

  CreateFrame(name="コマ1", image="コマ1.png"
    , x=440, y=0
    , outline_shape="Fade", outline_color=RGBA(0,0,0,64), outline_thick=8);
  CreateFrame(name="コマ2", image="コマ2.png"
    , x="OutRight", y=65
    , outline_shape="Vivide", outline_color=white, outline_thick=8);
  CreateFrame(name="コマ3", image="コマ3.png"
    , x=407, y=505, ox="Center", oy="Middle", sx=0%, sy=0%
    , outline_shape="Vivide", outline_color=black, outline_thick=8);

  CreateBalloon(name="台詞1"
    , style="普通", text="それにしても...<BR>腹(はら)が減(へ)った"
    , x=585, y=65, shape="Dumpling", w=300, h=185, tail=-30);
  CreateBalloon(name="台詞2"
    , style="小", text="<FONT style='つぶやき'>クククク…"
    , x=470, y=520, shape="Rock", w=220, h=125, tail=160);

  CreateColor(name="幕", color=white, w=1280, h=720);

  Enter(to="背景");
  Enter(to="コマ1");
  Enter(to="幕");
  wait 500;

  Opaque(to="幕", time=500, alpha=0%);
  WaitDecor();

  Enter(to="コマ2");
  Move(to="コマ2", time=800, x=780, step="Dec3");
  WaitDecor();

  Enter(to="台詞1", effect="Bound");
  WaitDecor();

  Enter(to="コマ3");
  Zoom(to="コマ3", time=1000, sx=100%, sy=100%, step="AccSig");
  WaitDecor();

  Enter(to="台詞2", effect="Expand");
  WaitDecor();
}
YouTube Preview Image

フェードインするようになった!


適当に待つ

演出にだいぶ手を入れたので、ここいらで演出のタイミングを調整しておこう。
まずはコマの表示速度を調整しよう。
やることは各命令のtimeパラメータを修正していくだけだ。

しかしこの時注意すべきことがある。
直後のwaitの値も同じように修正しなくてはいけないのだ。
そうしないと動きの後に意図しない変な間が入ってしまったりする。
1つの動きを直すのに2箇所も直さないといけないなんて…

めんどくさい!

WaitDecor命令

こんな時はWaitDecor命令を使う。
WaitDecor命令は、指定したデーカーの動作の完了を待つ命令だ。
WaitDecor命令を使うと、どのくらい待つかを細かく考えずに済む。

動きの時間を修正した場合に、待ち時間をいちいち書き換える必要もなくなるといった寸法だ。
また文章や吹きだしなどは、表示の完了までにかかる時間がわかりにくいので
そういった場合にもWaitDecor命令が便利だ。


Opaque(to="コマ1", time=1000, alpha=100%, step="AccSin");
WaitDecor(to="*");

toパラメータには待つ対象となるデーカーの名前を指定する。
上のサンプルでは対象に “*” を指定しているが、ちょっと変なかんじだ。
“*” は名前ではなく特殊な意味を持つ表記で『全てのデーカー』を表している。
つまりこのように書くと、対象がどのデーカーかすらも考える必要がなくなるのだ。

WaitDecor命令のtoパラメータのデフォルト値(省略した場合に使われる値)は “*” なので、
もっと単純に…


Opaque(to="コマ1", time=1000, alpha=100%, step="AccSin");
WaitDecor();

と書いてもいい。

ちなみにWaitDecor命令は対象のデーカーに対する命令ではなく、
スクリプトを実行しているエンジンに対する命令なので
即座には終わらず、命令の実行が完了してから次に進む。

では組み込んでみよう。


style 普通 { face="MS ゴシック", size=32 }
style 小 { size=24 }
style つぶやき { interval=100, speed=250, effect="Rise" }

method Main()
{
  CreateImage(name="背景", image="背景.png"
    , x=0, y=0);

  CreateFrame(name="コマ1", image="コマ1.png"
    , x=440, y=0, alpha=0%
    , outline_shape="Fade", outline_color=RGBA(0,0,0,64), outline_thick=8);
  CreateFrame(name="コマ2", image="コマ2.png"
    , x="OutRight", y=65
    , outline_shape="Vivide", outline_color=white, outline_thick=8);
  CreateFrame(name="コマ3", image="コマ3.png"
    , x=407, y=505, ox="Center", oy="Middle", sx=0%, sy=0%
    , outline_shape="Vivide", outline_color=black, outline_thick=8);

  CreateBalloon(name="台詞1"
    , style="普通", text="それにしても...<BR>腹(はら)が減(へ)った"
    , x=585, y=65, shape="Dumpling", w=300, h=185, tail=-30);
  CreateBalloon(name="台詞2"
    , style="小", text="<FONT style='つぶやき'>クククク…"
    , x=470, y=520, shape="Rock", w=220, h=125, tail=160);

  Enter(to="背景");
  wait 1000;

  Enter(to="コマ1");
  Opaque(to="コマ1", time=500, alpha=100%, step="AccSin");
  WaitDecor();

  Enter(to="コマ2");
  Move(to="コマ2", time=800, x=780, step="Dec3");
  WaitDecor();

  Enter(to="台詞1", effect="Bound");
  WaitDecor();

  Enter(to="コマ3");
  Zoom(to="コマ3", time=1000, sx=100%, sy=100%, step="AccSig");
  WaitDecor();

  Enter(to="台詞2", effect="Expand");
  WaitDecor();
}
YouTube Preview Image

スッキリ~


速度変化をつける

今度はコマの動きを工夫してみよう。
とはいえコマの動き方を大きく変えようという話ではない。
コマの動きに『速度変化』をつけようというお話だ。

今までコマが移動したり拡大したりしていたが、その動きその速度は常に一定だった。
よくよく考えてみると、現実において一定の速度で動くものというものはあまり目にしない。
一定速度で動くなんて自然ではない。不自然だ。
そのあたりが関係しているのかはよくわからないが…

確信を持ってこれだけは言える。

速度変化をつけるとキモチイイ

キモチイイ!
大事!

論より証拠。
実際に速度変化をつけてみよう。
動きに速度変化をつけるには step パラメータを使う。


Zoom(to="コマ3", time=1000, sx=100%, sy=100%, step="AccSig");

step パラメータは time パラメータをとる全ての命令で使うことができる。
step パラメータには速度変化の名前を指定する。
いくつか紹介しておこう。

Linear Step_Linear
AccSin Step_AccSin
Acc2 Step_Acc2
Acc3 Step_Acc3
DecSin Step_DecSin
Dec2 Step_Dec2
Dec3 Step_Dec3
AccSig Step_AccSig

では実際に組み込んでみよう。


style 普通 { face="MS ゴシック", size=32 }
style 小 { size=24 }
style つぶやき { interval=100, speed=250, effect="Rise" }

method Main()
{
  CreateImage(name="背景", image="背景.png"
    , x=0, y=0);

  CreateFrame(name="コマ1", image="コマ1.png"
    , x=440, y=0, alpha=0%
    , outline_shape="Fade", outline_color=RGBA(0,0,0,64), outline_thick=8);
  CreateFrame(name="コマ2", image="コマ2.png"
    , x="OutRight", y=65
    , outline_shape="Vivide", outline_color=white, outline_thick=8);
  CreateFrame(name="コマ3", image="コマ3.png"
    , x=407, y=505, ox="Center", oy="Middle", sx=0%, sy=0%
    , outline_shape="Vivide", outline_color=black, outline_thick=8);

  CreateBalloon(name="台詞1"
    , style="普通", text="それにしても...<BR>腹(はら)が減(へ)った"
    , x=585, y=65, shape="Dumpling", w=300, h=185, tail=-30);
  CreateBalloon(name="台詞2"
    , style="小", text="<FONT style='つぶやき'>クククク…"
    , x=470, y=520, shape="Rock", w=220, h=125, tail=160);

  Enter(to="背景");
  wait 1000;

  Enter(to="コマ1");
  Opaque(to="コマ1", time=1000, alpha=100%, step="AccSin");
  wait 1000;

  Enter(to="コマ2");
  Move(to="コマ2", time=1000, x=780, step="Dec3");
  wait 1000;

  Enter(to="台詞1", effect="Bound");
  wait 2000;

  Enter(to="コマ3");
  Zoom(to="コマ3", time=1000, sx=100%, sy=100%, step="AccSig");
  wait 1000;

  Enter(to="台詞2", effect="Expand");
  wait 1000;
}
YouTube Preview Image

キモチイイ!


コマの枠を指定する

『漫画のコマ』に相当するフレームデーカーには、
画像に自動的に「枠」をつけてくれるという機能がある。
今まで画像の周りにぼやーっと黒い枠がついていたと思うが、ソレだ。

けれどもただ単に枠がつくだけにすぎないので…
「だったら最初から画像自体に枠をつけてしまえばいいんじゃないの?」
「わざわざフレームデーカーなんて使う必要ないんじゃないの?」
「イメージデーカーで十分なんじゃないの?」
と思うかもしれない。

実際のところ画像自体に枠をつけてしまっても良いのだが
フレームデーカーを使って枠をつけることによる利点がいくつかある。
画像からコマを切り出す作業をする際に、枠のことをいちいち考えなくてよくなることも大きいが
最大の利点は、枠の形をスクリプトで調整することができるという点だ。

枠を指定するにはCreateFrame命令の
outline_shape、outline_color、outline_thickパラメータを使う。


CreateFrame(name="コマ2", image="コマ2.png"
  , x="OutRight", y=65
  , outline_shape="Vivide", outline_color=white, outline_thick=8);

outline_shape パラメータには枠の種類の名前を指定する。
“Fade”,”Vivide”,”Shadow”,”Emboss”などいくつか種類がある。
outline_color パラメータには枠の色を指定する。
outline_thick パラメータには枠の太さを指定する。

では組み込んでみよう。


style 普通 { face="MS ゴシック", size=32 }
style 小 { size=24 }
style つぶやき { interval=100, speed=250, effect="Rise" }

method Main()
{
  CreateImage(name="背景", image="背景.png"
    , x=0, y=0);

  CreateFrame(name="コマ1", image="コマ1.png"
    , x=440, y=0, alpha=0%
    , outline_shape="Fade", outline_color=RGBA(0,0,0,64), outline_thick=8);
  CreateFrame(name="コマ2", image="コマ2.png"
    , x="OutRight", y=65
    , outline_shape="Vivide", outline_color=white, outline_thick=8);
  CreateFrame(name="コマ3", image="コマ3.png"
    , x=407, y=505, ox="Center", oy="Middle", sx=0%, sy=0%
    , outline_shape="Vivide", outline_color=black, outline_thick=8);

  CreateBalloon(name="台詞1"
    , style="普通", text="それにしても...<BR>腹(はら)が減(へ)った"
    , x=585, y=65, shape="Dumpling", w=300, h=185, tail=-30);
  CreateBalloon(name="台詞2"
    , style="小", text="<FONT style='つぶやき'>クククク…"
    , x=470, y=520, shape="Rock", w=220, h=125, tail=160);

  Enter(to="背景");
  wait 1000;

  Enter(to="コマ1");
  Opaque(to="コマ1", time=1000, alpha=100%);
  wait 1000;

  Enter(to="コマ2");
  Move(to="コマ2", time=1000, x=780);
  wait 1000;

  Enter(to="台詞1", effect="Bound");
  wait 2000;

  Enter(to="コマ3");
  Zoom(to="コマ3", time=1000, sx=100%, sy=100%);
  wait 1000;

  Enter(to="台詞2", effect="Expand");
  wait 1000;
}
YouTube Preview Image

枠を変えたことでまたガラッと雰囲気が変わった!