├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .jsdoc.json ├── .prettierrc ├── .travis.yml ├── LICENSE ├── README.md ├── docs ├── components_GameComponent.jsx.html ├── contexts_GameContext.js.html ├── errors_ConfigError.js.html ├── errors_InvalidPropertyNameError.js.html ├── errors_MissingArgumentError.js.html ├── fonts │ ├── OpenSans-Bold-webfont.eot │ ├── OpenSans-Bold-webfont.svg │ ├── OpenSans-Bold-webfont.woff │ ├── OpenSans-BoldItalic-webfont.eot │ ├── OpenSans-BoldItalic-webfont.svg │ ├── OpenSans-BoldItalic-webfont.woff │ ├── OpenSans-Italic-webfont.eot │ ├── OpenSans-Italic-webfont.svg │ ├── OpenSans-Italic-webfont.woff │ ├── OpenSans-Light-webfont.eot │ ├── OpenSans-Light-webfont.svg │ ├── OpenSans-Light-webfont.woff │ ├── OpenSans-LightItalic-webfont.eot │ ├── OpenSans-LightItalic-webfont.svg │ ├── OpenSans-LightItalic-webfont.woff │ ├── OpenSans-Regular-webfont.eot │ ├── OpenSans-Regular-webfont.svg │ ├── OpenSans-Regular-webfont.woff │ ├── OpenSans-Semibold-webfont.eot │ ├── OpenSans-Semibold-webfont.svg │ ├── OpenSans-Semibold-webfont.ttf │ ├── OpenSans-Semibold-webfont.woff │ ├── OpenSans-SemiboldItalic-webfont.eot │ ├── OpenSans-SemiboldItalic-webfont.svg │ ├── OpenSans-SemiboldItalic-webfont.ttf │ └── OpenSans-SemiboldItalic-webfont.woff ├── global.html ├── hooks_useEventEmitter.js.html ├── hooks_useEventListener.js.html ├── hooks_usePhaser.js.html ├── icons │ ├── home.svg │ └── search.svg ├── index.html ├── module-ConfigError.html ├── module-GameComponent.html ├── module-GameContext.html ├── module-GameProvider.html ├── module-InvalidPropertyNameError.html ├── module-MissingArgumentError.html ├── module-useEventEmitter.html ├── module-useEventListener.html ├── module-usePhaser.html ├── module.exports.html ├── scripts │ ├── linenumber.js │ └── pagelocation.js └── styles │ ├── collapse.css │ ├── jsdoc-default.css │ ├── prettify-jsdoc.css │ └── prettify-tomorrow.css ├── example ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ └── manifest.json └── src │ ├── App.js │ ├── App.test.js │ ├── components │ ├── EventEmitterButton.jsx │ ├── FrameCounter.jsx │ └── Overlay.jsx │ ├── config.js │ ├── events.js │ ├── index.css │ ├── index.js │ └── scenes │ ├── create.js │ ├── preload.js │ └── update.js ├── package-lock.json ├── package.json └── src ├── .eslintrc ├── components ├── GameComponent.jsx └── GameComponent.test.js ├── contexts └── GameContext.js ├── errors ├── ConfigError.js ├── ConfigError.test.js ├── InvalidPropertyNameError.js ├── InvalidPropertyNameError.test.js ├── MissingArgumentError.js └── MissingArgumentError.test.js ├── hooks ├── useEventEmitter.js ├── useEventListener.js ├── usePhaser.js └── usePhaser.test.js ├── index.js ├── index.test.js └── setupTests.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/ 2 | dist/ 3 | docs/ 4 | node_modules/ 5 | .snapshots/ 6 | *.min.js -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": [ 4 | "standard", 5 | "standard-react", 6 | "plugin:prettier/recommended", 7 | "prettier/standard", 8 | "prettier/react" 9 | ], 10 | "env": { 11 | "node": true 12 | }, 13 | "parserOptions": { 14 | "ecmaVersion": 2020, 15 | "ecmaFeatures": { 16 | "legacyDecorators": true, 17 | "jsx": true 18 | } 19 | }, 20 | "settings": { 21 | "react": { 22 | "version": "16" 23 | } 24 | }, 25 | "rules": { 26 | "space-before-function-paren": 0, 27 | "react/prop-types": 0, 28 | "react/jsx-handler-names": 0, 29 | "react/jsx-fragments": 0, 30 | "react/no-unused-prop-types": 0, 31 | "import/export": 0 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # See https://help.github.com/ignore-files/ for more about ignoring files. 3 | 4 | # dependencies 5 | node_modules 6 | 7 | # builds 8 | build 9 | dist 10 | .rpt2_cache 11 | 12 | # misc 13 | .DS_Store 14 | .env 15 | .env.local 16 | .env.development.local 17 | .env.test.local 18 | .env.production.local 19 | 20 | npm-debug.log* 21 | yarn-debug.log* 22 | yarn-error.log* 23 | -------------------------------------------------------------------------------- /.jsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "opts": { 3 | "destination": "./docs/", 4 | "recurse": true, 5 | "template": "node_modules/jsdoc-template" 6 | }, 7 | "recurseDepth": 10, 8 | "source": { 9 | "exclude": ["node_modules"], 10 | "includePattern": ".+\\.js(doc|x)?$", 11 | "include": ["README.md", "src"] 12 | }, 13 | "templates": { 14 | "referenceTitle": "phaser-react-tools" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "jsxSingleQuote": true, 4 | "semi": false, 5 | "tabWidth": 2, 6 | "bracketSpacing": true, 7 | "jsxBracketSameLine": false, 8 | "arrowParens": "always", 9 | "trailingComma": "none" 10 | } 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 12 4 | - 10 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Ben Rosen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # phaser-react-tools 2 | 3 | ![npm](https://img.shields.io/npm/v/phaser-react-tools) ![Maintenance](https://img.shields.io/maintenance/yes/2021) ![GitHub commit activity](https://img.shields.io/github/commit-activity/m/benrosen/phaser-react-tools) ![GitHub last commit](https://img.shields.io/github/last-commit/benrosen/phaser-react-tools) ![NPM](https://img.shields.io/npm/l/phaser-react-tools) ![GitHub issues](https://img.shields.io/github/issues-raw/benrosen/phaser-react-tools) ![GitHub pull requests](https://img.shields.io/github/issues-pr-raw/benrosen/phaser-react-tools) ![GitHub language count](https://img.shields.io/github/languages/count/benrosen/phaser-react-tools) ![GitHub top language](https://img.shields.io/github/languages/top/benrosen/phaser-react-tools) ![npm](https://img.shields.io/npm/dw/phaser-react-tools) 4 | 5 | By default, [Phaser][1] and [React][2] don't always get along. `phaser-react-tools` is here to help. 6 | 7 | You can use `phaser-react-tools` to: 8 | 9 | - Embed your Phaser game in a React application 10 | - Build your game's UI with React 11 | - Send events & data between Phaser and React 12 | 13 | ## Quickstart 14 | 15 | To install, run: 16 | 17 | `npm i phaser-react-tools` 18 | 19 | ## Config 20 | 21 | The `GameComponent` is a [HOC][3] that can be configured [just like a normal Phaser game][4]. 22 | 23 | ```jsx 24 | import { GameComponent } from 'phaser-react-tools' 25 | 26 | export default function App() { 27 | return ( 28 | 43 | {/* YOUR GAME UI GOES HERE */} 44 | 45 | ) 46 | } 47 | ``` 48 | 49 | ## Events 50 | 51 | The `useEventEmitter` hook can help you send messages from a React component to your Phaser game. 52 | 53 | ```jsx 54 | import { useEventEmitter } from 'phaser-react-tools' 55 | 56 | export default () => { 57 | const emit = useEventEmitter('BUTTON_CLICK_EVENT') 58 | 59 | return 60 | } 61 | ``` 62 | 63 | The `useEventListener` hook can help you handle game events in your React components. 64 | 65 | ```jsx 66 | import { useEventListener } from 'phaser-react-tools' 67 | 68 | export default () => { 69 | useEventListener('BUTTON_CLICK_EVENT', (event) => { 70 | console.log(event) 71 | }) 72 | } 73 | ``` 74 | 75 | ## Next steps 76 | 77 | Check out the `/example` directory or [visit the docs][5]. 78 | 79 | If you find a bug or have ideas for improvements, please [create an issue][6] and/or [submit a pull request][7]. 80 | 81 | [1]: https://www.npmjs.com/package/phaser 'Phaser package' 82 | [2]: https://www.npmjs.com/package/react 'React package' 83 | [3]: https://reactjs.org/docs/higher-order-components.html 'Higher-order component' 84 | [4]: https://photonstorm.github.io/phaser3-docs/Phaser.Types.Core.html#.GameConfig 'Phaser config docs' 85 | [5]: https://benrosen.github.io/phaser-react-tools 'phaser-react-tools docs' 86 | [6]: https://github.com/benrosen/phaser-react-tools/issues 'create an issue' 87 | [7]: https://github.com/benrosen/phaser-react-tools/pulls 'submit a pull request' 88 | -------------------------------------------------------------------------------- /docs/components_GameComponent.jsx.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | components/GameComponent.jsx - Documentation 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 49 | 50 | 51 | 52 |
53 | 69 |
70 | 71 | 80 | 81 |
82 | 83 |

84 | components/GameComponent.jsx 85 |

86 | 87 | 88 | 89 | 90 | 91 |
92 |
93 |
import { GameProvider } from '../contexts/GameContext'
 94 | import PropTypes from 'prop-types'
 95 | import React from 'react'
 96 | import usePhaser from '../hooks/usePhaser'
 97 | 
 98 | /**
 99 |  * A higher-order React functional component that manages the Phaser game.
100 |  *
101 |  * @function
102 |  * @module GameComponent
103 |  * @param {Object} props The component props.
104 |  * @param {Array|Object} [props.children] The child components.
105 |  * @param {Object} props.config The config object for the Phaser game instance.
106 |  * @throws {ConfigError} Will throw a ConfigError if the Phaser game is mis-configured by the user.
107 |  * @see module:usePhaser
108 |  * @see module:GameProvider
109 |  */
110 | export default function GameComponent({ children, config }) {
111 |   const [canvasRef, game] = usePhaser(config)
112 |   return (
113 |     <div style={{ display: 'inline-block', position: 'relative' }}>
114 |       <GameProvider value={game}>{children}</GameProvider>
115 |       <canvas ref={canvasRef} />
116 |     </div>
117 |   )
118 | }
119 | 
120 | GameComponent.propTypes = {
121 |   children: PropTypes.oneOfType([
122 |     PropTypes.arrayOf(PropTypes.node),
123 |     PropTypes.node
124 |   ]),
125 |   config: PropTypes.object
126 | }
127 | 
128 |
129 |
130 | 131 | 132 | 133 | 134 |
135 | 136 |
137 | 138 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /docs/contexts_GameContext.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | contexts/GameContext.js - Documentation 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 49 | 50 | 51 | 52 |
53 | 69 |
70 | 71 | 80 | 81 |
82 | 83 |

84 | contexts/GameContext.js 85 |

86 | 87 | 88 | 89 | 90 | 91 |
92 |
93 |
import { createContext } from 'react'
 94 | 
 95 | /**
 96 |  * A React Context object that stores the Phaser game instance.
 97 |  *
 98 |  * @module GameContext
 99 |  * @see module:GameProvider
100 |  */
101 | export const GameContext = createContext({})
102 | 
103 | /**
104 |  * A higher-order React functional component that provides a GameContext to its children.
105 |  *
106 |  * @function
107 |  * @module GameProvider
108 |  * @param {Object} props The component props.
109 |  * @param {Array|Object} [props.children] The child components.
110 |  * @param {Object} props.value A Phaser game instance.
111 |  * @see module:GameContext
112 |  */
113 | export const GameProvider = GameContext.Provider
114 | 
115 |
116 |
117 | 118 | 119 | 120 | 121 |
122 | 123 |
124 | 125 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /docs/errors_ConfigError.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | errors/ConfigError.js - Documentation 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 49 | 50 | 51 | 52 |
53 | 69 |
70 | 71 | 80 | 81 |
82 | 83 |

84 | errors/ConfigError.js 85 |

86 | 87 | 88 | 89 | 90 | 91 |
92 |
93 |
import InvalidPropertyNameError from './InvalidPropertyNameError'
 94 | import MissingArgumentError from './MissingArgumentError'
 95 | 
 96 | /**
 97 |  * An error that occurs when a protected value on the Phaser config object is set incorrectly.
 98 |  *
 99 |  * @class
100 |  * @module ConfigError
101 |  * @extends TypeError
102 |  */
103 | export default class ConfigError extends TypeError {
104 |   /**
105 |    * Creates an instance representing an error that occurs when a protected value on the Phaser config object is set incorrectly.
106 |    *
107 |    * @param {Object} config The Phaser config object whose property value is set incorrectly.
108 |    * @param {*} propertyName The name of the property whose value is set incorrectly.
109 |    * @throws {module:MissingArgumentError} Will throw a MissingArgumentError if required arguments are missing.
110 |    */
111 |   constructor(config, propertyName) {
112 |     if (!config) {
113 |       throw new MissingArgumentError(
114 |         'You must provide the Phaser config object whose property value is set incorrectly when attempting to create a ConfigError.'
115 |       )
116 |     }
117 | 
118 |     if (!propertyName) {
119 |       throw new MissingArgumentError(
120 |         'You must provide the name of the property whose value is set incorrectly when attempting to create a ConfigError.'
121 |       )
122 |     }
123 | 
124 |     const value = config[propertyName]
125 | 
126 |     if (value === undefined) {
127 |       throw new InvalidPropertyNameError(
128 |         `The Phaser config object does not have a property named ${propertyName}.`
129 |       )
130 |     }
131 | 
132 |     super(
133 |       `phaser-react-tools sets the ${propertyName} property of the Phaser config object internally. As such, the user-provided value of ${value} will be overridden.`
134 |     )
135 | 
136 |     Error.captureStackTrace(this, ConfigError)
137 |   }
138 | }
139 | 
140 |
141 |
142 | 143 | 144 | 145 | 146 |
147 | 148 |
149 | 150 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /docs/errors_InvalidPropertyNameError.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | errors/InvalidPropertyNameError.js - Documentation 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 49 | 50 | 51 | 52 |
53 | 69 |
70 | 71 | 80 | 81 |
82 | 83 |

84 | errors/InvalidPropertyNameError.js 85 |

86 | 87 | 88 | 89 | 90 | 91 |
92 |
93 |
/**
 94 |  * An error that occurs when an invalid property name is provided.
 95 |  *
 96 |  * @class
 97 |  * @module InvalidPropertyNameError
 98 |  * @extends TypeError
 99 |  */
100 | export default class InvalidPropertyNameError extends TypeError {
101 |   /**
102 |    * Creates an instance representing an error that occurs when an invalid property name is provided.
103 |    *
104 |    * @param  {...any} [args] The error arguments.
105 |    */
106 |   constructor(...args) {
107 |     super(...args)
108 |     Error.captureStackTrace(this, InvalidPropertyNameError)
109 |   }
110 | }
111 | 
112 |
113 |
114 | 115 | 116 | 117 | 118 |
119 | 120 |
121 | 122 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /docs/errors_MissingArgumentError.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | errors/MissingArgumentError.js - Documentation 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 49 | 50 | 51 | 52 |
53 | 69 |
70 | 71 | 80 | 81 |
82 | 83 |

84 | errors/MissingArgumentError.js 85 |

86 | 87 | 88 | 89 | 90 | 91 |
92 |
93 |
/**
 94 |  * An error that occurs when a required argument is missing.
 95 |  *
 96 |  * @class
 97 |  * @module MissingArgumentError
 98 |  * @extends TypeError
 99 |  */
100 | export default class MissingArgumentError extends TypeError {
101 |   /**
102 |    * Creates an instance representing an error that occurs when a required argument is missing.
103 |    *
104 |    * @param  {...any} [args] The error arguments.
105 |    */
106 |   constructor(...args) {
107 |     super(...args)
108 |     Error.captureStackTrace(this, MissingArgumentError)
109 |   }
110 | }
111 | 
112 |
113 |
114 | 115 | 116 | 117 | 118 |
119 | 120 |
121 | 122 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-Bold-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-Bold-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-BoldItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-BoldItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-BoldItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-BoldItalic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-Italic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-Italic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-Light-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-Light-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-LightItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-LightItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-LightItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-LightItalic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-Regular-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-Regular-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Semibold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-Semibold-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Semibold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-Semibold-webfont.ttf -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Semibold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-Semibold-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-SemiboldItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-SemiboldItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-SemiboldItalic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-SemiboldItalic-webfont.ttf -------------------------------------------------------------------------------- /docs/fonts/OpenSans-SemiboldItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/docs/fonts/OpenSans-SemiboldItalic-webfont.woff -------------------------------------------------------------------------------- /docs/global.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Global - Documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 |
51 | 67 |
68 | 69 | 78 | 79 |
80 | 81 |

82 | Global 83 |

84 | 85 | 86 | 87 | 88 |
89 |
90 | 91 |

92 | 93 | 94 | 95 |

96 | 97 | 98 | 99 |
100 | 101 |
102 |
103 | 104 | 105 | 106 | 107 | 108 |
109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 |
142 | 143 | 144 | 145 | 146 |
147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 |

Type Definitions

164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 |

178 | emitFunction(detailopt) 179 |

180 |
181 | 182 | 183 | 184 | 185 | 186 |
187 | Emit an event. 188 |
189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 |
Parameters:
197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 237 | 238 | 239 | 248 | 249 | 250 | 251 | 252 | 256 | 257 | 258 | 259 | 260 |
NameTypeAttributesDescription
detail 226 | 227 | 228 | 229 | Object 230 | 231 | 232 | 233 | 234 | 235 | 236 | 240 | 241 | <optional>
242 | 243 | 244 | 245 | 246 | 247 |
253 | The event payload. 254 | 255 |
261 | 262 | 263 | 264 | 265 | 266 |
267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 |
Source:
294 |
295 | 300 |
301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 |
309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 |

336 | eventHandler(eventopt) 337 |

338 |
339 | 340 | 341 | 342 | 343 | 344 |
345 | Handle an event. 346 |
347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 |
Parameters:
355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 395 | 396 | 397 | 406 | 407 | 408 | 409 | 410 | 414 | 415 | 416 | 417 | 418 |
NameTypeAttributesDescription
event 384 | 385 | 386 | 387 | * 388 | 389 | 390 | 391 | 392 | 393 | 394 | 398 | 399 | <optional>
400 | 401 | 402 | 403 | 404 | 405 |
411 | The event to be handled. 412 | 413 |
419 | 420 | 421 | 422 | 423 | 424 |
425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 |
Source:
452 |
453 | 458 |
459 | 460 | 461 | 462 | 463 | 464 |
See:
465 |
466 | 473 |
474 | 475 | 476 | 477 |
478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 |

505 | InstanceConfig :Object 506 |

507 |
508 | 509 | 510 | 511 | 512 | 513 |
514 | A config object containing a canvas ref and a reference to the Phaser game instance. 515 |
516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 |
Properties:
527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 567 | 568 | 569 | 570 | 571 | 572 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 596 | 597 | 598 | 599 | 600 | 601 | 604 | 605 | 606 | 607 | 608 |
NameTypeDescription
canvasRef 556 | 557 | 558 | 559 | Object 560 | 561 | 562 | 563 | 564 | 565 | 566 | 573 | The reference to the Phaser game canvas. 574 |
game 585 | 586 | 587 | 588 | Object 589 | 590 | 591 | 592 | 593 | 594 | 595 | 602 | The Phaser game instance. 603 |
609 | 610 | 611 | 612 | 613 |
614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 |
Source:
641 |
642 | 647 |
648 | 649 | 650 | 651 | 652 | 653 |
See:
654 |
655 | 666 |
667 | 668 | 669 | 670 |
671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 |
689 |
690 | 691 | 692 | 693 | 694 |
695 | 696 |
697 | 698 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | -------------------------------------------------------------------------------- /docs/hooks_useEventEmitter.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | hooks/useEventEmitter.js - Documentation 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 49 | 50 | 51 | 52 |
53 | 69 |
70 | 71 | 80 | 81 |
82 | 83 |

84 | hooks/useEventEmitter.js 85 |

86 | 87 | 88 | 89 | 90 | 91 |
92 |
93 |
import { useCallback, useContext } from 'react'
 94 | 
 95 | import { GameContext } from '../contexts/GameContext'
 96 | 
 97 | /**
 98 |  * Returns a function that can emit an event of the given type.
 99 |  *
100 |  * @function
101 |  * @module useEventEmitter
102 |  * @param {string} type The type of event to emit.
103 |  * @returns {emitFunction} A function that can emit an event of the given type.
104 |  */
105 | export default function useEventEmitter(type) {
106 |   const game = useContext(GameContext)
107 | 
108 |   return useCallback(
109 |     (detail) => {
110 |       game.events.emit(type, detail)
111 |     },
112 |     [game]
113 |   )
114 | }
115 | 
116 | /**
117 |  * Emit an event.
118 |  *
119 |  * @callback emitFunction
120 |  * @param {Object} [detail] The event payload.
121 |  */
122 | 
123 |
124 |
125 | 126 | 127 | 128 | 129 |
130 | 131 |
132 | 133 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /docs/hooks_useEventListener.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | hooks/useEventListener.js - Documentation 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 49 | 50 | 51 | 52 |
53 | 69 |
70 | 71 | 80 | 81 |
82 | 83 |

84 | hooks/useEventListener.js 85 |

86 | 87 | 88 | 89 | 90 | 91 |
92 |
93 |
import { useContext, useEffect } from 'react'
 94 | 
 95 | import { GameContext } from '../contexts/GameContext'
 96 | 
 97 | /**
 98 |  * Subscribe a callback function to events of the given type.
 99 |  *
100 |  * @function
101 |  * @module useEventListener
102 |  * @param {string} type The type of event for which to listen.
103 |  * @param {eventHandler} handler The event handler callback function.
104 |  */
105 | export default function useEventListener(type, handler) {
106 |   const game = useContext(GameContext)
107 |   useEffect(() => {
108 |     if (game === undefined) {
109 |       return
110 |     }
111 |     game.events.on(type, handler)
112 |     return () => {
113 |       game.events.off(type, handler)
114 |     }
115 |   }, [game, handler, type])
116 | }
117 | 
118 | /**
119 |  * Handle an event.
120 |  *
121 |  * @callback eventHandler
122 |  * @param {*} [event] The event to be handled.
123 |  * @see module:useEventListener
124 |  */
125 | 
126 |
127 |
128 | 129 | 130 | 131 | 132 |
133 | 134 |
135 | 136 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /docs/hooks_usePhaser.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | hooks/usePhaser.js - Documentation 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 49 | 50 | 51 | 52 |
53 | 69 |
70 | 71 | 80 | 81 |
82 | 83 |

84 | hooks/usePhaser.js 85 |

86 | 87 | 88 | 89 | 90 | 91 |
92 |
93 |
import { useEffect, useRef, useState } from 'react'
 94 | 
 95 | import ConfigError from '../errors/ConfigError'
 96 | import Phaser from 'phaser'
 97 | 
 98 | /**
 99 |  * Returns a setup object containing a canvas ref and a reference to the Phaser game instance.
100 |  *
101 |  * @function
102 |  * @module usePhaser
103 |  * @param {Object} [config] The config object for the Phaser game instance.
104 |  * @returns {InstanceConfig} A config object containing a canvas ref and a reference to the Phaser game instance.
105 |  * @throws {module:ConfigError} Will throw a ConfigError if the Phaser game is mis-configured by the user.
106 |  */
107 | export default function usePhaser(config = {}) {
108 |   const canvasRef = useRef()
109 |   const [game, setGame] = useState()
110 | 
111 |   useEffect(() => {
112 |     if (config.canvas) {
113 |       throw new ConfigError(config, 'canvas')
114 |     }
115 | 
116 |     if (config.type !== undefined && config.type !== Phaser.CANVAS) {
117 |       throw new ConfigError(config, 'type')
118 |     }
119 | 
120 |     const modifiedConfig = config
121 | 
122 |     modifiedConfig.canvas = canvasRef.current
123 |     modifiedConfig.type = Phaser.CANVAS
124 | 
125 |     const userDefinedPostBootCallback = config.callbacks?.postBoot
126 | 
127 |     const auxiliaryPostBootCallback = (bootedGame) => {
128 |       setGame(() => bootedGame)
129 |     }
130 | 
131 |     if (userDefinedPostBootCallback) {
132 |       modifiedConfig.callbacks.postBoot = (bootedGame) => {
133 |         auxiliaryPostBootCallback(bootedGame)
134 |         userDefinedPostBootCallback(bootedGame)
135 |       }
136 |     } else if (config.callbacks) {
137 |       console.log('user did ')
138 |       modifiedConfig.callbacks.postBoot = auxiliaryPostBootCallback
139 |     } else {
140 |       modifiedConfig.callbacks = {
141 |         postBoot: auxiliaryPostBootCallback
142 |       }
143 |     }
144 | 
145 |     const phaser = new Phaser.Game(modifiedConfig)
146 | 
147 |     return () => {
148 |       phaser.destroy()
149 |     }
150 |   }, [config])
151 | 
152 |   return [canvasRef, game]
153 | }
154 | 
155 | /**
156 |  * A config object containing a canvas ref and a reference to the Phaser game instance.
157 |  *
158 |  * @typedef InstanceConfig
159 |  * @type {Object}
160 |  * @property {Object} canvasRef The reference to the Phaser game canvas.
161 |  * @property {Object} game The Phaser game instance.
162 |  * @see module:usePhaser
163 |  * @see module:GameComponent
164 |  */
165 | 
166 |
167 |
168 | 169 | 170 | 171 | 172 |
173 | 174 |
175 | 176 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /docs/icons/home.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/icons/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Home - Documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 |
51 | 67 |
68 | 69 | 78 | 79 |
80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 |
93 |
94 |

phaser-react-tools

95 |

npm Maintenance GitHub commit activity GitHub last commit NPM GitHub issues GitHub pull requests GitHub language count GitHub top language npm

96 |

By default, Phaser and React don't always get along. phaser-react-tools is here to help.

97 |

You can use phaser-react-tools to:

98 |
    99 |
  • Embed your Phaser game in a React application
  • 100 |
  • Build your game's UI with React
  • 101 |
  • Send events & data between Phaser and React
  • 102 |
103 |

Quickstart

104 |

To install, run:

105 |

npm i phaser-react-tools

106 |

Config

107 |

The GameComponent is a HOC that can be configured just like a normal Phaser game.

108 |
import { GameComponent } from 'phaser-react-tools'
109 | 
110 | export default function App() {
111 |   return (
112 |     <GameComponent
113 |       config={{
114 |         backgroundColor: '000000',
115 |         height: 300,
116 |         width: 400,
117 |         scene: {
118 |           preload: function () {
119 |             console.log('preload')
120 |           },
121 |           create: function () {
122 |             console.log('create')
123 |           }
124 |         }
125 |       }}
126 |     >
127 |       {/* YOUR GAME UI GOES HERE */}
128 |     </GameComponent>
129 |   )
130 | }
131 | 
132 |

Events

133 |

The useEventEmitter hook can help you send messages from a React component to your Phaser game.

134 |
import { useEventEmitter } from 'phaser-react-tools'
135 | 
136 | export default () => {
137 |   const emit = useEventEmitter('BUTTON_CLICK_EVENT')
138 | 
139 |   return <button onClick={() => emit('Click!')}>Emit</button>
140 | }
141 | 
142 |

The useEventListener hook can help you handle game events in your React components.

143 |
import { useEventListener } from 'phaser-react-tools'
144 | 
145 | export default () => {
146 |   useEventListener('BUTTON_CLICK_EVENT', (event) => {
147 |     console.log(event)
148 |   })
149 | }
150 | 
151 |

Next steps

152 |

Check out the /example directory or visit the docs.

153 |

If you find a bug or have ideas for improvements, please create an issue and/or submit a pull request.

154 |
155 |
156 | 157 | 158 | 159 | 160 | 161 |
162 | 163 |
164 | 165 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /docs/module-ConfigError.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | module:ConfigError - Documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 |
51 | 67 |
68 | 69 | 78 | 79 |
80 | 81 |

82 | module:ConfigError 83 |

84 | 85 | 86 | 87 | 88 |
89 |
90 | 91 |

92 | 93 | module:ConfigError 94 | 95 |

96 | 97 | 98 | 99 |
100 | 101 |
102 |
103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |

116 | new module:ConfigError(config, propertyName) 117 |

118 |
119 | 120 | 121 | 122 | 123 | 124 |
125 | Creates an instance representing an error that occurs when a protected value on the Phaser config object is set incorrectly. 126 |
127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 |
Parameters:
135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 173 | 174 | 175 | 176 | 177 | 178 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 202 | 203 | 204 | 205 | 206 | 207 | 211 | 212 | 213 | 214 | 215 |
NameTypeDescription
config 162 | 163 | 164 | 165 | Object 166 | 167 | 168 | 169 | 170 | 171 | 172 | 179 | The Phaser config object whose property value is set incorrectly. 180 | 181 |
propertyName 191 | 192 | 193 | 194 | * 195 | 196 | 197 | 198 | 199 | 200 | 201 | 208 | The name of the property whose value is set incorrectly. 209 | 210 |
216 | 217 | 218 | 219 | 220 | 221 |
222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 |
Source:
249 |
250 | 255 |
256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 |
264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 |
Throws:
276 | 277 | 278 | 279 |
280 |
281 |
282 | Will throw a MissingArgumentError if required arguments are missing. 283 |
284 |
285 |
286 |
287 |
288 |
Type
289 |
290 | 291 | 292 | module:MissingArgumentError 293 | 294 | 295 | 296 | 297 | 298 |
299 |
300 |
301 |
302 |
303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 |
311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 |
330 |
331 | 332 | 333 | 334 | 335 |
336 | 337 |
338 | 339 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | -------------------------------------------------------------------------------- /docs/module-GameComponent.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | GameComponent - Documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 |
51 | 67 |
68 | 69 | 78 | 79 |
80 | 81 |

82 | GameComponent 83 |

84 | 85 | 86 | 87 | 88 |
89 |
90 | 91 | 92 | 93 |
94 | 95 |
96 |
97 | 98 | 99 |
100 | A higher-order React functional component that manages the Phaser game. 101 |
102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 |
Parameters:
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 155 | 156 | 157 | 158 | 159 | 160 | 274 | 275 | 276 | 277 | 278 |
NameTypeDescription
props 144 | 145 | 146 | 147 | Object 148 | 149 | 150 | 151 | 152 | 153 | 154 | 161 | The component props. 162 | 163 |
Properties
164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 210 | 211 | 212 | 221 | 222 | 223 | 224 | 225 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 249 | 250 | 251 | 258 | 259 | 260 | 261 | 262 | 266 | 267 | 268 | 269 | 270 |
NameTypeAttributesDescription
children 193 | 194 | 195 | 196 | Array 197 | 198 | 199 | | 200 | 201 | 202 | Object 203 | 204 | 205 | 206 | 207 | 208 | 209 | 213 | 214 | <optional>
215 | 216 | 217 | 218 | 219 | 220 |
226 | The child components. 227 | 228 |
config 238 | 239 | 240 | 241 | Object 242 | 243 | 244 | 245 | 246 | 247 | 248 | 252 | 253 | 254 | 255 | 256 | 257 | 263 | The config object for the Phaser game instance. 264 | 265 |
271 | 272 | 273 |
279 | 280 | 281 | 282 | 283 | 284 |
285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 |
Source:
312 |
313 | 318 |
319 | 320 | 321 | 322 | 323 | 324 |
See:
325 |
326 | 337 |
338 | 339 | 340 | 341 |
342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 |
Throws:
354 | 355 | 356 | 357 |
358 |
359 |
360 | Will throw a ConfigError if the Phaser game is mis-configured by the user. 361 |
362 |
363 |
364 |
365 |
366 |
Type
367 |
368 | 369 | 370 | ConfigError 371 | 372 | 373 | 374 | 375 | 376 |
377 |
378 |
379 |
380 |
381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 |
390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 |
409 |
410 | 411 | 412 | 413 | 414 |
415 | 416 |
417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | -------------------------------------------------------------------------------- /docs/module-GameContext.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | GameContext - Documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 |
51 | 67 |
68 | 69 | 78 | 79 |
80 | 81 |

82 | GameContext 83 |

84 | 85 | 86 | 87 | 88 |
89 |
90 | 91 | 92 | 93 |
94 | 95 |
96 |
97 | 98 | 99 |
100 | A React Context object that stores the Phaser game instance. 101 |
102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 |
120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 |
Source:
147 |
148 | 153 |
154 | 155 | 156 | 157 | 158 | 159 |
See:
160 |
161 | 168 |
169 | 170 | 171 | 172 |
173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 |
190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 |
209 |
210 | 211 | 212 | 213 | 214 |
215 | 216 |
217 | 218 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | -------------------------------------------------------------------------------- /docs/module-GameProvider.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | GameProvider - Documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 |
51 | 67 |
68 | 69 | 78 | 79 |
80 | 81 |

82 | GameProvider 83 |

84 | 85 | 86 | 87 | 88 |
89 |
90 | 91 | 92 | 93 |
94 | 95 |
96 |
97 | 98 | 99 |
100 | A higher-order React functional component that provides a GameContext to its children. 101 |
102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 |
Parameters:
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 155 | 156 | 157 | 158 | 159 | 160 | 274 | 275 | 276 | 277 | 278 |
NameTypeDescription
props 144 | 145 | 146 | 147 | Object 148 | 149 | 150 | 151 | 152 | 153 | 154 | 161 | The component props. 162 | 163 |
Properties
164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 210 | 211 | 212 | 221 | 222 | 223 | 224 | 225 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 249 | 250 | 251 | 258 | 259 | 260 | 261 | 262 | 266 | 267 | 268 | 269 | 270 |
NameTypeAttributesDescription
children 193 | 194 | 195 | 196 | Array 197 | 198 | 199 | | 200 | 201 | 202 | Object 203 | 204 | 205 | 206 | 207 | 208 | 209 | 213 | 214 | <optional>
215 | 216 | 217 | 218 | 219 | 220 |
226 | The child components. 227 | 228 |
value 238 | 239 | 240 | 241 | Object 242 | 243 | 244 | 245 | 246 | 247 | 248 | 252 | 253 | 254 | 255 | 256 | 257 | 263 | A Phaser game instance. 264 | 265 |
271 | 272 | 273 |
279 | 280 | 281 | 282 | 283 | 284 |
285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 |
Source:
312 |
313 | 318 |
319 | 320 | 321 | 322 | 323 | 324 |
See:
325 |
326 | 333 |
334 | 335 | 336 | 337 |
338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 |
355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 |
374 |
375 | 376 | 377 | 378 | 379 |
380 | 381 |
382 | 383 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | -------------------------------------------------------------------------------- /docs/module-InvalidPropertyNameError.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | module:InvalidPropertyNameError - Documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 |
51 | 67 |
68 | 69 | 78 | 79 |
80 | 81 |

82 | module:InvalidPropertyNameError 83 |

84 | 85 | 86 | 87 | 88 |
89 |
90 | 91 |

92 | 93 | module:InvalidPropertyNameError 94 | 95 |

96 | 97 | 98 | 99 |
100 | 101 |
102 |
103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |

116 | new module:InvalidPropertyNameError(…argsopt) 117 |

118 |
119 | 120 | 121 | 122 | 123 | 124 |
125 | Creates an instance representing an error that occurs when an invalid property name is provided. 126 |
127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 |
Parameters:
135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 175 | 176 | 177 | 188 | 189 | 190 | 191 | 192 | 196 | 197 | 198 | 199 | 200 |
NameTypeAttributesDescription
args 164 | 165 | 166 | 167 | any 168 | 169 | 170 | 171 | 172 | 173 | 174 | 178 | 179 | <optional>
180 | 181 | 182 | 183 | 184 | 185 | <repeatable>
186 | 187 |
193 | The error arguments. 194 | 195 |
201 | 202 | 203 | 204 | 205 | 206 |
207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 |
Source:
234 |
235 | 240 |
241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 |
249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 |
265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 |
284 |
285 | 286 | 287 | 288 | 289 |
290 | 291 |
292 | 293 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | -------------------------------------------------------------------------------- /docs/module-MissingArgumentError.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | module:MissingArgumentError - Documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 |
51 | 67 |
68 | 69 | 78 | 79 |
80 | 81 |

82 | module:MissingArgumentError 83 |

84 | 85 | 86 | 87 | 88 |
89 |
90 | 91 |

92 | 93 | module:MissingArgumentError 94 | 95 |

96 | 97 | 98 | 99 |
100 | 101 |
102 |
103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |

116 | new module:MissingArgumentError(…argsopt) 117 |

118 |
119 | 120 | 121 | 122 | 123 | 124 |
125 | Creates an instance representing an error that occurs when a required argument is missing. 126 |
127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 |
Parameters:
135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 175 | 176 | 177 | 188 | 189 | 190 | 191 | 192 | 196 | 197 | 198 | 199 | 200 |
NameTypeAttributesDescription
args 164 | 165 | 166 | 167 | any 168 | 169 | 170 | 171 | 172 | 173 | 174 | 178 | 179 | <optional>
180 | 181 | 182 | 183 | 184 | 185 | <repeatable>
186 | 187 |
193 | The error arguments. 194 | 195 |
201 | 202 | 203 | 204 | 205 | 206 |
207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 |
Source:
234 |
235 | 240 |
241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 |
249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 |
265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 |
284 |
285 | 286 | 287 | 288 | 289 |
290 | 291 |
292 | 293 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | -------------------------------------------------------------------------------- /docs/module-useEventEmitter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | useEventEmitter - Documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 |
51 | 67 |
68 | 69 | 78 | 79 |
80 | 81 |

82 | useEventEmitter 83 |

84 | 85 | 86 | 87 | 88 |
89 |
90 | 91 | 92 | 93 |
94 | 95 |
96 |
97 | 98 | 99 |
100 | Returns a function that can emit an event of the given type. 101 |
102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 |
Parameters:
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 155 | 156 | 157 | 158 | 159 | 160 | 164 | 165 | 166 | 167 | 168 |
NameTypeDescription
type 144 | 145 | 146 | 147 | string 148 | 149 | 150 | 151 | 152 | 153 | 154 | 161 | The type of event to emit. 162 | 163 |
169 | 170 | 171 | 172 | 173 | 174 |
175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 |
Source:
202 |
203 | 208 |
209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 |
217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 |
234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 |
253 |
254 | 255 | 256 | 257 | 258 |
259 | 260 |
261 | 262 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | -------------------------------------------------------------------------------- /docs/module-useEventListener.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | useEventListener - Documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 |
51 | 67 |
68 | 69 | 78 | 79 |
80 | 81 |

82 | useEventListener 83 |

84 | 85 | 86 | 87 | 88 |
89 |
90 | 91 | 92 | 93 |
94 | 95 |
96 |
97 | 98 | 99 |
100 | Subscribe a callback function to events of the given type. 101 |
102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 |
Parameters:
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 155 | 156 | 157 | 158 | 159 | 160 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 184 | 185 | 186 | 187 | 188 | 189 | 193 | 194 | 195 | 196 | 197 |
NameTypeDescription
type 144 | 145 | 146 | 147 | string 148 | 149 | 150 | 151 | 152 | 153 | 154 | 161 | The type of event for which to listen. 162 | 163 |
handler 173 | 174 | 175 | 176 | eventHandler 177 | 178 | 179 | 180 | 181 | 182 | 183 | 190 | The event handler callback function. 191 | 192 |
198 | 199 | 200 | 201 | 202 | 203 |
204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 |
Source:
231 |
232 | 237 |
238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 |
246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 |
263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 |
282 |
283 | 284 | 285 | 286 | 287 |
288 | 289 |
290 | 291 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | -------------------------------------------------------------------------------- /docs/module-usePhaser.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | usePhaser - Documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 |
51 | 67 |
68 | 69 | 78 | 79 |
80 | 81 |

82 | usePhaser 83 |

84 | 85 | 86 | 87 | 88 |
89 |
90 | 91 | 92 | 93 |
94 | 95 |
96 |
97 | 98 | 99 |
100 | Returns a setup object containing a canvas ref and a reference to the Phaser game instance. 101 |
102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 |
Parameters:
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 157 | 158 | 159 | 168 | 169 | 170 | 171 | 172 | 176 | 177 | 178 | 179 | 180 |
NameTypeAttributesDescription
config 146 | 147 | 148 | 149 | Object 150 | 151 | 152 | 153 | 154 | 155 | 156 | 160 | 161 | <optional>
162 | 163 | 164 | 165 | 166 | 167 |
173 | The config object for the Phaser game instance. 174 | 175 |
181 | 182 | 183 | 184 | 185 | 186 |
187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 |
Source:
214 |
215 | 220 |
221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 |
Throws:
241 | 242 | 243 | 244 |
245 |
246 |
247 | Will throw a ConfigError if the Phaser game is mis-configured by the user. 248 |
249 |
250 |
251 |
252 |
253 |
Type
254 |
255 | 256 | 257 | module:ConfigError 258 | 259 | 260 | 261 | 262 | 263 |
264 |
265 |
266 |
267 |
268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 |
277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 |
296 |
297 | 298 | 299 | 300 | 301 |
302 | 303 |
304 | 305 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | -------------------------------------------------------------------------------- /docs/scripts/linenumber.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | (function () { 4 | var lineId, lines, totalLines, anchorHash; 5 | var source = document.getElementsByClassName('prettyprint source linenums'); 6 | var i = 0; 7 | var lineNumber = 0; 8 | 9 | if (source && source[0]) { 10 | anchorHash = document.location.hash.substring(1); 11 | lines = source[0].getElementsByTagName('li'); 12 | totalLines = lines.length; 13 | 14 | for (; i < totalLines; i++) { 15 | lineNumber++; 16 | lineId = 'line' + lineNumber; 17 | lines[i].id = lineId; 18 | if (lineId === anchorHash) { 19 | lines[i].className += ' selected'; 20 | } 21 | } 22 | } 23 | })(); 24 | -------------------------------------------------------------------------------- /docs/scripts/pagelocation.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | $(document).ready(function () { 4 | var currentSectionNav, target; 5 | 6 | // If an anchor hash is in the URL highlight the menu item 7 | highlightActiveHash(); 8 | // If a specific page section is in the URL highlight the menu item 9 | highlightActiveSection(); 10 | 11 | // If a specific page section is in the URL scroll that section up to the top 12 | currentSectionNav = $('#' + getCurrentSectionName() + '-nav'); 13 | 14 | if (currentSectionNav.position()) { 15 | $('nav').scrollTop(currentSectionNav.position().top); 16 | } 17 | 18 | // function to scroll to anchor when clicking an anchor linl 19 | $('a[href*="#"]:not([href="#"])').click(function () { 20 | /* eslint-disable no-invalid-this */ 21 | if (location.pathname.replace(/^\//, '') === this.pathname.replace(/^\//, '') && location.hostname === this.hostname) { 22 | target = $(this.hash); 23 | target = target.length ? target : $('[name=' + this.hash.slice(1) + ']'); 24 | if (target.length) { 25 | $('html, body').animate({ 26 | scrollTop: target.offset().top 27 | }, 1000); 28 | } 29 | } 30 | /* eslint-enable no-invalid-this */ 31 | }); 32 | }); 33 | 34 | // If a new anchor section is selected, change the hightlighted menu item 35 | $(window).bind('hashchange', function (event) { 36 | highlightActiveHash(event); 37 | }); 38 | 39 | function highlightActiveHash(event) { 40 | var oldUrl, oldSubSectionElement; 41 | 42 | // check for and remove old hash active state 43 | if (event && event.originalEvent.oldURL) { 44 | oldUrl = event.originalEvent.oldURL; 45 | 46 | if (oldUrl.indexOf('#') > -1) { 47 | oldSubSectionElement = $('#' + getCurrentSectionName() + '-' + oldUrl.substring(oldUrl.indexOf('#') + 1) + '-nav'); 48 | 49 | if (oldSubSectionElement) { 50 | oldSubSectionElement.removeClass('active'); 51 | } 52 | } 53 | } 54 | 55 | if (getCurrentHashName()) { 56 | $('#' + getCurrentSectionName() + '-' + getCurrentHashName() + '-nav').addClass('active'); 57 | } 58 | } 59 | 60 | function highlightActiveSection() { 61 | var pageId = getCurrentSectionName(); 62 | 63 | $('#' + pageId + '-nav').addClass('active'); 64 | } 65 | 66 | function getCurrentSectionName() { 67 | var path = window.location.pathname; 68 | var pageUrl = path.split('/').pop(); 69 | 70 | var sectionName = pageUrl.substring(0, pageUrl.indexOf('.')); 71 | 72 | // remove the wodr module- if its in the url 73 | sectionName = sectionName.replace('module-', ''); 74 | 75 | return sectionName; 76 | } 77 | 78 | function getCurrentHashName() { 79 | var pageSubSectionId; 80 | var pageSubSectionHash = window.location.hash; 81 | 82 | if (pageSubSectionHash) { 83 | pageSubSectionId = pageSubSectionHash.substring(1).replace('.', ''); 84 | 85 | return pageSubSectionId; 86 | } 87 | 88 | return false; 89 | } 90 | -------------------------------------------------------------------------------- /docs/styles/collapse.css: -------------------------------------------------------------------------------- 1 | @media only screen and (min-width: 681px) { 2 | nav > ul > li:hover .methods, 3 | .active .methods { 4 | display: block; 5 | } 6 | 7 | .methods { 8 | display: none; 9 | } 10 | 11 | nav > ul > li { 12 | padding: 20px 0; 13 | } 14 | 15 | nav > ul > li > a { 16 | padding: 0; 17 | } 18 | 19 | nav > ul > li.active a { 20 | margin-bottom: 10px; 21 | } 22 | 23 | nav > ul > li:hover > a, 24 | nav > ul > li.active > a { 25 | margin-bottom: 15px; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/styles/prettify-jsdoc.css: -------------------------------------------------------------------------------- 1 | /* JSDoc prettify.js theme */ 2 | 3 | /* plain text */ 4 | .pln { 5 | color: #000000; 6 | font-weight: normal; 7 | font-style: normal; 8 | } 9 | 10 | /* string content */ 11 | .str { 12 | color: hsl(104, 100%, 24%); 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | 17 | /* a keyword */ 18 | .kwd { 19 | color: #000000; 20 | font-weight: bold; 21 | font-style: normal; 22 | } 23 | 24 | /* a comment */ 25 | .com { 26 | font-weight: normal; 27 | font-style: italic; 28 | } 29 | 30 | /* a type name */ 31 | .typ { 32 | color: #000000; 33 | font-weight: normal; 34 | font-style: normal; 35 | } 36 | 37 | /* a literal value */ 38 | .lit { 39 | color: #006400; 40 | font-weight: normal; 41 | font-style: normal; 42 | } 43 | 44 | /* punctuation */ 45 | .pun { 46 | color: #000000; 47 | font-weight: bold; 48 | font-style: normal; 49 | } 50 | 51 | /* lisp open bracket */ 52 | .opn { 53 | color: #000000; 54 | font-weight: bold; 55 | font-style: normal; 56 | } 57 | 58 | /* lisp close bracket */ 59 | .clo { 60 | color: #000000; 61 | font-weight: bold; 62 | font-style: normal; 63 | } 64 | 65 | /* a markup tag name */ 66 | .tag { 67 | color: #006400; 68 | font-weight: normal; 69 | font-style: normal; 70 | } 71 | 72 | /* a markup attribute name */ 73 | .atn { 74 | color: #006400; 75 | font-weight: normal; 76 | font-style: normal; 77 | } 78 | 79 | /* a markup attribute value */ 80 | .atv { 81 | color: #006400; 82 | font-weight: normal; 83 | font-style: normal; 84 | } 85 | 86 | /* a declaration */ 87 | .dec { 88 | color: #000000; 89 | font-weight: bold; 90 | font-style: normal; 91 | } 92 | 93 | /* a variable name */ 94 | .var { 95 | color: #000000; 96 | font-weight: normal; 97 | font-style: normal; 98 | } 99 | 100 | /* a function name */ 101 | .fun { 102 | color: #000000; 103 | font-weight: bold; 104 | font-style: normal; 105 | } 106 | 107 | /* Specify class=linenums on a pre to get line numbering */ 108 | ol.linenums { 109 | margin-top: 0; 110 | margin-bottom: 0; 111 | } 112 | -------------------------------------------------------------------------------- /docs/styles/prettify-tomorrow.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Theme */ 2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 3 | /* Pretty printing styles. Used with prettify.js. */ 4 | /* SPAN elements with the classes below are added by prettyprint. */ 5 | /* plain text */ 6 | .pln { 7 | color: #4d4d4c; } 8 | 9 | @media screen { 10 | /* string content */ 11 | .str { 12 | color: hsl(104, 100%, 24%); } 13 | 14 | /* a keyword */ 15 | .kwd { 16 | color: hsl(240, 100%, 50%); } 17 | 18 | /* a comment */ 19 | .com { 20 | color: hsl(0, 0%, 60%); } 21 | 22 | /* a type name */ 23 | .typ { 24 | color: hsl(240, 100%, 32%); } 25 | 26 | /* a literal value */ 27 | .lit { 28 | color: hsl(240, 100%, 40%); } 29 | 30 | /* punctuation */ 31 | .pun { 32 | color: #000000; } 33 | 34 | /* lisp open bracket */ 35 | .opn { 36 | color: #000000; } 37 | 38 | /* lisp close bracket */ 39 | .clo { 40 | color: #000000; } 41 | 42 | /* a markup tag name */ 43 | .tag { 44 | color: #c82829; } 45 | 46 | /* a markup attribute name */ 47 | .atn { 48 | color: #f5871f; } 49 | 50 | /* a markup attribute value */ 51 | .atv { 52 | color: #3e999f; } 53 | 54 | /* a declaration */ 55 | .dec { 56 | color: #f5871f; } 57 | 58 | /* a variable name */ 59 | .var { 60 | color: #c82829; } 61 | 62 | /* a function name */ 63 | .fun { 64 | color: #4271ae; } } 65 | /* Use higher contrast and text-weight for printable form. */ 66 | @media print, projection { 67 | .str { 68 | color: #060; } 69 | 70 | .kwd { 71 | color: #006; 72 | font-weight: bold; } 73 | 74 | .com { 75 | color: #600; 76 | font-style: italic; } 77 | 78 | .typ { 79 | color: #404; 80 | font-weight: bold; } 81 | 82 | .lit { 83 | color: #044; } 84 | 85 | .pun, .opn, .clo { 86 | color: #440; } 87 | 88 | .tag { 89 | color: #006; 90 | font-weight: bold; } 91 | 92 | .atn { 93 | color: #404; } 94 | 95 | .atv { 96 | color: #060; } } 97 | /* Style */ 98 | /* 99 | pre.prettyprint { 100 | background: white; 101 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 102 | font-size: 12px; 103 | line-height: 1.5; 104 | border: 1px solid #ccc; 105 | padding: 10px; } 106 | */ 107 | 108 | /* Get LI elements to show when they are in the main article */ 109 | article ul li { 110 | list-style-type: circle; 111 | margin-left: 25px; 112 | } 113 | 114 | /* Specify class=linenums on a pre to get line numbering */ 115 | ol.linenums { 116 | margin-top: 0; 117 | margin-bottom: 0; } 118 | 119 | /* IE indents via margin-left */ 120 | li.L0, 121 | li.L1, 122 | li.L2, 123 | li.L3, 124 | li.L4, 125 | li.L5, 126 | li.L6, 127 | li.L7, 128 | li.L8, 129 | li.L9 { 130 | /* */ } 131 | 132 | /* Alternate shading for lines */ 133 | li.L1, 134 | li.L3, 135 | li.L5, 136 | li.L7, 137 | li.L9 { 138 | /* */ } 139 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | This example was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | It is linked to the phaser-react-tools package in the parent directory for development purposes. 4 | 5 | You can run `npm install` and then `npm start` to test your package. 6 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phaser-react-tools-example", 3 | "homepage": ".", 4 | "version": "0.0.0", 5 | "private": true, 6 | "scripts": { 7 | "start": "node ../node_modules/react-scripts/bin/react-scripts.js start", 8 | "build": "node ../node_modules/react-scripts/bin/react-scripts.js build", 9 | "test": "node ../node_modules/react-scripts/bin/react-scripts.js test", 10 | "eject": "node ../node_modules/react-scripts/bin/react-scripts.js eject" 11 | }, 12 | "dependencies": { 13 | "phaser": "^3.50.1", 14 | "phaser-react-tools": "file:..", 15 | "react": "file:../node_modules/react", 16 | "react-dom": "file:../node_modules/react-dom", 17 | "react-scripts": "file:../node_modules/react-scripts" 18 | }, 19 | "devDependencies": { 20 | "@babel/plugin-syntax-object-rest-spread": "^7.8.3" 21 | }, 22 | "eslintConfig": { 23 | "extends": "react-app" 24 | }, 25 | "browserslist": [ 26 | ">0.2%", 27 | "not dead", 28 | "not ie <= 11", 29 | "not op_mini all" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /example/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benrosen/phaser-react-tools/f534d61e737a525f9a222175cbe8caa6426b0736/example/public/favicon.ico -------------------------------------------------------------------------------- /example/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 12 | 16 | 17 | 18 | 27 | phaser-react-tools 28 | 29 | 30 | 31 | 34 | 35 |
36 | 37 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /example/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "phaser-react-tools", 3 | "name": "phaser-react-tools", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /example/src/App.js: -------------------------------------------------------------------------------- 1 | import EventEmitterButton from './components/EventEmitterButton' 2 | import FrameCounter from './components/FrameCounter' 3 | import { GameComponent } from 'phaser-react-tools' 4 | import Overlay from './components/Overlay' 5 | import React from 'react' 6 | import config from './config' 7 | 8 | const App = () => { 9 | return ( 10 |
11 |

My Phaser Game

12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | ) 20 | } 21 | 22 | export default App 23 | -------------------------------------------------------------------------------- /example/src/App.test.js: -------------------------------------------------------------------------------- 1 | import App from './App' 2 | import React from 'react' 3 | import ReactDOM from 'react-dom' 4 | 5 | describe('The example app', () => { 6 | it('renders without crashing', () => { 7 | const div = document.createElement('div') 8 | ReactDOM.render(, div) 9 | ReactDOM.unmountComponentAtNode(div) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /example/src/components/EventEmitterButton.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import events from '../events' 3 | import { useEventEmitter } from 'phaser-react-tools' 4 | 5 | export default () => { 6 | const emit = useEventEmitter(events.ON_BUTTON_CLICK) 7 | return ( 8 | 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /example/src/components/FrameCounter.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react' 2 | 3 | import events from '../events' 4 | import { useEventListener } from 'phaser-react-tools' 5 | 6 | export default () => { 7 | const [frame, setFrame] = useState(0) 8 | useEventListener(events.ON_UPDATE, (event) => { 9 | setFrame((frame) => (frame += 1)) 10 | }) 11 | return

Frame: {frame}

12 | } 13 | -------------------------------------------------------------------------------- /example/src/components/Overlay.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default function Overlay({ children }) { 4 | return ( 5 |
12 | {children} 13 |
14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /example/src/config.js: -------------------------------------------------------------------------------- 1 | import create from './scenes/create' 2 | import preload from './scenes/preload' 3 | import update from './scenes/update' 4 | 5 | export default { 6 | backgroundColor: '000000', 7 | height: 300, 8 | width: 400, 9 | scene: { 10 | preload: preload, 11 | create: create, 12 | update: update 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /example/src/events.js: -------------------------------------------------------------------------------- 1 | export default { 2 | ON_UPDATE: 'ON_UPDATE', 3 | ON_BUTTON_CLICK: 'ON_BUTTON_CLICK' 4 | } 5 | -------------------------------------------------------------------------------- /example/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 5 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 13 | monospace; 14 | } 15 | -------------------------------------------------------------------------------- /example/src/index.js: -------------------------------------------------------------------------------- 1 | import './index.css' 2 | 3 | import React from 'react' 4 | import ReactDOM from 'react-dom' 5 | import App from './App' 6 | 7 | ReactDOM.render(, document.getElementById('root')) 8 | -------------------------------------------------------------------------------- /example/src/scenes/create.js: -------------------------------------------------------------------------------- 1 | import Phaser from 'phaser' 2 | import events from '../events' 3 | 4 | export default function create() { 5 | this.game.events.on(events.ON_BUTTON_CLICK, (event) => { 6 | console.log(event) 7 | const { width, height } = this.game.config 8 | const color = new Phaser.Display.Color().random().color 9 | const radius = Phaser.Math.Between(0, Math.max(width, height) / 2) 10 | this.add.circle(width / 2, height / 2, radius, color) 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /example/src/scenes/preload.js: -------------------------------------------------------------------------------- 1 | export default function preload() { 2 | // do preload stuff 3 | } 4 | -------------------------------------------------------------------------------- /example/src/scenes/update.js: -------------------------------------------------------------------------------- 1 | import events from '../events' 2 | 3 | export default function update() { 4 | // do update stuff 5 | this.game.events.emit(events.ON_UPDATE) 6 | } 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phaser-react-tools", 3 | "version": "1.0.4", 4 | "description": "Toolkit for integrating Phaser and React.", 5 | "author": "benrosen", 6 | "license": "MIT", 7 | "repository": "benrosen/phaser-react-tools", 8 | "main": "dist/index.js", 9 | "module": "dist/index.modern.js", 10 | "source": "src/index.js", 11 | "engines": { 12 | "node": ">=10" 13 | }, 14 | "scripts": { 15 | "build": "microbundle-crl", 16 | "deploy": "run-s publish & git push -u origin HEAD", 17 | "document": "node_modules/.bin/jsdoc -c .jsdoc.json", 18 | "patch": "npm version patch -m 'Patch %s'", 19 | "predeploy": "run-s test build document", 20 | "start": "microbundle-crl watch --no-compress --format modern,cjs", 21 | "test": "run-s test:unit test:lint", 22 | "test:unit": "cross-env CI=1 react-scripts test --env=jsdom", 23 | "test:lint": "eslint . --ext .js,.jsx", 24 | "test:watch": "react-scripts test --env=jsdom" 25 | }, 26 | "peerDependencies": { 27 | "phaser": "^3.0.0", 28 | "react": "^16.0.0" 29 | }, 30 | "devDependencies": { 31 | "@testing-library/jest-dom": "^5.11.6", 32 | "@testing-library/react": "^11.2.2", 33 | "@testing-library/react-hooks": "^3.7.0", 34 | "babel-eslint": "^10.0.3", 35 | "cross-env": "^7.0.2", 36 | "eslint": "^6.8.0", 37 | "eslint-config-prettier": "^6.7.0", 38 | "eslint-config-standard": "^14.1.0", 39 | "eslint-config-standard-react": "^9.2.0", 40 | "eslint-plugin-import": "^2.18.2", 41 | "eslint-plugin-node": "^11.0.0", 42 | "eslint-plugin-prettier": "^3.1.1", 43 | "eslint-plugin-promise": "^4.2.1", 44 | "eslint-plugin-react": "^7.17.0", 45 | "eslint-plugin-standard": "^4.0.1", 46 | "jest-canvas-mock": "^2.3.0", 47 | "jsdoc": "^3.6.6", 48 | "microbundle-crl": "^0.13.10", 49 | "npm-run-all": "^4.1.5", 50 | "phaser": "^3.50.1", 51 | "prettier": "^2.0.4", 52 | "react": "^16.13.1", 53 | "react-dom": "^16.13.1", 54 | "react-scripts": "^3.4.1", 55 | "react-test-renderer": "^17.0.1" 56 | }, 57 | "files": [ 58 | "dist" 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /src/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "jest": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/components/GameComponent.jsx: -------------------------------------------------------------------------------- 1 | import { GameProvider } from '../contexts/GameContext' 2 | import PropTypes from 'prop-types' 3 | import React from 'react' 4 | import usePhaser from '../hooks/usePhaser' 5 | 6 | /** 7 | * A higher-order React functional component that manages the Phaser game. 8 | * 9 | * @function 10 | * @module GameComponent 11 | * @param {Object} props The component props. 12 | * @param {Array|Object} [props.children] The child components. 13 | * @param {Object} props.config The config object for the Phaser game instance. 14 | * @throws {ConfigError} Will throw a ConfigError if the Phaser game is mis-configured by the user. 15 | * @see module:usePhaser 16 | * @see module:GameProvider 17 | */ 18 | export default function GameComponent({ children, config }) { 19 | const [canvasRef, game] = usePhaser(config) 20 | return ( 21 |
22 | {children} 23 | 24 |
25 | ) 26 | } 27 | 28 | GameComponent.propTypes = { 29 | children: PropTypes.oneOfType([ 30 | PropTypes.arrayOf(PropTypes.node), 31 | PropTypes.node 32 | ]), 33 | config: PropTypes.object 34 | } 35 | -------------------------------------------------------------------------------- /src/components/GameComponent.test.js: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom/extend-expect' 2 | 3 | import React, { useContext } from 'react' 4 | 5 | import ConfigError from '../errors/ConfigError' 6 | import GameComponent from './GameComponent' 7 | import { GameContext } from '../contexts/GameContext' 8 | import Phaser from 'phaser' 9 | import { render } from '@testing-library/react' 10 | 11 | describe('The GameComponent component', () => { 12 | describe('children', () => { 13 | const childMessage = 'Hello world!' 14 | 15 | it('should render.', () => { 16 | const ChildComponent = () =>

{childMessage}

17 | const { getByText } = render( 18 | 19 | 20 | 21 | ) 22 | expect(getByText(childMessage)).toBeInTheDocument() 23 | }) 24 | 25 | it('should have access to a GameContext via the useContext hook.', () => { 26 | const ChildComponent = () => { 27 | useContext(GameContext) 28 | return

{childMessage}

29 | } 30 | const { getByText } = render( 31 | 32 | 33 | 34 | ) 35 | expect(getByText(childMessage)).toBeInTheDocument() 36 | }) 37 | }) 38 | 39 | describe('config', () => { 40 | it('should throw a ConfigError if the value of the type property is not Phaser.CANVAS.', () => { 41 | jest.spyOn(console, 'error') 42 | console.error.mockImplementation(() => {}) 43 | 44 | expect(() => 45 | render( 46 | 51 | ) 52 | ).toThrow(ConfigError) 53 | 54 | console.error.mockRestore() 55 | }) 56 | 57 | it('should throw a ConfigError if the value of the canvas property is defined.', () => { 58 | jest.spyOn(console, 'error') 59 | console.error.mockImplementation(() => {}) 60 | 61 | expect(() => 62 | render( 63 | 68 | ) 69 | ).toThrow(ConfigError) 70 | 71 | console.error.mockRestore() 72 | }) 73 | }) 74 | }) 75 | -------------------------------------------------------------------------------- /src/contexts/GameContext.js: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react' 2 | 3 | /** 4 | * A React Context object that stores the Phaser game instance. 5 | * 6 | * @module GameContext 7 | * @see module:GameProvider 8 | */ 9 | export const GameContext = createContext({}) 10 | 11 | /** 12 | * A higher-order React functional component that provides a GameContext to its children. 13 | * 14 | * @function 15 | * @module GameProvider 16 | * @param {Object} props The component props. 17 | * @param {Array|Object} [props.children] The child components. 18 | * @param {Object} props.value A Phaser game instance. 19 | * @see module:GameContext 20 | */ 21 | export const GameProvider = GameContext.Provider 22 | -------------------------------------------------------------------------------- /src/errors/ConfigError.js: -------------------------------------------------------------------------------- 1 | import InvalidPropertyNameError from './InvalidPropertyNameError' 2 | import MissingArgumentError from './MissingArgumentError' 3 | 4 | /** 5 | * An error that occurs when a protected value on the Phaser config object is set incorrectly. 6 | * 7 | * @class 8 | * @module ConfigError 9 | * @extends TypeError 10 | */ 11 | export default class ConfigError extends TypeError { 12 | /** 13 | * Creates an instance representing an error that occurs when a protected value on the Phaser config object is set incorrectly. 14 | * 15 | * @param {Object} config The Phaser config object whose property value is set incorrectly. 16 | * @param {*} propertyName The name of the property whose value is set incorrectly. 17 | * @throws {module:MissingArgumentError} Will throw a MissingArgumentError if required arguments are missing. 18 | */ 19 | constructor(config, propertyName) { 20 | if (!config) { 21 | throw new MissingArgumentError( 22 | 'You must provide the Phaser config object whose property value is set incorrectly when attempting to create a ConfigError.' 23 | ) 24 | } 25 | 26 | if (!propertyName) { 27 | throw new MissingArgumentError( 28 | 'You must provide the name of the property whose value is set incorrectly when attempting to create a ConfigError.' 29 | ) 30 | } 31 | 32 | const value = config[propertyName] 33 | 34 | if (value === undefined) { 35 | throw new InvalidPropertyNameError( 36 | `The Phaser config object does not have a property named ${propertyName}.` 37 | ) 38 | } 39 | 40 | super( 41 | `phaser-react-tools sets the ${propertyName} property of the Phaser config object internally. As such, the user-provided value of ${value} will be overridden.` 42 | ) 43 | 44 | Error.captureStackTrace(this, ConfigError) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/errors/ConfigError.test.js: -------------------------------------------------------------------------------- 1 | import ConfigError from './ConfigError' 2 | import InvalidPropertyNameError from './InvalidPropertyNameError' 3 | import MissingArgumentError from './MissingArgumentError' 4 | 5 | describe('The ConfigError', () => { 6 | it('should throw a MissingArgumentError if the Phaser config object whose property value is set incorrectly is not provided.', () => { 7 | expect(() => { 8 | const config = undefined 9 | const propertyName = 'title' 10 | throw new ConfigError(config, propertyName) 11 | }).toThrow(MissingArgumentError) 12 | }) 13 | 14 | it('should throw a MissingArgumentError if the name of the property whose value is set incorrectly is not provided.', () => { 15 | expect(() => { 16 | const config = { title: 'My Phaser Game' } 17 | const propertyName = undefined 18 | throw new ConfigError(config, propertyName) 19 | }).toThrow(MissingArgumentError) 20 | }) 21 | 22 | it('should throw an InvalidPropertyNameError if the property is not defined on the Phaser config object.', () => { 23 | expect(() => { 24 | const config = { title: 'My Phaser Game' } 25 | const propertyName = 'asdf' 26 | throw new ConfigError(config, propertyName) 27 | }).toThrow(InvalidPropertyNameError) 28 | }) 29 | 30 | it('should be throwable.', () => { 31 | expect(() => { 32 | throw new ConfigError({ title: 'My Phaser Game' }, 'title') 33 | }).toThrow(ConfigError) 34 | }) 35 | 36 | // TODO test for stack trace 37 | // it('should contain a stack trace.', () => {}) 38 | 39 | describe('message', () => { 40 | const config = { title: 'My Phaser Game' } 41 | const propertyName = 'title' 42 | const configError = new ConfigError(config, propertyName) 43 | const message = configError.message 44 | 45 | it('should be defined.', () => { 46 | expect(message).toBeDefined() 47 | }) 48 | 49 | it('should contain the name of the property whose value is set incorrectly.', () => { 50 | const expression = new RegExp(propertyName) 51 | expect(message).toMatch(expression) 52 | }) 53 | 54 | it('should contain the value of the property whose value is set incorrectly.', () => { 55 | const value = config[propertyName] 56 | const expression = new RegExp(value) 57 | expect(message).toMatch(expression) 58 | }) 59 | }) 60 | }) 61 | -------------------------------------------------------------------------------- /src/errors/InvalidPropertyNameError.js: -------------------------------------------------------------------------------- 1 | /** 2 | * An error that occurs when an invalid property name is provided. 3 | * 4 | * @class 5 | * @module InvalidPropertyNameError 6 | * @extends TypeError 7 | */ 8 | export default class InvalidPropertyNameError extends TypeError { 9 | /** 10 | * Creates an instance representing an error that occurs when an invalid property name is provided. 11 | * 12 | * @param {...any} [args] The error arguments. 13 | */ 14 | constructor(...args) { 15 | super(...args) 16 | Error.captureStackTrace(this, InvalidPropertyNameError) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/errors/InvalidPropertyNameError.test.js: -------------------------------------------------------------------------------- 1 | import InvalidPropertyNameError from './InvalidPropertyNameError' 2 | 3 | describe('The InvalidPropertyNameError', () => { 4 | it('should be throwable.', () => { 5 | expect(() => { 6 | throw new InvalidPropertyNameError() 7 | }).toThrow(InvalidPropertyNameError) 8 | }) 9 | 10 | it('should contain the message that was passed into its constructor.', () => { 11 | const message = 'Missing required argument.' 12 | const error = new InvalidPropertyNameError(message) 13 | expect(error.message).toBe(message) 14 | }) 15 | 16 | // TODO test for stack trace 17 | // it('should contain a stack trace.', () => {}) 18 | }) 19 | -------------------------------------------------------------------------------- /src/errors/MissingArgumentError.js: -------------------------------------------------------------------------------- 1 | /** 2 | * An error that occurs when a required argument is missing. 3 | * 4 | * @class 5 | * @module MissingArgumentError 6 | * @extends TypeError 7 | */ 8 | export default class MissingArgumentError extends TypeError { 9 | /** 10 | * Creates an instance representing an error that occurs when a required argument is missing. 11 | * 12 | * @param {...any} [args] The error arguments. 13 | */ 14 | constructor(...args) { 15 | super(...args) 16 | Error.captureStackTrace(this, MissingArgumentError) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/errors/MissingArgumentError.test.js: -------------------------------------------------------------------------------- 1 | import MissingArgumentError from './MissingArgumentError' 2 | 3 | describe('The MissingArgumentError', () => { 4 | it('should be throwable.', () => { 5 | expect(() => { 6 | throw new MissingArgumentError() 7 | }).toThrow(MissingArgumentError) 8 | }) 9 | 10 | it('should contain the message that was passed into its constructor.', () => { 11 | const message = 'Missing required argument.' 12 | const error = new MissingArgumentError(message) 13 | expect(error.message).toBe(message) 14 | }) 15 | 16 | // TODO test for stack trace 17 | // it('should contain a stack trace.', () => {}) 18 | }) 19 | -------------------------------------------------------------------------------- /src/hooks/useEventEmitter.js: -------------------------------------------------------------------------------- 1 | import { useCallback, useContext } from 'react' 2 | 3 | import { GameContext } from '../contexts/GameContext' 4 | 5 | /** 6 | * Returns a function that can emit an event of the given type. 7 | * 8 | * @function 9 | * @module useEventEmitter 10 | * @param {string} type The type of event to emit. 11 | * @returns {emitFunction} A function that can emit an event of the given type. 12 | */ 13 | export default function useEventEmitter(type) { 14 | const game = useContext(GameContext) 15 | 16 | return useCallback( 17 | (detail) => { 18 | game.events.emit(type, detail) 19 | }, 20 | [game] 21 | ) 22 | } 23 | 24 | /** 25 | * Emit an event. 26 | * 27 | * @callback emitFunction 28 | * @param {Object} [detail] The event payload. 29 | */ 30 | -------------------------------------------------------------------------------- /src/hooks/useEventListener.js: -------------------------------------------------------------------------------- 1 | import { useContext, useEffect } from 'react' 2 | 3 | import { GameContext } from '../contexts/GameContext' 4 | 5 | /** 6 | * Subscribe a callback function to events of the given type. 7 | * 8 | * @function 9 | * @module useEventListener 10 | * @param {string} type The type of event for which to listen. 11 | * @param {eventHandler} handler The event handler callback function. 12 | */ 13 | export default function useEventListener(type, handler) { 14 | const game = useContext(GameContext) 15 | useEffect(() => { 16 | if (game === undefined) { 17 | return 18 | } 19 | game.events.on(type, handler) 20 | return () => { 21 | game.events.off(type, handler) 22 | } 23 | }, [game, handler, type]) 24 | } 25 | 26 | /** 27 | * Handle an event. 28 | * 29 | * @callback eventHandler 30 | * @param {*} [event] The event to be handled. 31 | * @see module:useEventListener 32 | */ 33 | -------------------------------------------------------------------------------- /src/hooks/usePhaser.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from 'react' 2 | 3 | import ConfigError from '../errors/ConfigError' 4 | import Phaser from 'phaser' 5 | 6 | /** 7 | * Returns a setup object containing a canvas ref and a reference to the Phaser game instance. 8 | * 9 | * @function 10 | * @module usePhaser 11 | * @param {Object} [config] The config object for the Phaser game instance. 12 | * @returns {InstanceConfig} A config object containing a canvas ref and a reference to the Phaser game instance. 13 | * @throws {module:ConfigError} Will throw a ConfigError if the Phaser game is mis-configured by the user. 14 | */ 15 | export default function usePhaser(config = {}) { 16 | const canvasRef = useRef() 17 | const [game, setGame] = useState() 18 | 19 | useEffect(() => { 20 | if (config.canvas) { 21 | throw new ConfigError(config, 'canvas') 22 | } 23 | 24 | if (config.type !== undefined && config.type !== Phaser.CANVAS) { 25 | throw new ConfigError(config, 'type') 26 | } 27 | 28 | const modifiedConfig = config 29 | 30 | modifiedConfig.canvas = canvasRef.current 31 | modifiedConfig.type = Phaser.CANVAS 32 | 33 | const userDefinedPostBootCallback = config.callbacks?.postBoot 34 | 35 | const auxiliaryPostBootCallback = (bootedGame) => { 36 | setGame(() => bootedGame) 37 | } 38 | 39 | if (userDefinedPostBootCallback) { 40 | modifiedConfig.callbacks.postBoot = (bootedGame) => { 41 | auxiliaryPostBootCallback(bootedGame) 42 | userDefinedPostBootCallback(bootedGame) 43 | } 44 | } else if (config.callbacks) { 45 | console.log('user did ') 46 | modifiedConfig.callbacks.postBoot = auxiliaryPostBootCallback 47 | } else { 48 | modifiedConfig.callbacks = { 49 | postBoot: auxiliaryPostBootCallback 50 | } 51 | } 52 | 53 | const phaser = new Phaser.Game(modifiedConfig) 54 | 55 | return () => { 56 | phaser.destroy() 57 | } 58 | }, [config]) 59 | 60 | return [canvasRef, game] 61 | } 62 | 63 | /** 64 | * A config object containing a canvas ref and a reference to the Phaser game instance. 65 | * 66 | * @typedef InstanceConfig 67 | * @type {Object} 68 | * @property {Object} canvasRef The reference to the Phaser game canvas. 69 | * @property {Object} game The Phaser game instance. 70 | * @see module:usePhaser 71 | * @see module:GameComponent 72 | */ 73 | -------------------------------------------------------------------------------- /src/hooks/usePhaser.test.js: -------------------------------------------------------------------------------- 1 | import ConfigError from '../errors/ConfigError' 2 | import Phaser from 'phaser' 3 | import { renderHook } from '@testing-library/react-hooks' 4 | import usePhaser from './usePhaser' 5 | 6 | describe('The usePhaser hook', () => { 7 | it('should throw a ConfigError if the value of config.canvas is defined.', () => { 8 | const config = { canvas: 'abc' } 9 | jest.spyOn(console, 'error') 10 | console.error.mockImplementation(() => {}) 11 | expect(() => renderHook(() => usePhaser(config))).toThrow(ConfigError) 12 | console.error.mockRestore() 13 | }) 14 | 15 | it('should throw a ConfigError if the value of config.type is not Phaser.CANVAS.', () => { 16 | const config = { type: Phaser.AUTO } 17 | jest.spyOn(console, 'error') 18 | console.error.mockImplementation(() => {}) 19 | expect(() => renderHook(() => usePhaser(config))).toThrow(ConfigError) 20 | console.error.mockRestore() 21 | }) 22 | 23 | it('should not throw a ConfigError if the the value of config.type is Phaser.CANVAS.', () => { 24 | const config = { type: Phaser.CANVAS } 25 | expect(() => renderHook(() => usePhaser(config))).not.toThrow(ConfigError) 26 | }) 27 | 28 | it('should return a setup object.', () => { 29 | const { result } = renderHook(() => usePhaser()) 30 | expect(result.current).toBeDefined() 31 | }) 32 | 33 | describe('setup object', () => { 34 | const userConfig = { 35 | height: 200, 36 | title: 'My Phaser Game', 37 | width: 300 38 | } 39 | 40 | const { result } = renderHook(() => usePhaser(userConfig)) 41 | const [canvasRef, gameInstance] = result.current 42 | 43 | describe('canvas ref', () => { 44 | it('should be defined.', () => { 45 | expect(canvasRef).toBeDefined() 46 | }) 47 | 48 | describe('current value', () => { 49 | it('should be undefined.', () => { 50 | expect(canvasRef.current).toBeUndefined() 51 | }) 52 | }) 53 | }) 54 | 55 | describe('pre-boot game instance', () => { 56 | it('should be undefined.', () => { 57 | expect(gameInstance).toBeUndefined() 58 | }) 59 | }) 60 | 61 | // 62 | // TODO test post-boot game instance 63 | // 64 | // describe('post-boot game instance', () => { 65 | // describe('config', () => { 66 | // const gameConfig = game.config 67 | 68 | // it('should be defined.', () => { 69 | // expect(gameConfig).toBeDefined() 70 | // }) 71 | 72 | // // TODO test that gameConfig contains all data from userConfig 73 | // it('should contain the Phaser config object data.', () => { 74 | // // 75 | // }) 76 | 77 | // describe('canvas property', () => { 78 | // const canvas = gameConfig.canvas 79 | 80 | // it('should be defined.', () => { 81 | // expect(canvas).toBeDefined() 82 | // }) 83 | 84 | // // TODO test canvasRef reference 85 | // // it('should reference the canvasRef.', () => { 86 | // // // 87 | // // }) 88 | // }) 89 | 90 | // describe('type property', () => { 91 | // const type = gameConfig.type 92 | 93 | // it('should be defined.', () => { 94 | // expect(type).toBeDefined() 95 | // }) 96 | 97 | // it('should equal Phaser.CANVAS.', () => { 98 | // expect(type).toBe(Phaser.CANVAS) 99 | // }) 100 | // }) 101 | 102 | // describe('postBoot callback', () => { 103 | // const postBootCallback = gameConfig.callbacks.postBoot 104 | 105 | // it('should be defined', () => { 106 | // expect(postBootCallback).toBeDefined() 107 | // }) 108 | // }) 109 | // }) 110 | // }) 111 | }) 112 | }) 113 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { GameContext, GameProvider } from './contexts/GameContext' 2 | 3 | import GameComponent from './components/GameComponent' 4 | import useEventEmitter from './hooks/useEventEmitter' 5 | import useEventListener from './hooks/useEventListener' 6 | import usePhaser from './hooks/usePhaser' 7 | 8 | export { 9 | GameComponent, 10 | GameContext, 11 | GameProvider, 12 | useEventEmitter, 13 | useEventListener, 14 | usePhaser 15 | } 16 | -------------------------------------------------------------------------------- /src/index.test.js: -------------------------------------------------------------------------------- 1 | import { 2 | GameComponent, 3 | GameContext, 4 | GameProvider, 5 | useEventEmitter, 6 | useEventListener, 7 | usePhaser 8 | } from './index.js' 9 | 10 | describe('The phaser-react-tools module', () => { 11 | it('should export GameComponent.', () => { 12 | expect(GameComponent).toBeTruthy() 13 | }) 14 | 15 | it('should export GameContext.', () => { 16 | expect(GameContext).toBeTruthy() 17 | }) 18 | 19 | it('should export GameProvider.', () => { 20 | expect(GameProvider).toBeTruthy() 21 | }) 22 | 23 | it('should export useEventEmitter.', () => { 24 | expect(useEventEmitter).toBeTruthy() 25 | }) 26 | 27 | it('should export useEventListener.', () => { 28 | expect(useEventListener).toBeTruthy() 29 | }) 30 | 31 | it('should export usePhaser.', () => { 32 | expect(usePhaser).toBeTruthy() 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | import 'jest-canvas-mock' 2 | --------------------------------------------------------------------------------