Destroying Game Objects in Phaser 4
In Phaser 4, destroy() is the method you use when a game object should be removed completely from the scene.
This is different from setVisible(false) or setActive(false). Those only hide or deactivate an object. destroy() permanently removes it.
What destroy() Does
When you call:
enemy.destroy();
Phaser removes that object from the scene and cleans up its internal references. After that, the object should not be used again.
When to Use destroy()
Use destroy() when the object is no longer needed at all:
- temporary effects
- one-time UI elements
- a boss after defeat
- a scene-specific object
- removed containers or text
Example:
this.gameOverText.destroy();
Basic Example
create() {this.message = this.add.text(400, 300, 'Hello', {fontSize: '32px',color: '#ffffff'}).setOrigin(0.5);}removeMessage() {this.message.destroy();}
After destroy(), the text is gone permanently.
destroy() vs setVisible(false)
object.setVisible(false);
- hides the object
- object still exists
object.destroy();
- removes the object
- object no longer exists
If you may need the object again later, do not destroy it. Use visibility or active state instead. You can read more in our guide on Visibility and Active States in Phaser 4.
destroy() vs setActive(false)
object.setActive(false);
- disables active logic
- object still exists
object.destroy();
- removes the object entirely
Important Rule
After destroying an object, do not keep using it:
this.player.destroy();this.player.setVisible(true); // wrong
Once destroyed, the reference may still exist in JavaScript, but the game object is no longer valid for gameplay use.
Common Use Case: Bullet Cleanup
if (bullet.x > 800) {bullet.destroy();}
This is fine if bullets are created occasionally. But if you create many bullets, object pooling is usually better than destroying and recreating constantly.
Common Use Case: Temporary Text
const winText = this.add.text(400, 300, 'You Win!', {fontSize: '48px',color: '#00ff00'}).setOrigin(0.5);this.time.delayedCall(2000, () => {winText.destroy();});
This shows text for 2 seconds, then removes it.
Destroying Containers
If you destroy a container, its children are usually removed with it:
this.panel.destroy();
This is useful for menus, popups, and overlays that should disappear completely.
Physics Objects
If the object has a physics body, destroying the game object also removes it from the scene, but you should still be careful with references in your own code.
if (enemy) {enemy.destroy();enemy = null;}
Setting the variable to null helps avoid accidental reuse.
Best Practices
- Use
destroy()only for permanent removal. - Use
setVisible(false)if you want to hide something temporarily. - Use
setActive(false)if you want to pause logic without removing the object. - Prefer object pooling for bullets, enemies, and repeated effects.
- Clear your references after destruction when needed.
Quick Cheat Sheet
// Hide onlyobject.setVisible(false);// Deactivate onlyobject.setActive(false);// Remove permanentlyobject.destroy();
Simple Rule
- Hide it?
setVisible(false) - Disable it?
setActive(false) - Remove it forever?
destroy()
FAQ
What does destroy() do in Phaser 4?
destroy()permanently removes a game object from the scene and clears Phaser's internal references to it. After that, the object should not be used again.
What is the difference between destroy() and setVisible(false)?
setVisible(false) only hides an object while keeping it in memory. destroy() removes the object permanently from the scene.
Should I use destroy() for bullets in Phaser 4?
If bullets are created only occasionally, destroy() is acceptable. But in action-heavy games, object pooling is usually better for performance.
Should I clear my references after destroy()?
Yes. In many cases, setting your own variables to null after destruction helps prevent accidental reuse of invalid references.
Conclusion
destroy() is the right tool when a game object should be removed permanently. But if you only want to hide something or pause its logic temporarily, use visibility and active state controls instead.