グループって何?

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 つの「サブグループ」があります。 smallBoxesbigBoxes です。

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 に設定します。

前へ 次へ