吹きだしの形を指定する

今度は吹きだしに手を加えよう。
漫画において吹きだしは台詞を入れる単なる枠ではない。

吹きだしは台詞の意味を視覚的に表す記号である。

その上で特に重要なのが、吹きだしの『形』だ。
吹きだしの形を使い分けることで、より豊かな表現が可能になるのだ。

『動く漫画』においても、吹きだしの形はやはり重要である。
バルーンデーカーは様々な形状の吹きだしを作り出す高度な機能を備えている。
吹きだしをどんな形状にするかは、CreateBalloon命令のshapeパラメータで指定できる。


  CreateBalloon(name="台詞1"
    , style="普通", text="それにしても...<BR>腹(はら)が減(へ)った"
    , x=588, y=75, shape="Dumpling", tail=-30);

shapeパラメータには吹き出しの形状の名前を指定する。
用意されている形状はざっと90種類。
いくつか例を挙げておこう。

Balloon_Dumpling Balloon_Potato Balloon_Rock Balloon_PolyRect Balloon_Bale
Dumpling Potato Rock PolyRect Bale
Balloon_FlickerRect Balloon_FatStar Balloon_Punch Balloon_Burst Balloon_Gas
FlickerRect FatStar Punch Burst Gas

吹きだしのサイズは台詞が収まるように自動的に調整されるが、
形と文章量の相性によっては吹きだしの大きさがイマイチになる場合もある。
そんな時はw, hパラメータで吹きだしのサイズを直接指定する。


  CreateBalloon(name="台詞1"
    , style="普通", text="それにしても...<BR>腹(はら)が減(へ)った"
    , x=588, y=75, shape="Dumpling", w=300, h=185, tail=-30);

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, alpha=0%);
  CreateFrame(name="コマ2", image="コマ2.png"
    , x="OutRight", y=65);
  CreateFrame(name="コマ3", image="コマ3.png"
    , x=407, y=505, ox="Center", oy="Middle", sx=0%, sy=0%);
  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");
  wait 1500;

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

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

グッと表情が豊かになった!


文章に緩急をつける

漫画の吹きだしの中の文章は、ただの文章ではなく台詞である。
何をあたり前のことを…と思うかもしれないが、改めてそう認識することが重要なのだ。

人が言葉を発する時、一定の速度で淡々と喋ることはまずない。
それが台詞であっても同様だ。

台詞には必ず緩急がある。

しかしアドベンチャーゲームのメッセージは
例えそれが台詞であったとしても一定速度で表示することが多い。
アドベンチャーゲームの多くが小説の延長線上にあるせいかもしれないが…
ざっと見の読みやすさを重視している部分や、伝統的にそうなってる部分もある。

しかしFoooの実現する『動く漫画』の吹きだしは
感覚的に小説のソレより人間の言葉に近い。
そのため一定速度で一様に文章を表示すると違和感が出る場合がある。
緩急があって然るべき、なのだ。

そこでFoooには文章に緩急をつけるための機能が用意されている。

WAITタグ


それにしても<WAIT time=800><BR>腹(はら)が減(へ)った

WAITタグは文章中に待ちを埋め込むタグだ。
timeで待ち時間をミリ秒単位で指定する。

しかしやはりタグを書くのは長ったらしい…
そこでもっと簡単に待ちを指定する方法が用意されている。

待ち文字


それにしても,...<BR>腹(はら)が減(へ)った

何やら . と , がちょこちょこっと書かれている。
これでさっきと同じように800ミリ秒待つという意味になる。
文中において、ピリオド . は100ミリ秒の待ち、カンマ , は500ミリ秒の待ちと解釈されるのだ。
, が1個、. が3個で合せて800ミリ秒の待ちといった具合だ。

最初の”Hello, world”のスクリプトで , が表示されなかったのを覚えているだろうか。
なぜ , が表示されないのか説明を省いたが…そう…
, が表示されなかったのは、待ち文字として解釈されてしまっていたからなのだ。

このような特殊な意味として解釈される文字は < > ( ) などいろいろあるが
特殊な意味として解釈されたくない場合は、文字の前に&記号を書く。


method Main()
{
   CreateText(name="Text", text="hello&, world");
   Enter(to="Text");
}

これで”hello, world”と表示されるようになる。

では組み込んでみよう。


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%);
  CreateFrame(name="コマ2", image="コマ2.png"
    , x="OutRight", y=65);
  CreateFrame(name="コマ3", image="コマ3.png"
    , x=407, y=505, ox="Center", oy="Middle", sx=0%, sy=0%);
  CreateBalloon(name="台詞1"
    , style="普通", text="それにしても...<BR>腹(はら)が減(へ)った"
    , x=588, y=75, tail=-30);
  CreateBalloon(name="台詞2"
    , style="小", text="<FONT style='つぶやき'>クククク…"
    , x=485, y=525, 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");
  wait 1500;

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

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

台詞にちょっと間が入ったのがわかるだろうか。


文字の出方を指定する

文章の見た目はなんとなく整ったので、今度は文章の『文字の出方』を調整しよう。

今までの動作サンプルを見ればわかるように、
テキストデーカーやバルーンデーカーを作成し表示すると
自動的に文字が打印されるように1文字ずつ表示される。
この様な動作のことをFoooでは…

『タイピング』と呼んでいる。

一般的な呼び方なのかどうかは知らない(何
タイピングの仕方はFONTタグで指定することができる。


<FONT interval=100 speed=250 effect='Rise'>クククク…</FONT>

FONTタグで指定するというのはニアンス的にちょっと変な感じもあるのだが
実際のところ文字サイズなどの指定と一緒に行うことが多いので一緒にしている。

スタイル定義でも指定可能だ。


style つぶやき { interval=100, speed=250, effect="Rise" }

interval にはタイピングする時間間隔をミリ秒単位で指定する。
speed にはタイピング効果にかける時間をミリ秒単位で指定する。
effect にはタイピング効果の種類の名前を指定する。

上の説明にもあるようにタイピング時には
タイピング効果という特殊な演出をつけることができる。
タイピング効果には様々な種類が用意されている。
いくつか挙げておこう。

TypingEffect_Fade TypingEffect_Rise TypingEffect_Bang TypingEffect_OffCenter TypingEffect_Splash
Fade Rise Bang OffCenter Splash

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


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%);
  CreateFrame(name="コマ2", image="コマ2.png"
    , x="OutRight", y=65);
  CreateFrame(name="コマ3", image="コマ3.png"
    , x=407, y=505, ox="Center", oy="Middle", sx=0%, sy=0%);
  CreateBalloon(name="台詞1"
    , style="普通", text="それにしても<BR>腹(はら)が減(へ)った"
    , x=588, y=75, tail=-30);
  CreateBalloon(name="台詞2"
    , style="小", text="<FONT style='つぶやき'>クククク…"
    , x=485, y=525, 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");
  wait 1500;

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

  Enter(to="台詞2");
  wait 1000;
}

今回はタグでスタイルを指定してみた。
FONTタグの閉じタグを書いていないが、閉じる必要がない場合は省略できる。

よくよく見るとCreateBalloon命令のstyleパラメータでもスタイルを指定しており
スタイルの指定が重複してしまっている。
こういう場合どうなるのか。

スタイルの指定が複数ある場合、先に指定されたスタイルの指定内容に
後のスタイルの指定内容を付け加える形になる。
また同じ種類の指定があれば上書きされる。
スタイルは組み合わせて使うことが出来るのだ。

実行してみよう。

YouTube Preview Image

文字の出方を細かく調整することで、ぐっと臨場感が増すことがわかるだろう。


ルビを振る

タグについて説明したので、ついでにルビを振る方法についても説明しておこう。

ルビとは漢字の上や横に読み仮名を小さな文字で書くアレだ。
難しい単語の読みをわかりやすくるためや、
通常とはまったく異なった読み方をさせたい時などに主に使う。
・をルビにすることで文章を強調するなんて使い方もある。
少年漫画では、読者層を考慮して全ての漢字にルビを振っていることが多い。

単語にルビを振るにはRUBYタグを使う。


<RUBY text='さんま'>秋刀魚</RUBY>

これで”秋刀魚”に”さんま”とルビが振られる。
振り仮名にはひらがな、カタカナ、英数字、漢字を自由に使用できる。
振り仮名と単語の文字数は一緒でなくてもいい。

…しかしこの書きかたはなんとも大げさだ。
単語より前に振り仮名を書くというのも、ちょっと直感的ではない。

実はもっと簡単にルビを記述する方法がある。


(秋刀魚/さんま)

随分すっきりした。
文中において(~/~)という表記はルビの指定と解釈されRUBYタグと同様の効果がある。

さらにルビを振る対象が漢字だけで構成され、
見た目で対象範囲を特定できる場合はもっと簡単に記述できる。


秋刀魚(さんま)

超スッキリ!

ほとんどの場合、この書き方で事足りる。
実際に組み込んでみよう。


style 普通 { face="MS ゴシック", size=32 }
style 小 { size=24 }

method Main()
{
  CreateImage(name="背景", image="背景.png"
    , x=0, y=0);
  CreateFrame(name="コマ1", image="コマ1.png"
    , x=440, y=0, alpha=0%);
  CreateFrame(name="コマ2", image="コマ2.png"
    , x="OutRight", y=65);
  CreateFrame(name="コマ3", image="コマ3.png"
    , x=407, y=505, ox="Center", oy="Middle", sx=0%, sy=0%);
  CreateBalloon(name="台詞1"
    , style="普通", text="それにしても<BR>腹(はら)が減(へ)った"
    , x=588, y=75, tail=-30);
  CreateBalloon(name="台詞2"
    , style="小", text="クククク…"
    , x=485, y=525, 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");
  wait 1500;

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

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

修正点が少なすぎて拍子抜けしただろう。
このくらいルビは簡単に使用できるのだ。


スタイルでフォントを指定する

タグによるフォントの指定は、テキストの一部だけフォントを変えるなどできて便利なのだが
長~いスクリプトで全体的にフォントを変えていこうと思った場合
毎度毎度textパラメータに長ったらしい記述をしなくてはいけないのは、すごく面倒だ。
そんな時に使うのが…

スタイル定義だ。

フォントの形、サイズ、色などを『スタイル』という形で予め定義しておき、
命令ではそのスタイルを指定して使う。
このようにすると命令毎のフォントの指定を大幅に簡略化できる。

HTMLを知ってる人なら「スタイルシートみたいなものかな?」
と思ったかもしれない。
記述の仕方はちょっと違うが、機能の意図としては同じようなものだ。

どう書くのか見ていこう。
まずはスタイルを定義する記述。


style 普通 { face="MS ゴシック", size=32 }

“普通”という名前のスタイルを定義している。
簡単なので詳しく説明しなくても、どういう意味の記述かだいたいわかると思う。

次にスタイルの使い方。
スタイルはFONTタグで指定できる。


  CreateBalloon(name="台詞1"
    , text="<FONT style='普通'>それにしても<BR>腹が減った</FONT>"
    , x=588, y=75, tail=-30);

しかしまだこれもちょっと煩雑なかんじだ。
文章全体にスタイルを指定してしまってかまわない場合は、もっと簡単に記述する方法がある。
それがCreateBalloon命令のstyleパラメータを使う方法。


  CreateBalloon(name="台詞1"
    , style="普通", text="それにしても<BR>腹が減った"
    , x=588, y=75, tail=-30);

かなりスッキリした!
それでは組み込んでみよう。


style 普通 { face="MS ゴシック", size=32 }
style 小 { size=24 }

method Main()
{
  CreateImage(name="背景", image="背景.png"
    , x=0, y=0);
  CreateFrame(name="コマ1", image="コマ1.png"
    , x=440, y=0, alpha=0%);
  CreateFrame(name="コマ2", image="コマ2.png"
    , x="OutRight", y=65);
  CreateFrame(name="コマ3", image="コマ3.png"
    , x=407, y=505, ox="Center", oy="Middle", sx=0%, sy=0%);
  CreateBalloon(name="台詞1"
    , style="普通", text="それにしても<BR>腹が減った"
    , x=588, y=75, tail=-30);
  CreateBalloon(name="台詞2"
    , style="小", text="クククク…"
    , x=485, y=525, 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");
  wait 1500;

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

  Enter(to="台詞2");
  wait 1000;
}

実行結果は前回と一緒なので省略~


タグでフォントを指定する

さてさて『動く漫画』を作ってみたわけだが…
かなり演出が大雑把で…

なーんだFoooなんてこんなものか

なんて思ったかもしれない。
いやいやいやいや
いやいやいやいや
いやいやいやいや

Foooの実力はこんなものではない!

しかし演出がまだまだ大雑把なのは間違いない。
ここからは、演出の細かな調整を可能にするFoooの様々な機能を紹介しながら
『動く漫画』をより読みやすく、躍動感のあるものに仕上げていこうと思う。

真っ先に手を加えたいのは、文字だ。
とにもかくにも文字が小さすぎる!
サンプルは画面を縮小して掲載しているせいもあって、あまりにも文字が見づらい。

文字のサイズを大きくしたい。
ではどのようにして文字のサイズを変えるかというと…

『タグ』を使う。

『タグ』というとホームページを作成する時に使う言語『HTML』を
思い出す人が多いのではないだろうか。
それが正解。
ここで言ってる『タグ』はHTMLのタグとほとんど同じものだ。

CreateText命令やCreateBalloon命令のtextパラメータでは、
次のようにして『タグ』を記述することができる。


  CreateBalloon(name="台詞1"
    , text="<FONT size=32>それにしても<BR>腹が減った</FONT>"
    , x=564, y=75, tail=-30);

FONTタグで文字サイズを32ピクセルに指定している。
さらにfaceパラメータでフォントを変えることもできる。


  CreateBalloon(name="台詞1"
    , text="<FONT face='MS ゴシック' size=32>それにしても腹が減った</FONT>"
    , x=564, y=75, tail=-30);

このようにHTMLのFONTタグとそっくりなかんじに書ける。
他に色や太さ、影、縁取りの指定なども可能だ。

ちなみにタグを使って改行もできる。
改行にはBRタグを使う。
これもHTMLと同じ。


  CreateBalloon(name="台詞1"
    , text="<FONT face='MS ゴシック' size=32>それにしても<BR>腹が減った</FONT>"
    , x=564, y=75, tail=-30);

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


method Main()
{
  CreateImage(name="背景", image="背景.png"
    , x=0, y=0);
  CreateFrame(name="コマ1", image="コマ1.png"
    , x=440, y=0, alpha=0%);
  CreateFrame(name="コマ2", image="コマ2.png"
    , x="OutRight", y=65);
  CreateFrame(name="コマ3", image="コマ3.png"
    , x=407, y=505, ox="Center", oy="Middle", sx=0%, sy=0%);
  CreateBalloon(name="台詞1"
    , text="<FONT face='MS ゴシック' size=32>それにしても<BR>腹が減った</FONT>"
    , x=588, y=75, tail=-30);
  CreateBalloon(name="台詞2"
    , text="<FONT size=24>クククク…</FONT>"
    , x=485, y=525, 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");
  wait 1500;

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

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

文字が大きくなって、グッと読みやすくなった!


動く漫画を作ろう

さて、ここまでの説明で『動く漫画』を実現するために必要な
基本的な知識はおおよそ整ったように思う。
ではではいよいよみなさんお待ちかね。
Foooスクリプトを使って実際に『動く漫画』を作ってみよう。

まず素材を用意しておく。

Fooo_CreateComic_Back Fooo_CreateComic_Frame1 Fooo_CreateComic_Frame2 Fooo_CreateComic_Frame3
背景.png コマ1.png コマ2.png コマ3.png

『動く漫画』は4つのステップで作っていく。
順に詳しく見ていこう。

STEP1: デーカーの作成

最初のステップは、デーカーの作成だ。
配置などは考えず、どばばーっと書き連ねてしまおう。


method Main()
{
  CreateImage(name="背景", image="背景.png");
  CreateFrame(name="コマ1", image="コマ1.png");
  CreateFrame(name="コマ2", image="コマ2.png");
  CreateFrame(name="コマ3", image="コマ3.png");
  CreateBalloon(name="台詞1", text="それにしても腹が減った");
  CreateBalloon(name="台詞2", text="クククク…");

  Enter(to="背景");
  Enter(to="コマ1");
  Enter(to="コマ2");
  Enter(to="コマ3");
  Enter(to="台詞1");
  Enter(to="台詞2");
}

Fooo_CreateComic_Step1

ぐちゃぐちゃだが…配置を無視しているので当然である。

STEP2: 配置

次のステップは、配置の調整だ。
配置の調整は、x, y, tailパラメータなどにまず適当な値を入れて
実行してみては微調整を繰り返す地味な作業である。


method Main()
{
  CreateImage(name="背景", image="背景.png", x=0, y=0);
  CreateFrame(name="コマ1", image="コマ1.png", x=440, y=0);
  CreateFrame(name="コマ2", image="コマ2.png", x=780, y=65);
  CreateFrame(name="コマ3", image="コマ3.png", x=100, y=355);
  CreateBalloon(name="台詞1", text="それにしても腹が減った"
    , x=620, y=110, tail=-30);
  CreateBalloon(name="台詞2", text="クククク…", x=485, y=525, tail=160);

  Enter(to="背景");
  Enter(to="コマ1");
  Enter(to="コマ2");
  Enter(to="コマ3");
  Enter(to="台詞1");
  Enter(to="台詞2");
}

Fooo_CreateComic_Step2

見た目が整った。

STEP3: 順序付け

第三のステップは、表示順の整理だ。
wait文を使って、Enterに時間差をつけていく。


method Main()
{
  CreateImage(name="背景", image="背景.png", x=0, y=0);
  CreateFrame(name="コマ1", image="コマ1.png", x=440, y=0);
  CreateFrame(name="コマ2", image="コマ2.png", x=780, y=65);
  CreateFrame(name="コマ3", image="コマ3.png", x=100, y=355);
  CreateBalloon(name="台詞1", text="それにしても腹が減った"
    , x=620, y=110, tail=-30);
  CreateBalloon(name="台詞2", text="クククク…", x=485, y=525, tail=160);

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

  Enter(to="コマ1");
  wait 1000;

  Enter(to="コマ2");
  wait 1000;

  Enter(to="台詞1");
  wait 1500;

  Enter(to="コマ3");
  wait 1000;

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

もうかなり漫画っぽくなってきた。

STEP4: 演出付け

第4のステップは、演出付けだ。
コマに動きをつけていく。


method Main()
{
  CreateImage(name="背景", image="背景.png", x=0, y=0);
  CreateFrame(name="コマ1", image="コマ1.png", x=440, y=0, alpha=0%);
  CreateFrame(name="コマ2", image="コマ2.png", x="OutRight", y=65);
  CreateFrame(name="コマ3", image="コマ3.png", x=407, y=505
    , ox="Center", oy="Middle", sx=0%, sy=0%);
  CreateBalloon(name="台詞1", text="それにしても腹が減った"
    , x=620, y=110, tail=-30);
  CreateBalloon(name="台詞2", text="クククク…", x=485, y=525, 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");
  wait 1500;

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

  Enter(to="台詞2");
  wait 1000;
}

あちこち手を加えているが、何をしているのかは説明せずともだいたいわかるだろう。
ちなみにsx, sy, angle, alphaパラメータはCreate系命令でも指定することができる。

ひとまず完成だ!

YouTube Preview Image

まだまだかなり荒削りだが『動く漫画』を作る手順はざっとこんなかんじである。
随分面倒なんだな…と思っただろうか。
思ったより簡単だな…と思っただろうか。

こんにち、このような演出はFLASHやAfterEffectsのような
タイムラインをGUIに持つエディタを使って作成していくのが一般的だ。
そんな演出を全部スクリプトで構造的に書いてしまえるというのがFoooの面白い特徴だろう。


位置を抽象指定する

前回次のようなスクリプトを書いた。


method Main()
{
  CreateImage(name="画像", image="画像.png", x=640, y=360
    , ox=200, oy=300);
  Enter(to="画像");
  Zoom(to="画像", time=1000, sx=200%, sy=200%);
  Rotate(to="画像", time=1000, angle=45);
}

このスクリプトを見て…
画面の中心位置や画像の中心位置を指定するのに、
いちいち画面サイズや画像サイズを調べて、
中心位置が何ピクセルだとか計算しなくちゃいけないなんてちょっと面倒だな…
とは思わなかっただろうか。

実際面倒だ。

実はもっと簡単に記述する方法がある。

比率で指定する

x, y, ox, oyパラメータにはピクセル数による具体的な指定だけでなく、
『比率』による抽象的な指定をすることもできる。
比率で指定する場合は、数字の後に%記号をつける。


method Main()
{
  CreateImage(name="画像", image="画像.png", x=50%, y=50%
    , ox=50%, oy=50%);
  Enter(to="画像");
  Zoom(to="画像", time=1000, sx=200%, sy=200%);
  Rotate(to="画像", time=1000, angle=45);
}

非常に明快だ。

抽象名で指定する

x, y, ox, oyパラメータには『抽象名』を指定することもできる。
抽象名はデーカーの特定の状態を表す抽象的な名前だ。
抽象名を使うことで、値を簡単に指定できるだけでなく
その指定が何を意図しているのかより明確になる。


method Main()
{
  CreateImage(name="画像", image="画像.png", x="Center", y="Middle"
    , ox="Center", oy="Middle");
  Enter(to="画像");
  Zoom(to="画像", time=1000, sx=200%, sy=200%);
  Rotate(to="画像", time=1000, angle=45);
}

“Center”, “Middle”と書いているのが抽象名だ。
xには”OutLeft”=左外側, “Center”=中央, “OutRight”=右外側
yには”OutTop”=上外側, “Middle”=中央, “OutBottom”=下外側
oxには”Left”=左, “Center”=中央, “Right”=右
oyには”Top”=上, “Middle”=中央, “Bottom”=下
などがそれぞれ指定可能である。


原点を指定する

これまでFoooの動作サンプルを見てきて、
拡大や回転の動きがちょっと変だなと思わなかっただろうか。
よく見ればデーカーの拡大や回転が、画像の左上を基準に行われているのがわかるだろう。

バグか!? バグなのか!?

いやいやバグではない。
左上が基準になっていたのは、デーカーの『原点』の位置が
画像の左上の位置(0,0)になっていたからだ。

『原点』とはデーカーの姿勢(配置、拡大、回転)の基準として使われる点のことである。
原点はデーカー内の座標として設定される。

ox, oyパラメータ

原点位置はデーカーの作成時にox, oyパラメータで指定することができる。
oxは原点の横方向の位置、oyは原点の縦方向の位置を指定するパラメータだ。
(ちなみにox, oyという名前は、origin x, origin yの略)

回転拡大を画像の中心を基準に行わせるには、
ox, oyパラメータに画像の中心座標を指定すればよい。
ではさっそく原点位置を画像の中心にしてみよう。
“画像.png”のサイズは400×600ピクセルなので中心座標は(200,300)だ。


method Main()
{
  CreateImage(name="画像", image="画像.png", x=640, y=360
    , ox=200, oy=300);
  Enter(to="画像");
  Zoom(to="画像", time=1000, sx=200%, sy=200%);
  Rotate(to="画像", time=1000, angle=45);
}

実行してみよう。

YouTube Preview Image

画像の中心を基準に拡大、回転するようになった!
なお、原点位置を変えると見た目上の位置が変わってしまうので注意が必要だ。

ここではx, yパラメータに画面の中央位置を指定している。
デーカーの原点も中央位置なので、画面の中央に配置されたデーカーが
自身の中心を基準に拡大回転するという動きになっている…というわけだ。


命令を組み合わせる

さてさて今度は、移動と、拡縮と、回転と、半透明化をデーカーに同時にさせることを考えてみよう。

まーた新しい命令が出てくるの?

と思った人はちょっと早合点。
今回新しい命令は1つも出てこない。
なぜなら既に紹介したMove、Zoom、Rotate、Opaque命令を使えば実現可能なことだからだ。

答えから示そう。
次のように書けばいい。


method Main()
{
  CreateImage(name="画像", image="画像.png", x=50, y=50);
  Enter(to="画像");
  Move(to="画像", time=1000, x=200, y=200);
  Zoom(to="画像", time=1000, sx=200%, sy=200%);
  Rotate(to="画像", time=1000, angle=45);
  Opaque(to="画像", time=1000, alpha=50%);
}

ちょ、ちょ、ちょ、ちょっと待って!
重複した命令は中断されるって前回言ったじゃん!
………と思うかもしれない。

だがこれでいいのだ。
確かに重複した命令は中断されるのだが、それはあくまで”同じ種類の”命令が重複した場合の話だ。
実は……… “異なる種類の”命令はデーカーに同時に与えることができるのである。

論より証拠。
とりあえず実行してみよう。

YouTube Preview Image

デーカーに異なる種類の命令を同時に与えると、
デーカーはそれぞれの命令を同時に遂行する。
Move命令とZoom命令を同時に与えると「移動しながら拡縮する」
Rotate命令とOpaque命令を同時に与えると「回転しながら透明度を変える」
といった具合だ。

今回は4つの命令を同時に与えているので、
移動と、拡縮と、回転と、半透明化が同時に行われたというわけだ。
これは言い換えれば…

命令は組み合わせることができる

ということである。
時間をずらして命令の組み合わせることも可能だ。
さらにwait文と組み合わせて次のようなスクリプトを書いたらどうなるか、想像してみよう。


method Main()
{
  CreateImage(name="画像", image="画像.png", x=50, y=50);
  Enter(to="画像");
  Move(to="画像", time=1000, x=200, y=200);
  wait 500;
  Zoom(to="画像", time=1000, sx=200%, sy=200%);
  wait 500;
  Rotate(to="画像", time=1000, angle=45);
  wait 500;
  Opaque(to="画像", time=1000, alpha=50%);
}

こんな奇妙な動きになる。

YouTube Preview Image

Move、Zoom、Rotate、Opaque命令はそれぞれ単体ではシンプルな動きしか表現できないが
組み合わせることで表現の幅が劇的に広がる。
単純な機能の『組み合わせ』で、複雑で多様な表現を実現するというこの考え方は、
Foooの重要な基本概念である。