You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When an object is added to a container, ADDED_TO_SCENE is never called. This is an issue because many objects use these events to manage whether they are in the updateList as well.
For example,
Sprite animations use the update list
DOM elements that need to know when to hide themselves use the update list
Both of these break when used in a container, except if the object is first added to the scene and then added to the container in the same frame.
Example Test Code
class MainScene extends Phaser.Scene {
preload() {
this.load.spritesheet("mummy", mummyURL, {
frameWidth: 37,
frameHeight: 45
});
}
create() {
const mummyAnimation = this.anims.create({
key: "walk",
frames: this.anims.generateFrameNumbers("mummy"),
frameRate: 16
});
// V1 (doesn't work)
this.makeSpriteV1();
// V2 (doesn't work)
// this.makeSpriteV2();
// V3 (does work)
// this.makeSpriteV3();
}
makeSpriteV1() {
const sprite = this.add.sprite(50, 50, "mummy");
this.sprite = sprite;
// Wait until sprite gets properly added to updateList
// so that it isn't in _pending anymore
this.time.delayedCall(1, () => this.addSpriteToContainer());
}
makeSpriteV2() {
// The sprite is never added to the display list at all
const sprite = new Phaser.GameObjects.Sprite(this, 50, 50, "mummy");
this.sprite = sprite;
this.addSpriteToContainer();
}
makeSpriteV3() {
// Sprite is added to `updateList._pending`
const sprite = this.add.sprite(50, 50, "mummy");
this.sprite = sprite;
this.addSpriteToContainer();
// Sprite was added to container, hence removed from displayList
// so it is in `updateList._destroyed` as well
// but it is also in pending
// so a little bit accidentally it does end up in the updateList after all
}
addSpriteToContainer() {
const container = this.add.container(100, 100, [this.sprite]);
this.sprite.play({ key: "walk", repeat: 7 });
}
}
In the example above (see https://codepen.io/prakol16/pen/YzQXxpg for the codepen), the mummy's animation doesn't run, except in V3. The reason it works in V3 seems to be something of an accident; when the sprite is first added to the scene, it is added to the update list, and hence added to updateList._pending. Then, when it is added to the container, it is added to updateList._destroy. (This is also kind of a bug, because I think a more expected behavior is that updateList.remove first checks if the item is in _pending, and removes it from _pending if so; otherwise it queues it to be destroyed). Luckily, when these queued events are resolved, it seems _destroy is executed first, and so it is "removed," (when it wasn't in _active to begin with) and then added back from _pending.
If we add a 1 ms delay, so that the sprite properly moves to _active, before adding it to the container, or if we simply never added it to _pending at all by not using the factory constructor, the bug shows up.
The text was updated successfully, but these errors were encountered:
… in the same frame were not correctly removed from the UpdateList. Fix#5803#5817#5818#6052
* `ProcessQueue.isActive` is a new method that tests if the given object is in the active list, or not.
* `ProcessQueue.isPending` is a new method that tests if the given object is in the pending insertion list, or not.
* `ProcessQueue.isDestroying` is a new method that tests if the given object is pending destruction, or not.
* `ProcessQueue.add` will no longer place the item into the pending list if it's already active or pending.
* `ProcessQueue.remove` will check if the item is in the pending list, and simply remove it, rather than destroying it.
Thank you for submitting this issue. We have fixed this and the fix has been pushed to the master branch. It will be part of the next release. If you get time to build and test it for yourself we would appreciate that.
Version
Description
When an object is added to a container,
ADDED_TO_SCENE
is never called. This is an issue because many objects use these events to manage whether they are in theupdateList
as well.For example,
Both of these break when used in a container, except if the object is first added to the scene and then added to the container in the same frame.
Example Test Code
In the example above (see https://codepen.io/prakol16/pen/YzQXxpg for the codepen), the mummy's animation doesn't run, except in V3. The reason it works in V3 seems to be something of an accident; when the sprite is first added to the scene, it is added to the update list, and hence added to
updateList._pending
. Then, when it is added to the container, it is added toupdateList._destroy
. (This is also kind of a bug, because I think a more expected behavior is thatupdateList.remove
first checks if the item is in_pending
, and removes it from_pending
if so; otherwise it queues it to be destroyed). Luckily, when these queued events are resolved, it seems_destroy
is executed first, and so it is "removed," (when it wasn't in_active
to begin with) and then added back from_pending
.If we add a 1 ms delay, so that the sprite properly moves to
_active
, before adding it to the container, or if we simply never added it to_pending
at all by not using the factory constructor, the bug shows up.The text was updated successfully, but these errors were encountered: