スレッド化する

前回はフェードインメソッドを作ったが、
今度はフェードインした後一定時間経ったらフェードアウトするメソッドを作ってみよう。
フェードインメソッドをちょちょいと細工して…


method フェードインアウト(color $色=white, string $合成="Normal"
  , int $フェード=1000, int $待ち=0)
{
  CreateColor(name="幕", color=$色, w=1280, h=720, blend=$合成);
  Enter(to="幕");
  wait 500;

  Opaque(to="幕", time=$フェード, alpha=0%, step="DecSin");
  wait $フェード;

  wait $待ち;

  Opaque(to="幕", time=$フェード, alpha=100%, step="AccSin");
  wait $フェード;
}

こんなかんじでよさそうだ。
幕を作って500ms経過してからフェードインしはじめ、
フェードインが終わったら待ち時間分だけ待ってフェードアウトする…という流れだ。
それでは組み込んでみよう。


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

#base_param CreateBalloon(style="普通")
#base_param CreateFrame(outline_shape="Vivide"
  , outline_color=white, outline_thick=8)

method フェードインアウト(color $色=white, string $合成="Normal"
  , int $フェード=1000, int $待ち=0)
{
  CreateColor(name="幕", color=$色, w=1280, h=720, blend=$合成);
  Enter(to="幕");
  wait 500;

  Opaque(to="幕", time=$フェード, alpha=0%, step="DecSin");
  wait $フェード;

  wait $待ち;

  Opaque(to="幕", time=$フェード, alpha=100%, step="AccSin");
  wait $フェード;
}

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

  CreateNode(name="コマ1"
    , x=642, y=0, sx=0%);
  CreateWindow(name="コマ1/窓"
    , w=405, h=720, ox="Center", propagation="CancelParentZoom");
  CreateImage(name="コマ1/窓/画像", image="コマ1.png"
    , x=20, y=324, ox="Center", oy="Middle", sx=110%, sy=110%
    , sampling="BieLinear");
  CreateOutline(name="コマ1/枠"
    , w=405, h=720, shape="Fade", color=RGBA(0,0,0,64), thick=8
    , ox="Center", adaptive=true);

  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%
    , outline_color=black);

  CreateBalloon(name="台詞1"
    , 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);

  Enter(to="背景");
  Enter(to="コマ1");
  Enter(to="コマ1/窓");
  Enter(to="コマ1/窓/画像");
  Enter(to="コマ1/枠");

  call @フェードインアウト(色=white, 合成="Add", 待ち=5000);

  Zoom(to="コマ1", time=1000, sx=100%, step="DecSin");
  Move(to="コマ1/窓/画像", time=1000, x=-20, 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

………止まっちゃってるし!

何がいけなかったのか。
というか………こうなるのは至極当たり前である。
フェードインアウトメソッドを呼び出すと処理はフェードインアウトメソッドに移り、
その実行が終わるまでMainメソッドには戻ってこないからだ。

これはそもそもフェードインとフェードアウトを
1つのメソッドにしてしまうことに無理がありそうだ。
しかしその無理を通す方法が、実はある。
それが『スレッド化』だ。

スレッドとは筋、糸という意味だが、
プログラミング用語では同時進行する処理の1つの流れのことを意味する。
メソッドは通常の呼び出し方とは別に、スレッドとして呼び出すことができる。
メソッドをスレッドとして呼び出すと、呼び出したメソッドは呼び出し元と

同時進行で実行される。

これはメソッドをある種の命令のようにみなせるということでもある。
命令の実行完了を待つ必要がないのと同じように、
スレッドも実行完了を待つ必要が無いのだ。

ThreadCreate命令

メソッドをスレッドとして呼び出すにはThreadCreate命令を使う。


ThreadCreate(call=@フェードインアウト(色="white", 合成="Add", 待ち=5000));

call文とさほど表記は変わらない。
フェードインアウトメソッドをスレッドとして呼び出すとどうなるのか…
とにもかくにも組み込んでみよう。
違いはごくわずかだ。


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

#base_param CreateBalloon(style="普通")
#base_param CreateFrame(outline_shape="Vivide"
  , outline_color=white, outline_thick=8)

method フェードインアウト(color $色=white, string $合成="Normal"
  , int $フェード=1000, int $待ち=0)
{
  CreateColor(name="幕", color=$色, w=1280, h=720, blend=$合成);
  Enter(to="幕");
  wait 500;

  Opaque(to="幕", time=$フェード, alpha=0%, step="DecSin");
  wait $フェード;

  wait $待ち;

  Opaque(to="幕", time=$フェード, alpha=100%, step="AccSin");
  wait $フェード;
}

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

  CreateNode(name="コマ1"
    , x=642, y=0, sx=0%);
  CreateWindow(name="コマ1/窓"
    , w=405, h=720, ox="Center", propagation="CancelParentZoom");
  CreateImage(name="コマ1/窓/画像", image="コマ1.png"
    , x=20, y=324, ox="Center", oy="Middle", sx=110%, sy=110%
    , sampling="BieLinear");
  CreateOutline(name="コマ1/枠"
    , w=405, h=720, shape="Fade", color=RGBA(0,0,0,64), thick=8
    , ox="Center", adaptive=true);

  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%
    , outline_color=black);

  CreateBalloon(name="台詞1"
    , 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);

  Enter(to="背景");
  Enter(to="コマ1");
  Enter(to="コマ1/窓");
  Enter(to="コマ1/窓/画像");
  Enter(to="コマ1/枠");

  ThreadCreate(call=@フェードインアウト(色=white, 合成="Add", 待ち=5000));
  wait 500;

  Zoom(to="コマ1", time=1000, sx=100%, step="DecSin");
  Move(to="コマ1/窓/画像", time=1000, x=-20, 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

フェードインアウトが同時進行している様子がわかるだろう。
スレッドはちょっととっつきにくい印象があると思うが、
演出が複雑に入り組む場合非常に便利な機能である。


Leave a Reply

*