グループって何?
p5play での「グループ」とは、「同じ値と振る舞いをもつスプライトオブジェクト」の集合体であり、同時に、その設計図でもあります。『パックマン』のステージにある「エサ(ドット)」がいい例ですね!
group.length
プロパティで、グループ内のスプライト(グループスプライト)がいくつあるかを確認できます。この例では、 dots グループのグループスプライトが 24
個未満である限り、while ループ条件は真となります。
このコードサンプルでは、 new dots.Sprite
によって、 dots グループの設定である「色、y
座標、円の直径」が継承されたグループスプライトが生成されることを示しています。各ドットの x 座標は、グループスプライトの生成後に、一意の値が割り当てられています。
この仕組みを「ソフト継承」と呼びます。グループは、生成されるグループスプライトの設計図の役目も果たすためです。
グループとは配列であり、添字を使ってグループスプライトにアクセスできます。グループには、標準の JavaScript の配列メソッドを使用することができます。
グループのプロパティを、後から別の値に設定すると、グループスプライトのすべてがその影響を受けます! この仕組みを「ダイナミック継承」と呼びます。
moveTowards
のような移動関数をグループに使用すると、グループスプライトのすべてが移動します。
アロー関数プロパティセッター
グループのプロパティに、値ではなく「値を返すアロー関数 (=>
)
」を設定すると、そのグループスプライトの生成時には、その時点でのアロー関数の評価結果がプロパティ値となります(実行時評価)。これを「アロー関数プロパティセッター」と呼びます。
group.amount
が調整されると、グループは自動的に、設定した量に応じてグループスプライトを生成したり破棄したりします。
このコードサンプルでは、各宝石のスプライトが生成された時点で、アロー関数プロパティセッターによって、キャンバス内でランダムな x 座標と y 座標が割り当てられるようになります。
アロー関数プロパティセッターの仮引数
プロパティセッターのアロー関数には、仮引数を与えることができます。この仮引数には、新たに生成されるグループスプライトが紐づく、グループ配列の添字が与えられます!
例えばこのコードサンプルでは、アロー関数プロパティセッターの仮引数に i
が割り当てられていますが、これは生成されるグループスプライトと紐づく、グループ配列の添字のことです。これを利用すれば、新規グループスプライトを生成する際、必要に応じたプロパティの計算が可能です。
コリジョンとオーバーラップ
コリジョン(衝突)とオーバーラップ(重なり)を検出する関数は、スプライト同士だけにとどまりません。スプライトとグループ、グループ同士のコリジョンやオーバーラップさえも判定する事ができるのです。使用できる関数は次のとおりです:
collides
(衝突した瞬間), colliding
(衝突中/接触中), collided
(衝突後に離れた瞬間)overlaps
(重なった瞬間), overlapping
(重なり中),
overlapped
(重なりを終えた瞬間)
これらの関数を if
文で使う代わりに、関数の第 2
引数に、コールバック関数を与える方法もあります。コールバック関数は、コリジョンまたはオーバーラップのイベントが発生したときに「発火」します。このコールバック関数の引数は 2
つあり、それぞれ自身と相手のスプライトが割り当てられます。
このコードサンプルでは、コールバック関数はプレイヤースプライトとプレイヤーが重なっている gems グループ内の gem スプライトを受け取ります。その gem は回収され(破棄され)ます。
allSprites グループ
p5play は、スケッチ内のすべてのスプライトを含む allSprites
グループを生成します。
カスタムプロパティ
スプライトやグループには、独自のプロパティを追加できます。これは他の JavaScript オブジェクトと同様です!
また、グループにカスタムプロパティを追加すると、それらは新規グループスプライトに継承されます。アロー関数プロパティセッターすら、使用可能です。
サブグループ
このコードサンプルでは、 boxes
グループに 2 つの「サブグループ」があります。 smallBoxes
と
bigBoxes
です。
bigBoxes
グループを使用して生成した新しいグループスプライトは、 boxes
グループの設定をソフト継承しますが、
smallBoxes
グループからは継承しません。
boxes
グループのグループスプライトには、 smallBoxes
グループと bigBoxes
グループ、それぞれのグループスプライトのすべてが含まれます。
remove
関数は、グループそのものを削除します。そのため、そのグループを今後使うことはないときに限り使用してください。もし、グループスプライトをすべて削除したいだけで、グループは残したいという場合は、
removeAll
関数を使用してください。
カリング
デフォルトでは、スプライトはカメラの中心から 10000 ピクセルぶん離れると、削除されます。これは、ワールドが大きくなりすぎることで、物理シミュレーションが遅くなるのを防ぐためです。この仕組みを「カリング(間引き)」と呼びます。
この挙動の変更には、 allSprites.autoCull = false
を設定するか、 cull
関数を使って「カリングしきい値」を設定します(補足:キャンバスの端からのピクセル数)。コライダーを持たないグループスプライトも、カリング対象となります。
デフォルトでは、グループスプライトは、カリングしきい値を超えると削除されます。ただし、 cull
関数の最後の引数にコールバック関数を与えて実行した場合は、削除の代わりに(補足:削除が必要な場合は、コールバック関数内で、明示的に削除してください)そのコールバック関数が、対象のグループスプライトと、そのフレームでカリング対象になるグループスプライトの総数を、仮引数として受け取ります。
このコードサンプルでは、 1 フレームにつき複数のボールがカリングされると、ボールの数が減ることに注目してください。
生存期間
スプライトの存在に制限を設けるもう一つの方法は、そのスプライトが存在可能なフレーム数を life
(生存期間)プロパティに設定することです。スプライトの life が 0
に達すると、削除されます。これは、ショットやバリアといった、一時的なオブジェクトを作成するのに便利です。
このコードサンプルのミニゲームをやってみてください! マウスをクリックしてビーチボールを生成し、水の勢いで空中に浮かせてみましょう。
グループの描画
sprite.draw
関数と同様に、 group.draw
を使用して、p5.js の draw
ループ内でグループが描画されるタイミングを、手動で制御できます。
手動で描画されないスプライトやグループは、 autoDraw
プロパティが false に設定されていない限り、 p5.js の draw
ループの最後に自動的に描画されます。
スプライトやグループの描画を手動にして、なおかつカメラを使いたい場合、そのカメラのオン・オフは手動で行う必要があることに注意してください。
グループの描画更新
group.update
関数は、すべてのグループスプライトに対し、 sprite.update
関数を実行します。自動更新を防ぐには、
autoUpdate
を false に設定します。