Visibility and Active States in Phaser 4: Controlling What Game Objects Do and Show
In Phaser 4, every game object can have two important states:
- Visibility: whether the object is shown on the screen.
- Active state: whether the object is considered active in the game logic.
These two concepts may look similar at first, but they are not the same. Understanding the difference between visible and active is important for building clean scenes, UI systems, menus, enemies, bullets, pickups, and reusable game objects.
In this guide, you'll learn how visibility and active states work in Phaser 4, when to use them, and how to avoid common mistakes.
What Is Visibility in Phaser 4?
Visibility controls whether a game object is rendered on the screen.
If an object is visible, the player can see it. If it is invisible, the object still exists, but it is not drawn.
const player = this.add.image(400, 300, 'player');player.setVisible(false);
This hides the player from the screen. To show it again:
player.setVisible(true);
The visible Property
Every visible game object has a visible property:
player.visible = false;player.visible = true;
However, in most cases, using setVisible() is cleaner and more readable because it supports method chaining, which you can read more about in our guide on Mastering Origin and Anchor in Phaser 4.
What Is Active State in Phaser 4?
The active state controls whether a game object is considered active by the game systems. An active object is usually treated as part of the running game logic. An inactive object still exists, but it can be ignored by certain systems, groups, or custom logic.
const enemy = this.add.image(500, 300, 'enemy');enemy.setActive(false);
This marks the enemy as inactive. To activate it again:
enemy.setActive(true);
The active Property
You can also use the active property directly:
enemy.active = false;
Visibility vs Active State
This is the key difference:
| State | Controls | Does Object Still Exist? | Is It Rendered? |
|---|---|---|---|
| visible | What the player sees | Yes | No, if false |
| active | Whether the object is active in logic | Yes | Can still be visible |
| destroy() | Removes the object from memory | No | No |
The most important points: setVisible(false) hides the object, but does not automatically stop your game logic from using it. Similarly, setActive(false) marks the object inactive, but does not automatically make it invisible.
Basic Example
create() {this.enemy = this.add.image(400, 300, 'enemy');this.enemy.setVisible(false);this.enemy.setActive(false);}
This enemy still exists in memory but is not visible and is marked as inactive. Later, you can bring it back:
this.enemy.setVisible(true);this.enemy.setActive(true);
Hiding a Game Object
To hide an object:
this.player.setVisible(false);
This is useful for:
- Hiding UI panels and settings menus.
- Hiding pause screens.
- Temporarily hiding characters during transitions.
- Showing and hiding tutorial text prompts.
create() {this.pauseText = this.add.text(400, 300, 'Paused', {fontSize: '48px',color: '#ffffff'}).setOrigin(0.5);this.pauseText.setVisible(false);}
Now the pause text exists, but the player cannot see it until called:
pauseGame() {this.pauseText.setVisible(true);}resumeGame() {this.pauseText.setVisible(false);}
Deactivating a Game Object
To deactivate an object:
this.enemy.setActive(false);
This is useful when an object should temporarily stop participating in game logic:
update() {if (!this.enemy.active) {return;}this.enemy.x -= 2;}
Combining setVisible() and setActive()
In real games, you will frequently chain these methods together to manage state changes efficiently:
this.enemy.setVisible(false).setActive(false);
To bring it back:
this.enemy.setVisible(true).setActive(true);
Practical Example: Enemy Spawn System
Instead of destroying and recreating enemies repeatedly, you can hide and deactivate them to build an efficient recycling pipeline.
create() {this.enemy = this.add.image(800, 300, 'enemy');this.enemy.setVisible(false).setActive(false);}spawnEnemy() {this.enemy.setPosition(800, 300);this.enemy.setVisible(true).setActive(true);}update() {if (!this.enemy.active) {return;}this.enemy.x -= 3;if (this.enemy.x < -50) {this.enemy.setVisible(false).setActive(false);}}
Practical Example: UI Panel Toggle
Visibility toggles are perfect for UI systems:
create() {this.settingsPanel = this.add.container(400, 300);const background = this.add.rectangle(0, 0, 300, 200, 0x000000, 0.8);const title = this.add.text(0, -70, 'Settings', {fontSize: '32px',color: '#ffffff'}).setOrigin(0.5);this.settingsPanel.add([background, title]);this.settingsPanel.setVisible(false);}toggleSettings() {const isVisible = this.settingsPanel.visible;this.settingsPanel.setVisible(!isVisible);}
Does setVisible(false) Stop Collision?
No, not automatically. This is a common beginner mistake. If an object is invisible, it may still exist in the game world and trigger physics collisions. That is why you should disable the physics body too:
coin.setVisible(false).setActive(false);if (coin.body) {coin.body.enable = false;}
setVisible() vs destroy()
Use destroy() only when you are permanently deleting an object and want to free memory. Use setVisible(false) and setActive(false) when you want to recycle objects or toggle UI elements.
Complete Phaser 4 Example
export default class MainScene extends Phaser.Scene {constructor() {super({ key: 'MainScene' });}preload() {this.load.image('enemy', 'assets/enemy.png');this.load.image('coin', 'assets/coin.png');}create() {this.enemy = this.add.image(800, 300, 'enemy');this.coin = this.add.image(400, 250, 'coin');this.enemy.setVisible(false).setActive(false);this.time.delayedCall(2000, () => {this.spawnEnemy();});}spawnEnemy() {this.enemy.setPosition(800, 300);this.enemy.setVisible(true).setActive(true);}update() {if (this.enemy.active) {this.enemy.x -= 3;if (this.enemy.x < -50) {this.enemy.setVisible(false).setActive(false);}}}}
Common Mistakes
- Thinking Invisible Means Inactive: Calling only
setVisible(false)will keep your update loops and collisions running on that object. - Thinking Inactive Means Invisible: Calling only
setActive(false)will stop updates but leave the object rendered on screen. - Destroying Objects Too Often: Avoid calling
bullet.destroy()repeatedly during game runs. Implement object pools instead.
FAQ
Does setVisible(false) stop collisions in Phaser 4?
No. Setting an object to invisible only hides it visually. If it has a physics body, the collision logic may still trigger. To stop collision, deactivate the object, disable its physics body, or turn off its active state.
Does setActive(false) hide the game object?
No. Deactivating an object marks it as inactive in the game logic, but it remains visible on the screen unless you also call setVisible(false).
What is the difference between destroy() and setVisible(false)?
destroy() permanently removes the object from memory and the scene.setVisible(false) temporarily hides the object while keeping it in memory so it can be reused later.
Why should I use object pooling instead of destroying objects?
Creating and destroying objects repeatedly is CPU-intensive. Object pooling reuses hidden and inactive objects, which drastically improves game performance.
Conclusion
Visibility and active states are simple but extremely important concepts in Phaser 4. Once you understand this difference, you can build cleaner systems for enemies, bullets, coins, UI panels, menus, and object pooling.