├── .eslintignore ├── .npmignore ├── .babelrc ├── tests ├── .eslintrc.yml ├── index.html └── index.js ├── .eslintrc.yml ├── README.md ├── .github └── workflows │ └── nodejs.yml ├── CHANGELOG.md ├── package.json ├── src └── index.js └── dist └── PhaserUpdatePlugin.js /.eslintignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | tests/ 2 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | ["transform-es2015-modules-umd", { 4 | "globals": { 5 | "phaser": "Phaser" 6 | } 7 | }] 8 | ], 9 | "moduleId": "phaser-plugin-update", 10 | "presets": ["env"] 11 | } 12 | -------------------------------------------------------------------------------- /tests/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | extends: '../.eslintrc.yml' 2 | env: 3 | browser: true 4 | es6: false 5 | globals: 6 | PhaserUpdatePlugin: readonly 7 | parserOptions: 8 | sourceType: script 9 | rules: 10 | no-console: 11 | - warn 12 | - allow: 13 | - assert 14 | - log 15 | -------------------------------------------------------------------------------- /tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | PhaserUpdatePlugin test 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | extends: 'eslint:recommended' 2 | env: 3 | browser: true 4 | es6: true 5 | globals: 6 | Phaser: readonly 7 | parserOptions: 8 | sourceType: module 9 | rules: 10 | indent: 11 | - error 12 | - 2 13 | linebreak-style: 14 | - error 15 | - unix 16 | no-console: 17 | - warn 18 | - allow: 19 | - log 20 | quotes: 21 | - error 22 | - single 23 | semi: 24 | - error 25 | - always 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Phaser 3 Update Plugin 2 | ====================== 3 | 4 | Runs a Game Object's `update` method automatically. 5 | 6 | ```javascript 7 | new Phaser.Game({ 8 | plugins: { 9 | scene: [{ key: 'updatePlugin', plugin: PhaserUpdatePlugin, mapping: 'updates' }] 10 | } 11 | }); 12 | ``` 13 | 14 | In a scene: 15 | 16 | ```javascript 17 | this.updates.add(gameObject); 18 | // or 19 | this.updates.addMultiple([ gameObject1, gameObject2 ]); 20 | ``` 21 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [14.x, 16.x, 18.x] 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - run: npm install 21 | - run: npm run build --if-present 22 | - run: npm test 23 | env: 24 | CI: true 25 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2.1.0 2 | ----- 3 | 4 | - Changed: `add()`, `addMultiple()`, and `remove()` return the objects passed to them (#3). Thanks @skn3. 5 | 6 | 2.0.4 7 | ----- 8 | 9 | - Fixed an error when destroying a game object from its update method (#2). Thanks @Olliebrown. 10 | 11 | 2.0.3 12 | ----- 13 | 14 | - Changed Phaser to a peer dependency. 15 | 16 | 2.0.2 17 | ----- 18 | 19 | - Updated dev dependencies. 20 | 21 | 2.0.1 22 | ----- 23 | 24 | - Fixed wrong method name in sceneDestroy() (#1). 25 | 26 | 2.0.0 27 | ----- 28 | 29 | - Added global `PhaserUpdatePlugin`. 30 | - Removed `Phaser.Plugins.UpdatePlugin`. 31 | - Changed 'main' file to `src/index.js` (ES6 module). 32 | - Renamed UMD script to `dist/PhaserUpdatePlugin.js`. 33 | 34 | 1.0.0 35 | ----- 36 | 37 | - npm release 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phaser-plugin-update", 3 | "version": "2.1.0", 4 | "description": "Runs a Game Object's `update` method automatically.", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "preversion": "npm run test && npm run build && npm run test:dist && git add dist", 8 | "test": "npx eslint src/index.js", 9 | "test:dist": "node -c dist/PhaserUpdatePlugin.js" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/samme/phaser-plugin-update.git" 14 | }, 15 | "keywords": [ 16 | "phaser", 17 | "phaser3", 18 | "phaser-plugin", 19 | "phaser3-plugin" 20 | ], 21 | "author": "samme", 22 | "license": "ISC", 23 | "bugs": { 24 | "url": "https://github.com/samme/phaser-plugin-update/issues" 25 | }, 26 | "homepage": "https://github.com/samme/phaser-plugin-update#readme", 27 | "devDependencies": { 28 | "phaser": "3.88.0" 29 | }, 30 | "peerDependencies": { 31 | "phaser": "^3.16.2" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import Phaser from 'phaser'; 2 | 3 | export default class UpdatePlugin extends Phaser.Plugins.ScenePlugin { 4 | boot () { 5 | const events = this.systems.events; 6 | 7 | this.gameObjects = new Phaser.Structs.Set(); 8 | 9 | events.on('update', this.sceneUpdate, this); 10 | events.on('shutdown', this.sceneShutdown, this); 11 | events.once('destroy', this.sceneDestroy, this); 12 | } 13 | 14 | sceneUpdate (time, delta) { 15 | this.gameObjects.each(function (obj) { 16 | obj.update(time, delta); 17 | }); 18 | } 19 | 20 | sceneShutdown () { 21 | this.gameObjects.clear(); 22 | } 23 | 24 | sceneDestroy () { 25 | const events = this.systems.events; 26 | 27 | events.off('update', this.sceneUpdate, this); 28 | events.off('shutdown', this.sceneShutdown, this); 29 | events.off('destroy', this.sceneDestroy, this); 30 | 31 | this.gameObjects = null; 32 | this.scene = null; 33 | this.systems = null; 34 | } 35 | 36 | add (obj) { 37 | obj.once('destroy', this.remove, this); 38 | this.gameObjects.set(obj); 39 | return obj; 40 | } 41 | 42 | addMultiple (objs) { 43 | objs.forEach(this.add, this); 44 | return objs; 45 | } 46 | 47 | remove (obj) { 48 | obj.off('destroy', this.remove, this); 49 | this.gameObjects.delete(obj); 50 | return obj; 51 | } 52 | 53 | dump () { 54 | // console.log('gameObjects', this.gameObjects.getArray()); 55 | console.log('gameObjects: %s', this.gameObjects.size); 56 | } 57 | } 58 | 59 | if (typeof window !== 'undefined') { 60 | window.PhaserUpdatePlugin = UpdatePlugin; 61 | } 62 | -------------------------------------------------------------------------------- /tests/index.js: -------------------------------------------------------------------------------- 1 | console.assert(Phaser, 'Phaser'); 2 | 3 | console.assert(PhaserUpdatePlugin, 'PhaserUpdatePlugin'); 4 | 5 | var scene = { 6 | 7 | create: function () { 8 | var sprite1 = this.add.circle(32, 32, 16, 0); 9 | var sprite2 = this.add.circle(64, 64, 16, 0); 10 | var sprite3 = this.add.circle(96, 96, 16, 0); 11 | var sprite4 = this.add.circle(128, 128, 16, 0); 12 | var sprite5 = this.add.circle(160, 160, 16, 0); 13 | 14 | var scene = this; 15 | 16 | sprite1.update = function () { this.x++; }; 17 | sprite2.update = function () { this.y++; }; 18 | sprite3.update = function () { this.x++; this.y++; }; 19 | sprite4.update = function (time, delta) { 20 | console.assert((typeof time) === 'number'); 21 | console.assert((typeof delta) === 'number'); 22 | console.log('time, delta', time, delta); 23 | console.log('remove'); 24 | 25 | scene.updates.remove(this); 26 | }; 27 | sprite5.update = function () { 28 | console.log('destroy'); 29 | 30 | this.destroy(); 31 | }; 32 | 33 | this.updates.add(sprite1); 34 | console.assert(this.updates.gameObjects.size === 1); 35 | console.assert(this.updates.gameObjects.contains(sprite1)); 36 | 37 | this.updates.remove(sprite1); 38 | console.assert(this.updates.gameObjects.size === 0); 39 | console.assert(!this.updates.gameObjects.contains(sprite1)); 40 | 41 | this.updates.addMultiple([sprite2, sprite3, sprite4, sprite5]); 42 | console.assert(this.updates.gameObjects.size === 4); 43 | 44 | this.time.delayedCall(100, function () { 45 | console.assert(this.updates.gameObjects.size === 2); 46 | console.assert(this.updates.gameObjects.contains(sprite2)); 47 | console.assert(this.updates.gameObjects.contains(sprite3)); 48 | console.assert(!this.updates.gameObjects.contains(sprite4)); 49 | console.assert(!this.updates.gameObjects.contains(sprite5)); 50 | }, null, this); 51 | 52 | this.time.delayedCall(3000, function () { 53 | console.assert(this.updates.gameObjects.size === 2); 54 | console.log('scene.stop()'); 55 | this.scene.stop(); 56 | // console.log('scene.remove()'); 57 | // this.scene.remove(); 58 | }, null, this); 59 | 60 | this.events.once('shutdown', function () { 61 | console.log('shutdown'); 62 | console.assert(this.updates.gameObjects.size === 0); 63 | }, this); 64 | } 65 | }; 66 | 67 | new Phaser.Game({ 68 | 69 | width: 480, height: 480, 70 | 71 | backgroundColor: 0xdddddd, 72 | 73 | scene: scene, 74 | 75 | plugins: { 76 | scene: [{ key: 'UpdatePlugin', plugin: PhaserUpdatePlugin, mapping: 'updates' }] 77 | } 78 | 79 | }); 80 | -------------------------------------------------------------------------------- /dist/PhaserUpdatePlugin.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | if (typeof define === "function" && define.amd) { 3 | define('phaser-plugin-update', ['exports', 'phaser'], factory); 4 | } else if (typeof exports !== "undefined") { 5 | factory(exports, require('phaser')); 6 | } else { 7 | var mod = { 8 | exports: {} 9 | }; 10 | factory(mod.exports, global.Phaser); 11 | global.phaserPluginUpdate = mod.exports; 12 | } 13 | })(this, function (exports, _phaser) { 14 | 'use strict'; 15 | 16 | Object.defineProperty(exports, "__esModule", { 17 | value: true 18 | }); 19 | 20 | var _phaser2 = _interopRequireDefault(_phaser); 21 | 22 | function _interopRequireDefault(obj) { 23 | return obj && obj.__esModule ? obj : { 24 | default: obj 25 | }; 26 | } 27 | 28 | function _classCallCheck(instance, Constructor) { 29 | if (!(instance instanceof Constructor)) { 30 | throw new TypeError("Cannot call a class as a function"); 31 | } 32 | } 33 | 34 | var _createClass = function () { 35 | function defineProperties(target, props) { 36 | for (var i = 0; i < props.length; i++) { 37 | var descriptor = props[i]; 38 | descriptor.enumerable = descriptor.enumerable || false; 39 | descriptor.configurable = true; 40 | if ("value" in descriptor) descriptor.writable = true; 41 | Object.defineProperty(target, descriptor.key, descriptor); 42 | } 43 | } 44 | 45 | return function (Constructor, protoProps, staticProps) { 46 | if (protoProps) defineProperties(Constructor.prototype, protoProps); 47 | if (staticProps) defineProperties(Constructor, staticProps); 48 | return Constructor; 49 | }; 50 | }(); 51 | 52 | function _possibleConstructorReturn(self, call) { 53 | if (!self) { 54 | throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 55 | } 56 | 57 | return call && (typeof call === "object" || typeof call === "function") ? call : self; 58 | } 59 | 60 | function _inherits(subClass, superClass) { 61 | if (typeof superClass !== "function" && superClass !== null) { 62 | throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); 63 | } 64 | 65 | subClass.prototype = Object.create(superClass && superClass.prototype, { 66 | constructor: { 67 | value: subClass, 68 | enumerable: false, 69 | writable: true, 70 | configurable: true 71 | } 72 | }); 73 | if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; 74 | } 75 | 76 | var UpdatePlugin = function (_Phaser$Plugins$Scene) { 77 | _inherits(UpdatePlugin, _Phaser$Plugins$Scene); 78 | 79 | function UpdatePlugin() { 80 | _classCallCheck(this, UpdatePlugin); 81 | 82 | return _possibleConstructorReturn(this, (UpdatePlugin.__proto__ || Object.getPrototypeOf(UpdatePlugin)).apply(this, arguments)); 83 | } 84 | 85 | _createClass(UpdatePlugin, [{ 86 | key: 'boot', 87 | value: function boot() { 88 | var events = this.systems.events; 89 | 90 | this.gameObjects = new _phaser2.default.Structs.Set(); 91 | 92 | events.on('update', this.sceneUpdate, this); 93 | events.on('shutdown', this.sceneShutdown, this); 94 | events.once('destroy', this.sceneDestroy, this); 95 | } 96 | }, { 97 | key: 'sceneUpdate', 98 | value: function sceneUpdate(time, delta) { 99 | this.gameObjects.each(function (obj) { 100 | obj.update(time, delta); 101 | }); 102 | } 103 | }, { 104 | key: 'sceneShutdown', 105 | value: function sceneShutdown() { 106 | this.gameObjects.clear(); 107 | } 108 | }, { 109 | key: 'sceneDestroy', 110 | value: function sceneDestroy() { 111 | var events = this.systems.events; 112 | 113 | events.off('update', this.sceneUpdate, this); 114 | events.off('shutdown', this.sceneShutdown, this); 115 | events.off('destroy', this.sceneDestroy, this); 116 | 117 | this.gameObjects = null; 118 | this.scene = null; 119 | this.systems = null; 120 | } 121 | }, { 122 | key: 'add', 123 | value: function add(obj) { 124 | obj.once('destroy', this.remove, this); 125 | this.gameObjects.set(obj); 126 | return obj; 127 | } 128 | }, { 129 | key: 'addMultiple', 130 | value: function addMultiple(objs) { 131 | objs.forEach(this.add, this); 132 | return objs; 133 | } 134 | }, { 135 | key: 'remove', 136 | value: function remove(obj) { 137 | obj.off('destroy', this.remove, this); 138 | this.gameObjects.delete(obj); 139 | return obj; 140 | } 141 | }, { 142 | key: 'dump', 143 | value: function dump() { 144 | // console.log('gameObjects', this.gameObjects.getArray()); 145 | console.log('gameObjects: %s', this.gameObjects.size); 146 | } 147 | }]); 148 | 149 | return UpdatePlugin; 150 | }(_phaser2.default.Plugins.ScenePlugin); 151 | 152 | exports.default = UpdatePlugin; 153 | 154 | 155 | if (typeof window !== 'undefined') { 156 | window.PhaserUpdatePlugin = UpdatePlugin; 157 | } 158 | }); 159 | --------------------------------------------------------------------------------