Scene Transition with Fade Out in Phaser 3

Easily add more dramatic Scene transitions with fade-out and fade-in effects

by on 6 minute read


Are you looking for a quick way to improve Scene transitions?

A hard cut from one Scene to another is appropriate at times.

But a soft transition with a fade-out, wait some time, and then fade-in is more dramatic.

Even a short fade-out then fade-in feels more polished.

Phaser 3 makes this pretty easy with built-in fade-out and fade-in effects on the Camera.

In this article, we will show you how to use these fade effects and add a delay before fading in the new Scene for added dramatics!

Example Set-Up

This example will consist of 2 Scenes. One of the Ourcade logo and another of the Phaser 3 logo.

We will then use the Space key to trigger a fade-out from one and fade-in to the other.

The code will be in TypeScript but don't worry if you are not familiar. Phaser makes using this effect so simple that the TypeScript will not look much different than modern JavaScript!

It is a great opportunity to get some exposure to TypeScript if you've been hesitant.

We also have a free book to help you get started with TypeScript and Phaser 3.

Learn to make an Infinite Runner in Phaser 3 with TypeScript!

Drop your email into the box below to get this free 90+ page book and join our newsletter.

Learn more about the book here.

Ourcade Logo Scene

Our first Scene will be the OurcadeLogoScene that simply loads the Ourcade logo and display it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import Phaser from 'phaser'

export default class OurcadeLogoScene extends Phaser.Scene
{
	constructor()
	{
		super('ourcade-logo')
	}

	preload()
    {
        this.load.image('ourcade-logo', 'assets/ourcade-logo.png')
    }

    create()
    {
		this.cameras.main.setBackgroundColor('#421278')

		this.add.image(400, 300, 'ourcade-logo')
	}
}

Everything should be fairly straight forward.

Notice that we are setting the background color of this Scene to #421278 which is a dark purple.

Phaser Logo Scene

Next, let's create the PhaserLogoScene in a similar way to the OurcadeLogoScene:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import Phaser from 'phaser'

export default class PhaserLogoScene extends Phaser.Scene
{
	constructor()
	{
		super('phaser-logo')
	}

	preload()
	{
		this.load.image('phaser-logo', 'assets/phaser-logo.png')
	}

	create()
	{
		this.add.image(400, 300, 'phaser-logo')
	}
}

This Scene is even simpler as we don't set a custom background color.

Did you notice how similar this code is to modern JavaScript?

TypeScript is nothing to fear! Any valid JavaScript is also valid TypeScript.

Fade Out a Scene

Now that we have our Scenes, let's fade-out the OurcadeLogoScene and start the PhaserLogoScene.

We will start the fade-out once the Space key is pressed.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// in OurcadeLogoScene

create()
{
	// previous code...

	this.input.keyboard.once('keydown-SPACE', () => {
		// fade to black
		this.cameras.main.fadeOut(1000, 0, 0, 0)
	})

	this.cameras.main.once(Phaser.Cameras.Scene2D.Events.FADE_OUT_COMPLETE, (cam, effect) => {
		this.scene.start('phaser-logo')
	})
}

We add a listener for the keydown-SPACE event on line 7 and then start the fade-out effect when that happens on line 9.

The first parameter is the time in milliseconds which we've set to 1000.

Then the next 3 parameters define the red, blue, and green values for the color to fade-out to. We've chosen 0 for all which is black.

Next, we listen for the Phaser.Cameras.Scene2D.Events.FADE_OUT_COMPLETE event which fires after the fade-out effect is finished and start the phaser-logo Scene.

You should see the current Scene fade out and then the next Scene appear abruptly.

Fade In a Scene

Next, let's have the next Scene fade-in when it starts. Add this to PhaserLogoScene:

1
2
3
4
5
6
7
8
// in PhaserLogoScene

create()
{
	// previous code...

	this.cameras.main.fadeIn(1000, 0, 0, 0)
}

That single line is all you need! It has the same signature or parameter list as the fadeOut() method we used earlier.

This will fade the Scene in over 1000 milliseconds from black.

Delay Before Fade In

Now, let's add a dramatic delay before starting the next Scene.

Replace this.scene.start() call in OurcadeLogoScene with:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// in OurcadeLogoScene

create()
{
	// previous code...

	this.cameras.main.once(Phaser.Cameras.Scene2D.Events.FADE_OUT_COMPLETE, (cam, effect) => {
		this.time.delayedCall(1000, () => {
			this.scene.start('phaser-logo')
		})
	})
}

The new line of code is on line 8 where we use a delayedCall to wait 1000 milliseconds or 1 second before starting the phaser-logo Scene.

Compare it to the code in the Fade Out a Scene section to get a better feel for what changed.

The fade-out, delay, then fade-in will look something like this:

Optional Fade In

Our example will always fade-in the PhaserLogoScene but you may be transitioning to a Scene from different points in your game and might not always want it to fade-in.

We can make it optional by passing in additional data to the Scene when we start it and then using that data to determine whether the Scene should fade-in or not.

This is where the TypeScript typing information comes in:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// in PhaserLogoScene

create(data: { fadeIn: boolean })
{
	// other code...

	if (data.fadeIn)
	{
		// wrap this line inside this if block
		this.cameras.main.fadeIn(1000, 0, 0, 0)
	}
}

Notice that we added a data parameter to the create() method. It will have a property called fadeIn that is of type boolean.

Then we check on line 7 that data.fadeIn is true before performing a fade-in.

This means that our existing code in OurcadeLogoScene will no longer result in a fade-in when starting the phaser-logo Scene.

Here's how we can make it fade-in again:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// in OurcadeLogoScene

create()
{
	// other code...

	this.cameras.main.once(Phaser.Cameras.Scene2D.Events.FADE_OUT_COMPLETE, (cam, effect) => {
		this.time.delayedCall(1000, () => {
			this.scene.start('phaser-logo', { fadeIn: true })
		})
	})
}

Notice that we are passing in the object { fadeIn: true } on line 9 when we start the phaser-logo Scene.

Next Steps

Phaser 3 comes with a handful of other effects you can use alone or mix & match as Scene transitions.

You can also do a long fade-out to a quick fade-in by adjusting the millisecond values passed to fadeOut() and fadeIn() or use different colors to get a different look and feel.

Be sure to sign up for our newsletter so you don't miss any future Phaser 3 game development tips and techniques!

Drop your email into the box below.

Don't miss any Phaser 3 game development content

Subscribers get exclusive tips & techniques not found on the blog!

Join our newsletter. It's free. We don't spam. Spamming is for jerks.

Phaser 3 camera scene transition camera effects

Want tips and techniques more suited for you?


You may also like...


Video Guides


Beginner Guides


Articles Recommended For You

Fix Stretched Image Distortions in Phaser 3 with 9-Slice Scaling

by on

Are you having image distortion problems when scaling to make a button or panel graphic bigger? Multiple versions of the …

5 minute read

Command Pattern to Undo Player Actions

by on

Are you looking for a clean and reusable way to implement undo for player actions? Perhaps you are making a turn-based …

15 minute read

Advanced Logging with the Strategy Pattern

by on

Have you ever tried debugging a problem with your game that only seems to happen in production? The Developer Tools …

7 minute read

State Pattern for Character Movement in Phaser 3

by on

Writing clean and well-organized code is something all game developers aspire to. We want code to be reusable and easy …

7 minute read

Didn't find what you were looking for?


comments powered by Disqus