提供: Japanese Scratch-Wiki

このきじは ひらがなのページがありません。ごめんなさい。
パーティクル効果とは、炎、爆発、火花、雲、霧などを小さな粒(粒子:パーティクル)が集まったものとみなし、それらの粒子の動きを再現することで得られるグラフィック効果のことである。

このチュートリアルでは、「火花」の効果を実現するスクリプトを例に、クローンを使ってパーティクル効果を実現する方法を説明する。そして、このコードを最適化して、他の人が簡単に自分のプロジェクトに組み込めるようなカスタムブロックを使ったパッケージの形に整理する。

スクリプト例

火花効果の生成

まずは、親となるスプライトを生成する必要がある。火花を表現する粒子 (パーティクル) は、すべてこのスプライトから生成される。なお、スプライト自身は、粒子として使用されることはない。スクリプトの概要は次のようになる:

  • 火花を生成する場所に移動する
  • クローンを10個作成する。これらはそれぞれ火花を構成する粒子となる。
  • 粒子の生成が終わったら、それぞれの粒子は飛び散り、落下していく。これを全体で見ると、火花が散っているように見える。

まずは「火花」という名前のスプライトを生成して、コスチュームとして1×1ピクセルのオレンジの点を描画する。

Warning メモ: ここでペンによる描画でなくコスチュームを使う理由は、ペンの場合、プロジェクトのほかの部分で「消す」ブロックを使用したとき、パーティクル効果も一緒に消えてしまうからである。

次に、ローカル変数 の「x速度」と「y速度」を作成する (変数の生成ダイアログで「このスプライトのみ」を選択する)。

Warning メモ: この例のように、他のユーザーに使用してもらうスクリプトを作るときは、可能な限りローカル変数を使うこと。使用するユーザーのパレットが大量の変数で埋まってしまうのを防止するだけでなく、ユーザーが同じ名前の変数を使用している場合でも、エラーを避けられるからだ。どうしてもグローバル変数が必要なときは、変数名に接頭辞をつけておくと良いだろう。たとえば、「色」という変数名の代わりに、「(火花).色」のような名前を付ける例が考えられる

それでは、クローンを作成して、「クローンされたとき」ブロックの下に、次のような放物線で移動するスクリプトを作成する。

[スペース v] キーが押されたとき
(10) 回繰り返す
  [自分自身 v] のクローンを作る
end

クローンされたとき
[x速度 v] を (((-5) から (5) までの乱数) / (3)) にする
[y速度 v] を ((1) から (10) までの乱数) にする
(20) 回繰り返す
  x座標を (x速度) ずつ変える
  y座標を (y速度) ずつ変える
  [y速度 v] を (-1) ずつ変える
end
このクローンを削除する

ここまで作成したら、スペースキーを押してスクリプトを実行してみよう。

x速度とy速度がクローンごとに別の値となり、混じり合ったりすることがないことがわかるはずだ。「このスプライトのみ」を指定した変数は、クローンされた範囲でのみ読み書きできる (レキシカルスコープを持つ) ため、 それぞれのクローンはそれぞれのx速度とy速度を持っており、その値がお互い影響し合うことはない。

このスクリプトには1つ問題がある。スペースキーを連続して押した場合、火花の粒子自身がさらに複製されてしまう (クローンのクローンが作成されてしまう) という点だ。これは明らかに適切な挙動とはいえない。そこで、次にクローンかどうかを判別するための変数を追加する。

@greenFlag が押されたとき::events hat
[クローン? v] を [no] にする

[スペース v] キーが押されたとき
もし <(クローン?) = [no]> なら
  (10) 回繰り返す
    [自分自身 v] のクローンを作る
  end
end

クローンされたとき
[クローン? v] を [yes] にする
[x速度 v] を (((-5) から (5) までの乱数) / (3)) にする
[y速度 v] を ((1) から (10) までの乱数) にする
(20) 回繰り返す
  x座標を (x速度) ずつ変える
  y座標を (y速度) ずつ変える
  [y速度 v] を (-1) ずつ変える
end
このクローンを削除する

「クローン?」変数は、元のスプライトとクローンを区別するために使用されている。この変数もローカル変数にしておくのを忘れないようにしてほしい。なお、この問題は、「スペースキーが押されたとき」ブロックを次のように書き換える方法でも解決できる。

@greenFlag が押されたとき::events hat
ずっと
  もし <[スペース v] キーが押された> なら
    (10) 回繰り返す
      [自分自身 v] のクローンを作る
    end
  end
end

改良

この節では、火花エンジンに次の改良を加える:

  • 火花が突然ではなく徐々に生成されるようにする(クローンを作成するタイミングを調整して、よりリアルな火花にする)
  • 火花が徐々に薄くなり、すーっと消えていくようにする (幽霊の効果を使う)

それ以外に、本来、見えるべきでない親スプライトを隠し、さらに、火花の生成部分をカスタムブロックにまとめておくことにする。

@greenFlag が押されたとき::events hat
[クローン? v] を [no] にする
隠す

クローンされたとき
表示する
[クローン? v] を [yes] にする
[x速度 v] を (((-5) から (5) までの乱数)/ (3)) にする
[y速度 v] を ((1) から (10) までの乱数) にする
(20) 回繰り返す
  [幽霊 v] の効果を (5) ずつ変える
  x座標を (x速度) ずつ変える
  y座標を (y速度) ずつ変える
  [y速度 v] を (-1) ずつ変える
end
このクローンを削除する

定義 火花発生 (x)(y)
x座標を (x) 、y座標を (y) にする
[生成タイミング v] を [-0.03] にする
もし <(クローン?) = [no]> なら
  (10) 回繰り返す
    [生成タイミング v] を (0.001) ずつ変える
    ((生成タイミング) * (生成タイミング)) 秒待つ
    [自分自身 v] のクローンを作る
    [自分自身 v] のクローンを作る
    [自分自身 v] のクローンを作る
    [自分自身 v] のクローンを作る
  end
end

[スペース v] キーが押されたとき
火花発生 (1) (1)::custom


なお、上記で説明した以外にも、このスクリプトでは、より目立つように火花の量を増やしている。

コードを配布する

作成した火花ライブラリを配布するときは、どのスプライトからでも使用できるよう処理をカスタムブロックにまとめておき、ユーザーからのメッセージを受け取ったとき火花を発生するようにすべきだ。

ここでは火花ライブラリで使用する情報を他のスプライトとやりとりするために、グローバルなリスト「(火花)設定」を作成している。このリストには、次の情報を順番に入れるものとする:

  1. 発生位置のX座標
  2. 発生位置のY座標
  3. 火花の色

これらを反映すると、次のようなスクリプトになる:

[スペース v] キーが押されたとき
火花発生 (1) (1)::custom

定義 火花発生 (x) (y)
x座標を (x) 、y座標を (y) にする
[生成タイミング v] を [-0.002] にする
もし <(クローン?) = [no]> なら
  (3) 回繰り返す
    [生成タイミング v] を (0.005) ずつ変える
    ((生成タイミング) * (生成タイミング)) 秒待つ
    [自分自身 v] のクローンを作る
    [自分自身 v] のクローンを作る
    [自分自身 v] のクローンを作る
    [自分自身 v] のクローンを作る
  end
end

クローンされたとき
表示する
[クローン? v] を [yes] にする
[x速度 v] を (((-5) から (5) までの乱数) / (3)) にする
[y速度 v] を ((1) から (10) までの乱数) にする
(20) 回繰り返す
  [幽霊 v] の効果を (5) ずつ変える
  x座標を (x速度) ずつ変える
  y座標を (y速度) ずつ変える
  [y速度 v] を (-1) ずつ変える
end
このクローンを削除する

@greenFlag が押されたとき::events hat
[クローン? v] を [no] にする
隠す

[(火花)発生 v] を受け取ったとき
[色 v] の効果を ((3 v) 番目( [(火花)設定 v] ) :: list) にする
火花発生 ((1 v) 番目( [(火花)設定 v] ) :: list) ((2 v) 番目( [(火花)設定 v] ) :: list) :: custom

次に、このようにして作った火花ライブラリをほかのスプライトから使用するサンプルも記載しておく。

[スペース v] キーが押されたとき
火花発生の効果 x: (マウスのx座標) y: (マウスのy座標) 色: ((1) から (200) までの乱数) :: custom

定義 火花発生の効果 x: (x) y: (y) 色: (色)
(1 v) 番目( [(火花)設定 v] )を (x) で置き換える
(2 v) 番目( [(火花)設定 v] )を (y) で置き換える
(3 v) 番目( [(火花)設定 v] )を (色) で置き換える
[(火花)発生 v] を送る

ただし、このスクリプトには、1回火花を発生させたあと、それが終わらない間にもう一度火花を発生させると、古い方の効果が止まってしまうという問題がある。メッセージの送受信を使っていることが原因である。これを避けるには、メッセージの代わりに、トリガー変数を使用すればよい。

そこで以下では、「(火花)設定」リストの4番目に新しい項目を追加して、新たな火花が発生するたびに値を「new」にしている。これによってライブラリ側は火花の発生要求を検知できるので、火花を発生させて、その後、この値をリセットする。

@greenFlag が押されたとき::events hat
[クローン? v] を [no] にする
隠す

クローンされたとき
表示する
[クローン? v] を [yes] にする
[x速度 v] を (((-5) から (5) までの乱数) / (3)) にする
[y速度 v] を ((1) から (10) までの乱数) にする
(20) 回繰り返す
[幽霊 v] の効果を (5) ずつ変える
x座標を (x速度) ずつ変える
y座標を (y速度) ずつ変える
[y速度 v] を (-1) ずつ変える
end
このクローンを削除する

定義 火花発生 (x) (y)
x座標を (x) 、y座標を (y) にする
[生成タイミング v] を [-0.002] にする
もし <(クローン?) = [no]> なら
  (3) 回繰り返す
    [生成タイミング v] を (0.005) ずつ変える
    ((生成タイミング) * (生成タイミング)) 秒待つ
    [自分自身 v] のクローンを作る
    [自分自身 v] のクローンを作る
    [自分自身 v] のクローンを作る
    [自分自身 v] のクローンを作る
  end
end

@greenFlag が押されたとき::events hat
ずっと
  もし <((4 v) 番目 [(火花)設定 v] :: list) = [new]> なら
    (4 v) 番目( [(火花)設定 v] )を [] で置き換える
    [色 v] の効果を ((3 v) 番目( [(火花)設定 v] ) :: list) にする
    火花発生 ((1 v) 番目([(火花)設定 v]) :: list) ((2 v) 番目([(火花)設定 v]):: list) :: custom
  end
end

[スペース v] キーが押されたとき
火花発生の効果 x: (マウスのx座標) y: (マウスのy座標) 色: ((1) から (200) までの乱数) :: custom

定義 火花発生の効果 x: (x) y: (y) 色: (色)
(1 v) 番目( [(火花)設定 v] )を (x) で置き換える
(2 v) 番目( [(火花)設定 v] )を (y) で置き換える
(3 v) 番目( [(火花)設定 v] )を (color) で置き換える
(4 v) 番目( [(火花)設定 v] )を [new] で置き換える

関連項目