Reputation: 3
I am trying to develop a phaser3 application with React. I am just setting up the first canvas for the Phaser.Game. Here is my App.js from the create-react-app.
import "./App.css";
import Phaser, { Game } from "phaser";
import PhaserMatterCollisionPlugin from "phaser-matter-collision-plugin";
import { useCallback, useEffect, useState } from "react";
function App() {
const [game, setGame] = useState(null);
// Creating game inside a useEffect in order to ensure 1 instance is created
console.log("before use effect");
useEffect(() => {
console.log("Going into useEffect");
console.log(game);
if (game) {
console.log("game detected. stop creation");
return;
}
const phaserGame = new Phaser.Game({
width: 512,
height: 412,
backgroundColor: "#333333",
type: Phaser.AUTO,
parent: "survival-game",
scene: [],
scale: {
zoom: 2,
},
physics: {
default: "matter",
matter: {
debug: true,
gravity: { y: 0 },
},
},
plugins: {
scene: [
{
plugin: PhaserMatterCollisionPlugin,
key: "matterCollision",
mapping: "matterCollision",
},
],
},
});
setGame(true);
return;
}, [game]);
}
export default App;
I used useEffect() with useState in order to prevent multiple game instances, but for some reason I am still getting a duplicate canvas and can see that it is running through the useEffect multiple times. console.log of the react app
Upvotes: 0
Views: 1072
Reputation: 169022
You should use a ref instead of state for the game object. Here's a small custom hook that sets up a Phaser.Game based on a given configuration:
function usePhaserGame(config) {
const phaserGameRef = React.useRef(null);
React.useEffect(() => {
if (phaserGameRef.current) {
return;
}
phaserGameRef.current = new Game(config);
return () => {
phaserGameRef.current.destroy(true);
phaserGameRef.current = null;
};
}, [] /* only run once; config ref elided on purpose */);
return phaserGameRef.current;
}
const config = {
width: 512,
height: 412,
backgroundColor: '#333333',
type: Phaser.AUTO,
parent: 'survival-game',
scene: [],
scale: {
zoom: 2,
},
physics: {
default: 'matter',
matter: {
debug: true,
gravity: {y: 0},
},
},
plugins: {
scene: [
{
plugin: PhaserMatterCollisionPlugin,
key: 'matterCollision',
mapping: 'matterCollision',
},
],
},
};
function App() {
const game = usePhaserGame(config);
}
Upvotes: 4