Skip to content
samme edited this page Aug 15, 2022 · 12 revisions

Groups are logical containers for game objects. They're not displayable (that would be a Container).

Groups are used for

  • Keeping a list of game objects (technically a set)
  • Batch creating game objects
  • Pooling (recycling) game objects
  • Calling a game object's update() method automatically

Creating groups

const group = this.add.group();

If you give a config argument it's interpreted as both GroupConfig and GroupCreateConfig, meaning it will create some members if key (texture) is included (see Batch creation. active is ambiguous.

Groups as lists

This is the simplest use for groups. It's like keeping an array but you don't have to worry about splicing members out. If you destroy a game object it gets removed from any groups it belongs to.

Game objects can belong to more than one group.

gems.add(gem);
collectibles.add(gem);
// …
collectibles.remove(gem);
inventory.add(gem);

Group size

The group size is group.getLength() or group.children.size.

Iterate a group

getChildren() and children.entries are identical.

for (const member of group.getChildren()) {
  /*…*/
}

group.getChildren().forEach((member) => {
  /*…*/
});

// With `iterate()` you must not add or remove group members during the loop
group.children.iterate((member) => {
  /*…*/
});

// With `each()` you may add or remove group members during the loop
group.children.each((member) => {
  /*…*/
});

Update group members

Use runChildUpdate to call group members' update() methods automatically. It will happen via the scene PRE_UPDATE event, before scene update(). Only active members are updated.

Updatable game objects should be in only one updating group, so they don't get updated twice per step.

const sprite = this.add.sprite(/*…*/);
sprite.update = function (time, delta) {
  /*…*/
};

const group = this.add.group({ runChildUpdate: true });
group.add(sprite);

You can toggle updates on or off:

group.runChildUpdate = false;

An inactive group doesn't update its children.

Groups in colliders

You pass a group directly to a collider.

this.add.overlap(group);

Batch creation

The classType must have constructor arguments (x, y, texture, frame), like Image or Sprite.

const group = this.add.group({
  classType: FancySprite,
  defaultKey: 'block',
  defaultFrame: 1,
});

group.create(0, 0);
group.create(0, 16);
group.create(0, 32);
// You must pass at least `key` (texture)
group.createMultiple({
  key: 'block',
  quantity: 12,
  createCallback: (member) => {
    /*…*/
  },
});

Beware that createMultiple() applies default values (setAlpha, setXY, etc.) after member constructors and createCallback are called.

Groups as pools

Space invaders as a group pool

In pooling you create game objects once and then recycle them as needed. Inactive game objects (also called dead or unused) are retrieved and reactivated when needed. Active game objects (also called alive or used) are deactivated when no longer needed. You will usually toggle a game object's visibility at the same time. In Arcade Physics groups, you should toggle body.enabled as well.

You can use getFirstAlive(false) and getFirstDead(false) to select (not create) existing pool members that are active or inactive, respectively.

For creation/reactivation you usually use get(), which is a shortcut for getFirstDead(true).

console.log(
  '%s | size: %d | max: %d | active: %d | inactive: %d | used: %d | free: %d | full: %s',
  group.name,
  group.getLength(),
  group.maxSize,
  group.countActive(true),
  group.countActive(false),
  group.getTotalUsed(),
  group.getTotalFree(),
  group.isFull()
);

Physics groups

Clone this wiki locally