煙を焚く

今度は煙を焚いてみよう。
これもやることは雪を降らすのとあまり変わらない。
まず煙の小さな塊を画像として用意する。

煙粒.png
Smoke


class 煙クラス
{
  method 煙クラス()
  {
  }

  method OnEnter()
  {
    int $number = 0;
    while(true)
    {
      string $name = "煙粒"+String($number++);
      ThreadCreate(call=@煙粒スレッド(name=$name));
      wait 100;
    }
  }

  method 煙粒スレッド(string $name)
  {
    CreateImage(name=$name
      , x=0, y=0, sx=20%, sy=20%, ox="Center", oy="Middle"
      , angle=rand_range(0,359), image="煙粒.png");
    Enter(to=$name);

    int $time = 2000;
    int $angle = 90+rand_range(-10,10);
    float $rad = radian(Float($angle));
    float $move = 300.0;
    float $x = $move*cos($rad);
    float $y = -$move*sin($rad);

    Move(to=$name, time=$time, x=$x, y=$y, step="DecSin");
    Zoom(to=$name, time=$time, sx=200%, sy=200%);
    Opaque(to=$name, time=$time, alpha=0%, step="AccSin");
    WaitDecor(to=$name);
    Delete(to=$name);
  }
}

method Main()
{
  CreateColor(name="背景", w=1280, h=720, color=black);
  Enter(to="背景");

  CreateObject(name="煙", x=1280/2, y=720/2+150, class=@煙クラス());
  Enter(to="煙");
}
YouTube Preview Image

今までと大きく違うのは1点から粒を放出するというところだ。
煙の塊をまばらに飛ばして拡大しながらだんだん透明にしていくと
このように煙が噴出してるかのような見た目になる。

「粒子の画像」と「粒子の動き方」をちょっと変えるだけで
同じような枠組みで様々な効果を作ることができることがわかるだろう。
このような粒子を用いた演出テクニックを一般的に

『パーティクルエフェクト』と言う。

これだけではあまりに簡単すぎてつまらないので
もうちょっと工夫してみよう。


class 煙クラス
{
  int $m_angle = 0;

  method 煙クラス()
  {
  }

  method OnEnter()
  {
    ThreadCreate(call=@煙発生スレッド());
  }

  method 煙発生スレッド()
  {
    int $number = 0;
    while(true)
    {
      string $name = "煙粒"+String($number++);
      ThreadCreate(call=@煙粒スレッド(name=$name));
      wait 100;
    }
  }

  method 煙粒スレッド(string $name)
  {
    CreateImage(name=$name
      , x=0, y=0, sx=20%, sy=20%, ox="Center", oy="Middle"
      , angle=rand_range(0,359), image="煙粒.png");
    Enter(to=$name);

    int $time = 2000;
    int $angle = 90+$m_angle+rand_range(-10,10);
    float $rad = radian(Float($angle));
    float $move = 300.0;
    float $x = $move*cos($rad);
    float $y = -$move*sin($rad);

    Move(to=$name, time=$time, x=$x, y=$y, step="DecSin");
    Zoom(to=$name, time=$time, sx=200%, sy=200%);
    Opaque(to=$name, time=$time, alpha=0%, step="AccSin");
    WaitDecor(to=$name);
    Delete(to=$name);
  }

  method 向き設定(int $angle)
  {
    operate $m_angle = $angle;
  }
}

method Main()
{
  CreateColor(name="背景", w=1280, h=720, color=black);
  Enter(to="背景");

  CreateObject(name="煙", x=1280/2, y=720/2+150, class=@煙クラス());
  Enter(to="煙");
  wait 2000;

  Request(to="煙", order=@向き設定(angle=45));
  wait 2000;

  Request(to="煙", order=@向き設定(angle=-45));
  wait 2000;

  Request(to="煙", order=@向き設定(angle=0));
  wait 2000;
}
YouTube Preview Image

煙を放つ向きを、Request命令で設定できるようにしてみた。
煙発生をOnEnterメソッドではなく、煙発生スレッドで行うようにしているが、
これはオブジェクトデーカーがメソッドの実行中にリクエストを受けると
実行中のメソッドを中断してしまうからだ。
スレッドがさらにスレッドを呼び出すという面白い構造になっているが
こういうことも可能なのである。


Leave a Reply

*