提供:Japanese Scratch-Wiki
パーティクル効果とは、炎、爆発、火花、雲、霧などを小さな粒(粒子:パーティクル)が集まったものとみなし、それらの粒子の動きを再現することで得られるグラフィック効果のことである。
このチュートリアルでは、「火花」の効果を実現するスクリプトを例に、クローンを使ってパーティクル効果を実現する方法を説明する。そして、このコードを最適化して、他の人が簡単に自分のプロジェクトに組み込めるようなカスタムブロックを使ったパッケージの形に整理する。
スクリプト例
火花効果の生成
まずは、親となるスプライトを生成する必要がある。火花を表現する粒子 (パーティクル) は、すべてこのスプライトから生成される。なお、スプライト自身は、粒子として使用されることはない。スクリプトの概要は次のようになる:
- 火花を生成する場所に移動する
- クローンを10個作成する。これらはそれぞれ火花を構成する粒子となる。
- 粒子の生成が終わったら、それぞれの粒子は飛び散り、落下していく。これを全体で見ると、火花が散っているように見える。
まずは「火花」という名前のスプライトを生成して、コスチュームとして1×1ピクセルのオレンジの点を描画する。

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

それでは、クローンを作成して、「クローンされたとき」ブロックの下に、次のような放物線で移動するスクリプトを作成する。
[スペース 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
なお、上記で説明した以外にも、このスクリプトでは、より目立つように火花の量を増やしている。
コードを配布する
作成した火花ライブラリを配布するときは、どのスプライトからでも使用できるよう処理をカスタムブロックにまとめておき、ユーザーからのメッセージを受け取ったとき火花を発生するようにすべきだ。
ここでは火花ライブラリで使用する情報を他のスプライトとやりとりするために、グローバルなリスト「(火花)設定」を作成している。このリストには、次の情報を順番に入れるものとする:
- 発生位置のX座標
- 発生位置のY座標
- 火花の色
これらを反映すると、次のようなスクリプトになる:
[スペース 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) にする 火花発生 ([(火花)設定 v] の (1 v) 番目) ([(火花)設定 v] の (2 v) 番目) :: custom
次に、このようにして作った火花ライブラリをほかのスプライトから使用するサンプルも記載しておく。
[スペース v] キーが押されたとき 火花発生の効果 x: (マウスのx座標) y: (マウスのy座標) 色: ((1) から (200) までの乱数) :: custom 定義 火花発生の効果 x: (x) y: (y) 色: (色) [(火花)設定 v] の (1 v) 番目を (x) で置き換える [(火花)設定 v] の (2 v) 番目を (y) で置き換える [(火花)設定 v] の (3 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 ずっと もし <([(火花)設定 v] の(4 v) 番目) = [new]> なら [(火花)設定 v] の (4 v) 番目を [] で置き換える [色 v] の効果を ([(火花)設定 v] の (3 v) 番目) にする 火花発生 ([(火花)設定 v] の (1 v) 番目) ([(火花)設定 v] の (2 v) 番目) :: custom end end [スペース v] キーが押されたとき 火花発生の効果 x: (マウスのx座標) y: (マウスのy座標) 色: ((1) から (200) までの乱数) :: custom 定義 火花発生の効果 x: (x) y: (y) 色: (色) [(火花)設定 v] の (1 v) 番目を (x) で置き換える [(火花)設定 v] の (2 v) 番目を (y) で置き換える [(火花)設定 v] の (3 v) 番目を (color) で置き換える [(火花)設定 v] の (4 v) 番目を [new] で置き換える