Successfully Integrating Phaser 3 into your React/Redux App (Part 1)

A tutorial on building a Phaser game within your React/Redux app.

Hope Fourie
7 min readDec 16, 2020

Before working with Phaser 3, all the apps I had built used React and Redux for front-end management. When I began trying to integrate a Phaser 3 game into one of my apps, I found few helpful resources. I even found articles telling me NOT to integrate React/Redux with Phaser. But I was determined. After a lot of research, reading documentation, and trying a bunch of methods that didn’t work, I managed to build a fully functional Phaser game within a React/Redux framework. I’m here to breakdown my strategy into a few simple steps, so you can add Phaser games to your apps too.

In this tutorial, we will be building a simple phaser platform game in which a gnome named Newt runs around a magical forrest collecting fireflies. Using React/Redux we will make a submit score form and a leaderboard component that updates in real time.

In part one, we will focus on setting up the framework of your React/Redux/Phaser app. Skip to part two here, or part three here.

To see the app we will be building, checkout my example repo here or visit my deployed app here.

Step one: Install Phaser

Before we start, you will need a working React/Redux app. You should have React, Redux, and React-Redux installed in it. If you don’t already have one, you can clone and fork this repo.

Install Phaser in your repo.

Step two: Set up your front-end directory

Your front-end directory (I call mine client) should look something like this:

Like in most React/Redux apps, app.js and store.js live inside the client directory, and React components live inside the components directory. Anything related to your Phaser game should be within the game directory.

Within the game directory, you can break down your scenes and entities (characters, items, etc) into modular components, similar to React. This strategy helps keep your game organized and optimized. The actual game component is located in game/index.js. This is where the game configuration is defined, and where the new game is started.

For the purpose of this tutorial, I have included two scenes: MainScene.js and OpeningScene.js. as well as three entities: Player.js, Ground.js, and Firefly.js. I have also included two React components, Leaderboard.js and ScoreForm.js.

Step three: Define your game component

In game/index.js, import ‘phaser’ and ‘react’. Then import your scenes: MainScene and OpeningScene.

Then, define your game as a React component. This way, it can be seamlessly integrated into your React app.

In your componentDidMount method, declare a variable config, and set it equal to your Phaser config object. For now we will only put MainScene in the scenes array.

After you’ve defined your config, initiate your game by creating a new instance of the Phaser.Game class at the bottom of componentDidMount.

Add a shouldComponentUpdate method that returns false, to ensure your game doesn’t restart every time your state is updated.

Finally, return an empty div in your render method.

Remember to export the Game class, so it can be imported into your app.

Step four: Redux store

In store.js, import { createStore } from Redux. To make API calls, I also imported axios.

Declare your initial state, action types, and action creators.

GET_PLAYERS and receivedPlayers will be used to populate our components’ local state with all the players currently in the database.

ADD_PLAYER and playerAdded will be used in our submit score form, to add a new player to the database and the leaderboard.

UPDATE_SCORE and updateScore will be used called within the phaser game when the player collects a firefly. Keeping the score on our Redux store will allow our other React components to access it.

Declare your thunks.

The functions fetchPlayers and addPlayer make axios calls to communicate with the database, and dispatch our action creators to keep our store up to date.

Finally, declare your reducer and create your Redux store.

Don’t forget to export your store, so you can import it in your app.js.

Step five: React Components

Submit Score Form

In components/ScoreForm.js, import React, connect from ‘react-redux’, and the addPlayer thunk from your store file.

Define a ScoreForm class component. Set two properties on the state: name and buttonDisabled. Name will keep track of the user’s input and buttonDisabled will allow us to prevent the user from submitting their score multiple times. We will define the handleChange and handleSubmit methods later, but for now bind the this context to the constructor.

Below the ScoreForm component, declare mapState and mapDispatch in order to pull state from our Redux store to our components props. Then use connect from ‘react-redux’ to create and export the connected component.

Within your ScoreForm class, write a render method that has a form with an input field and a submit button. The submit button should have a disabled attribute that is set to the buttonDisabled property on the component’s state. This will allow us to prevent the user from submitting their score multiple times.

The onSubmit attribute of your form should be the handleSubmit method of your component. The onChange attribute of your input field should be the handleChange method of your component. We will define these momentarily.

Between the component’s constructor and render method, define the handleChange and handleSubmit methods.

The handleChange method updates the components state every time a user changes the input field.

In the handleSubmit method, e.preventDefault() stops the page from refreshing when the submit button is pressed, which is the default behavior for React forms. On lines 23–26, the method calls the addPlayer thunk, that we mapped from the store and connected to our component. The object that is passed to it contains the player’s name input and the score we mapped from the store. When this thunk is called, both the database and the store are updated. Then it updates the components local state, resetting the input field and disabling the submit button.

Leaderboard

In components/Leaderboard.js, import React, connect, and

Define a Leaderboard class component. We will define the findTopPlayers method later, but for now bind the this context to the constructor.

Below the Leaderboard component, declare mapState and mapDispatch in order to pull state from our Redux store to our components props. Then use connect from ‘react-redux’ to create and export the connected component.

Within the Leaderboard class, write a method that takes the players array and returns the top three players.

At the bottom of the Leaderboard class, write a render method that creates a leaderboard by mapping through the top three players and creating a <div> to display their name and score.

Create a <div> that displays the score we mapped from store, so that they player can see their score updating in real time. Also include your ScoreForm component, so they can submit their score when they are done playing.

Adding Components to Your App

Now that you have all of your components, import them to your app.js. At this point, your app.js file should look something like this:

At this point, when you launch your app you should be able to see your Leaderboard and ScoreForm components, as well as a blank game canvas.

To continue this tutorial, visit Part Two here.

--

--