├── .gitattributes ├── .gitignore ├── .vscode └── launch.json ├── .yarn ├── plugins │ └── @yarnpkg │ │ └── plugin-workspace-tools.cjs └── releases │ └── yarn-berry.cjs ├── .yarnrc.yml ├── LICENSE ├── README.md ├── package.json ├── workspaces ├── javascript-example │ ├── README.md │ ├── package.json │ ├── src │ │ ├── assets │ │ │ ├── atlases │ │ │ │ ├── emoji.json │ │ │ │ ├── emoji.png │ │ │ │ ├── emoji.tps │ │ │ │ └── emoji │ │ │ │ │ ├── 1f31a.png │ │ │ │ │ ├── 1f31d.png │ │ │ │ │ ├── 1f31e.png │ │ │ │ │ ├── 1f47d.png │ │ │ │ │ ├── 1f47f.png │ │ │ │ │ ├── 1f4a9.png │ │ │ │ │ ├── 1f608.png │ │ │ │ │ ├── 1f60d.png │ │ │ │ │ ├── 1f61c.png │ │ │ │ │ ├── 1f621.png │ │ │ │ │ ├── 1f62c.png │ │ │ │ │ ├── 1f62d.png │ │ │ │ │ ├── 1f62e.png │ │ │ │ │ ├── 1f631.png │ │ │ │ │ ├── 1f912.png │ │ │ │ │ ├── 1f913.png │ │ │ │ │ ├── 1f915.png │ │ │ │ │ ├── 1f922.png │ │ │ │ │ ├── 1f92a.png │ │ │ │ │ ├── 1f92c.png │ │ │ │ │ ├── 1f92e.png │ │ │ │ │ ├── 1f92f.png │ │ │ │ │ ├── 1f975.png │ │ │ │ │ └── 1f976.png │ │ │ ├── tilemaps │ │ │ │ ├── level.json │ │ │ │ └── level.tmx │ │ │ └── tilesets │ │ │ │ ├── kenney-tileset-64px-extruded.png │ │ │ │ └── kenney-tileset-64px.png │ │ ├── index.html │ │ ├── index.js │ │ └── main-scene.js │ └── webpack.config.js ├── javascript-no-module-example │ ├── README.md │ ├── assets │ │ ├── atlases │ │ │ ├── emoji.json │ │ │ ├── emoji.png │ │ │ ├── emoji.tps │ │ │ └── emoji │ │ │ │ ├── 1f31a.png │ │ │ │ ├── 1f31d.png │ │ │ │ ├── 1f31e.png │ │ │ │ ├── 1f47d.png │ │ │ │ ├── 1f47f.png │ │ │ │ ├── 1f4a9.png │ │ │ │ ├── 1f608.png │ │ │ │ ├── 1f60d.png │ │ │ │ ├── 1f61c.png │ │ │ │ ├── 1f621.png │ │ │ │ ├── 1f62c.png │ │ │ │ ├── 1f62d.png │ │ │ │ ├── 1f62e.png │ │ │ │ ├── 1f631.png │ │ │ │ ├── 1f912.png │ │ │ │ ├── 1f913.png │ │ │ │ ├── 1f915.png │ │ │ │ ├── 1f922.png │ │ │ │ ├── 1f92a.png │ │ │ │ ├── 1f92c.png │ │ │ │ ├── 1f92e.png │ │ │ │ ├── 1f92f.png │ │ │ │ ├── 1f975.png │ │ │ │ └── 1f976.png │ │ ├── tilemaps │ │ │ ├── level.json │ │ │ └── level.tmx │ │ └── tilesets │ │ │ ├── kenney-tileset-64px-extruded.png │ │ │ └── kenney-tileset-64px.png │ ├── index.html │ └── index.js ├── plugin │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── cypress.json │ ├── cypress │ │ ├── integration │ │ │ ├── collision-events.spec.js │ │ │ ├── gameobject-collide-gameobject.spec.js │ │ │ ├── gameobject-collide-tiles.spec.js │ │ │ └── pair-collision-events.spec.js │ │ ├── plugins │ │ │ └── index.js │ │ └── support │ │ │ ├── commands.js │ │ │ └── index.js │ ├── doc-source-assets │ │ ├── collision-plugin-demo.gif │ │ └── collision-simple-demo.gif │ ├── doc-theme │ │ ├── assets │ │ │ ├── css │ │ │ │ └── main.css │ │ │ ├── images │ │ │ │ ├── icons.png │ │ │ │ ├── icons@2x.png │ │ │ │ ├── widgets.png │ │ │ │ └── widgets@2x.png │ │ │ └── js │ │ │ │ └── main.js │ │ ├── layouts │ │ │ └── default.hbs │ │ ├── partials │ │ │ ├── analytics.hbs │ │ │ ├── breadcrumb.hbs │ │ │ ├── comment.hbs │ │ │ ├── footer.hbs │ │ │ ├── header.hbs │ │ │ ├── hierarchy.hbs │ │ │ ├── index.hbs │ │ │ ├── member.declaration.hbs │ │ │ ├── member.getterSetter.hbs │ │ │ ├── member.hbs │ │ │ ├── member.reference.hbs │ │ │ ├── member.signature.body.hbs │ │ │ ├── member.signature.title.hbs │ │ │ ├── member.signatures.hbs │ │ │ ├── member.sources.hbs │ │ │ ├── members.group.hbs │ │ │ ├── members.hbs │ │ │ ├── navigation.hbs │ │ │ ├── parameter.hbs │ │ │ ├── toc.hbs │ │ │ ├── toc.root.hbs │ │ │ ├── type.hbs │ │ │ ├── typeAndParent.hbs │ │ │ └── typeParameters.hbs │ │ └── templates │ │ │ ├── index.hbs │ │ │ └── reflection.hbs │ ├── eslintrc.js │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── collision-types.ts │ │ ├── index.ts │ │ ├── logger.ts │ │ ├── mocks │ │ │ ├── game-objects.js │ │ │ ├── matter.js │ │ │ ├── phaser.js │ │ │ └── scene.js │ │ ├── phaser-matter-collision-plugin.ts │ │ ├── tests │ │ │ ├── plugin-collisions.test.ts │ │ │ ├── plugin-gameobject-collisions.test.ts │ │ │ └── plugin-lifecycle.test.ts │ │ ├── utils.ts │ │ └── valid-collision-object.ts │ ├── tests │ │ ├── assets │ │ │ ├── atlases │ │ │ │ ├── emoji.json │ │ │ │ ├── emoji.png │ │ │ │ ├── emoji.tps │ │ │ │ └── emoji │ │ │ │ │ ├── 1f31a.png │ │ │ │ │ ├── 1f31d.png │ │ │ │ │ ├── 1f31e.png │ │ │ │ │ ├── 1f47d.png │ │ │ │ │ ├── 1f47f.png │ │ │ │ │ ├── 1f4a9.png │ │ │ │ │ ├── 1f608.png │ │ │ │ │ ├── 1f60d.png │ │ │ │ │ ├── 1f61c.png │ │ │ │ │ ├── 1f621.png │ │ │ │ │ ├── 1f62c.png │ │ │ │ │ ├── 1f62d.png │ │ │ │ │ ├── 1f62e.png │ │ │ │ │ ├── 1f631.png │ │ │ │ │ ├── 1f912.png │ │ │ │ │ ├── 1f913.png │ │ │ │ │ ├── 1f915.png │ │ │ │ │ ├── 1f922.png │ │ │ │ │ ├── 1f92a.png │ │ │ │ │ ├── 1f92c.png │ │ │ │ │ ├── 1f92e.png │ │ │ │ │ ├── 1f92f.png │ │ │ │ │ ├── 1f975.png │ │ │ │ │ └── 1f976.png │ │ │ ├── cursors │ │ │ │ ├── pointer.cur │ │ │ │ ├── pointer.png │ │ │ │ └── pointer.svg │ │ │ ├── images │ │ │ │ ├── block.png │ │ │ │ ├── chain.png │ │ │ │ └── wooden-plank.png │ │ │ ├── spritesheets │ │ │ │ └── 0x72-industrial-player-32px-extruded.png │ │ │ ├── tilemaps │ │ │ │ ├── level.json │ │ │ │ ├── level.tmx │ │ │ │ ├── simple-map-collision-mapped.json │ │ │ │ ├── simple-map-collision-mapped.tmx │ │ │ │ ├── simple-map-collision-mapped2.json │ │ │ │ ├── simple-map-with-collisions.json │ │ │ │ ├── simple-map-with-collisions.tmx │ │ │ │ ├── simple-map.json │ │ │ │ ├── simple-map.tmx │ │ │ │ └── tileset-collision-shapes.json │ │ │ └── tilesets │ │ │ │ ├── kenney-tileset-64px-extruded.png │ │ │ │ └── kenney-tileset-64px.png │ │ ├── collision-events │ │ │ ├── index.html │ │ │ └── src │ │ │ │ ├── index.js │ │ │ │ └── main-scene.js │ │ ├── gameobject-collide-gameobject │ │ │ ├── index.html │ │ │ └── src │ │ │ │ ├── index.js │ │ │ │ └── main-scene.js │ │ ├── gameobject-collide-tiles │ │ │ ├── index.html │ │ │ └── src │ │ │ │ ├── index.js │ │ │ │ └── main-scene.js │ │ ├── pair-collision-events │ │ │ ├── index.html │ │ │ └── src │ │ │ │ ├── index.js │ │ │ │ └── main-scene.js │ │ ├── restarting │ │ │ ├── index.html │ │ │ └── src │ │ │ │ ├── index.js │ │ │ │ └── main-scene.js │ │ ├── slopes-plugin │ │ │ ├── index.html │ │ │ └── src │ │ │ │ ├── create-rotating-platform.js │ │ │ │ ├── index.js │ │ │ │ ├── main-scene.js │ │ │ │ ├── multi-key.js │ │ │ │ └── player.js │ │ └── test-utils.js │ ├── tsconfig.json │ ├── typedoc.json │ ├── webpack.config.js │ └── webpack.test.config.js └── typescript-example │ ├── .gitignore │ ├── README.md │ ├── package.json │ ├── src │ ├── assets │ │ ├── atlases │ │ │ ├── emoji.json │ │ │ ├── emoji.png │ │ │ ├── emoji.tps │ │ │ └── emoji │ │ │ │ ├── 1f31a.png │ │ │ │ ├── 1f31d.png │ │ │ │ ├── 1f31e.png │ │ │ │ ├── 1f47d.png │ │ │ │ ├── 1f47f.png │ │ │ │ ├── 1f4a9.png │ │ │ │ ├── 1f608.png │ │ │ │ ├── 1f60d.png │ │ │ │ ├── 1f61c.png │ │ │ │ ├── 1f621.png │ │ │ │ ├── 1f62c.png │ │ │ │ ├── 1f62d.png │ │ │ │ ├── 1f62e.png │ │ │ │ ├── 1f631.png │ │ │ │ ├── 1f912.png │ │ │ │ ├── 1f913.png │ │ │ │ ├── 1f915.png │ │ │ │ ├── 1f922.png │ │ │ │ ├── 1f92a.png │ │ │ │ ├── 1f92c.png │ │ │ │ ├── 1f92e.png │ │ │ │ ├── 1f92f.png │ │ │ │ ├── 1f975.png │ │ │ │ └── 1f976.png │ │ ├── tilemaps │ │ │ ├── level.json │ │ │ └── level.tmx │ │ └── tilesets │ │ │ ├── kenney-tileset-64px-extruded.png │ │ │ └── kenney-tileset-64px.png │ ├── index.html │ ├── index.ts │ └── main-scene.ts │ ├── tsconfig.json │ └── webpack.config.js └── yarn.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | /.yarn/releases/** binary 2 | /.yarn/plugins/** binary -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | # Yarn (v2) without plug n' play 4 | .yarn/* 5 | !.yarn/patches 6 | !.yarn/releases 7 | !.yarn/plugins 8 | !.yarn/sdks 9 | !.yarn/versions 10 | .pnp.* -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "node", 6 | "request": "launch", 7 | "name": "Jest All", 8 | "program": "${workspaceFolder}/node_modules/.bin/jest", 9 | "args": ["--runInBand", "--config=./config/jest.config.js"], 10 | "console": "integratedTerminal", 11 | "internalConsoleOptions": "neverOpen", 12 | "windows": { 13 | "program": "${workspaceFolder}/node_modules/jest/bin/jest" 14 | } 15 | }, 16 | { 17 | "type": "node", 18 | "request": "launch", 19 | "name": "Jest Current File", 20 | "program": "${workspaceFolder}/node_modules/.bin/jest", 21 | "args": ["${relativeFile}", "--config=./config/jest.config.js"], 22 | "console": "integratedTerminal", 23 | "internalConsoleOptions": "neverOpen", 24 | "windows": { 25 | "program": "${workspaceFolder}/node_modules/jest/bin/jest" 26 | } 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | plugins: 4 | - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs 5 | spec: "@yarnpkg/plugin-workspace-tools" 6 | 7 | yarnPath: .yarn/releases/yarn-berry.cjs 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Michael Hadley 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 Matter Collision Plugin 💥 2 | 3 | A plugin for making it easier to manage collisions with the [Phaser](https://phaser.io/) game engine and the [Matter.js](http://brm.io/matter-js/) physics engine. 4 | 5 | Matter is one of the cool physics engine choices you have in Phaser 3. Phaser has a thin wrapper over Matter's API, so you need to dig into Matter's native collision event system if you want to detect and respond to collisions. That system just gives you a dump of all the pairs of bodies that collided in a tick of the engine. This plugin wraps up that collision logic in a more useful way: 6 | 7 | ```js 8 | const player = this.matter.add.sprite(0, 0, "player"); 9 | const trapDoor = this.matter.add.sprite(200, 0, "door"); 10 | 11 | this.matterCollision.addOnCollideStart({ 12 | objectA: player, 13 | objectB: trapDoor, 14 | callback: () => console.log("Player touched door!") 15 | }); 16 | ``` 17 | 18 | Or in a slightly more complicated example: 19 | 20 | [![](./doc-source-assets/collision-simple-demo.gif)](https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/master/doc-source-assets/collision-simple-demo.gif) 21 | _See interactive versions of that example on CodeSandbox in [JavaScript](https://codesandbox.io/s/0o0917m23l) or [TypeScript](https://codesandbox.io/s/my3oyyqj39)._ 22 | 23 | If you are reading this on Github or NPM, check out the full HTML documentation [here](https://mikewesthad.github.io/phaser-matter-collision-plugin/docs/). 24 | 25 | ## Info 26 | 27 | This repository uses yarn workspaces to keep the plugin source code together with some example JavaScript and TypeScript projects. See the individual workspaces for more info on each: 28 | 29 | - `workspaces/plugin` 30 | - `workspaces/javascript-example` 31 | - `workspaces/typescript-example` 32 | - `workspaces/javascript-no-module-example` 33 | 34 | If you are looking for the plugin readme, you can find it [here](https://github.com/mikewesthad/phaser-matter-collision-plugin/tree/master/workspaces/plugin). 35 | 36 | ## Development 37 | 38 | If you are contributing to this library, here is how to get started: 39 | 40 | - Install [Node](https://nodejs.org/en/). 41 | - `npm install --global yarn`. 42 | - Open the root folder of this repository and run `yarn` to install and link dependencies. 43 | - Head to the workspace you plan to work on and use `yarn run XYZ` to run a script from that workspace. -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phaser-matter-collision-plugin-root", 3 | "private": true, 4 | "workspaces": [ 5 | "workspaces/*" 6 | ], 7 | "scripts": { 8 | "start": "yarn workspaces foreach run start", 9 | "ws:plugin": "yarn workspace plugin", 10 | "ws:ts-example": "yarn workspace typescript-example", 11 | "prettier": "prettier --check \"workspaces/*/src/**/*.{js,ts}\"" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/mikewesthad/phaser-matter-collision-plugin.git" 16 | }, 17 | "keywords": [ 18 | "matter.js", 19 | "phaser", 20 | "collision detection", 21 | "game engine", 22 | "physics engine" 23 | ], 24 | "author": "Michael Hadley", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/mikewesthad/phaser-matter-collision-plugin/issues" 28 | }, 29 | "homepage": "https://github.com/mikewesthad/phaser-matter-collision-plugin#readme", 30 | "devDependencies": { 31 | "concurrently": "^6.2.0", 32 | "prettier": "^2.3.1" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /workspaces/javascript-example/README.md: -------------------------------------------------------------------------------- 1 | # JavaScript Example for using Phaser Matter Collision Plugin 2 | 3 | This is a JavaScript example project that makes use of the Phaser Matter Collision Plugin. It uses a webpack-based build system. 4 | 5 | Note: 6 | - If you are trying to copy this project and use it outside of this repository, you'll need to modify `package.json`. Yarn workspaces express dependencies like this `"phaser-matter-collision-plugin": "workspace:*"`, so you'll need to replace that with a version number. -------------------------------------------------------------------------------- /workspaces/javascript-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "javascript-example", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "start": "webpack server --mode development --open" 6 | }, 7 | "devDependencies": { 8 | "copy-webpack-plugin": "^9.0.1", 9 | "html-webpack-plugin": "^5.3.2", 10 | "webpack": "^5.49.0", 11 | "webpack-cli": "^4.7.2", 12 | "webpack-dev-server": "^3.11.2" 13 | }, 14 | "dependencies": { 15 | "phaser": "^3.55.2", 16 | "phaser-matter-collision-plugin": "workspace:*" 17 | } 18 | } -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji.json: -------------------------------------------------------------------------------- 1 | {"frames": { 2 | 3 | "1f4a9": 4 | { 5 | "frame": {"x":297,"y":1,"w":72,"h":72}, 6 | "rotated": false, 7 | "trimmed": false, 8 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 9 | "sourceSize": {"w":72,"h":72} 10 | }, 11 | "1f31a": 12 | { 13 | "frame": {"x":1,"y":1,"w":72,"h":72}, 14 | "rotated": false, 15 | "trimmed": false, 16 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 17 | "sourceSize": {"w":72,"h":72} 18 | }, 19 | "1f31d": 20 | { 21 | "frame": {"x":75,"y":1,"w":72,"h":72}, 22 | "rotated": false, 23 | "trimmed": false, 24 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 25 | "sourceSize": {"w":72,"h":72} 26 | }, 27 | "1f31e": 28 | { 29 | "frame": {"x":149,"y":1,"w":72,"h":72}, 30 | "rotated": false, 31 | "trimmed": false, 32 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 33 | "sourceSize": {"w":72,"h":72} 34 | }, 35 | "1f47d": 36 | { 37 | "frame": {"x":1628,"y":1,"w":70,"h":72}, 38 | "rotated": false, 39 | "trimmed": true, 40 | "spriteSourceSize": {"x":1,"y":0,"w":70,"h":72}, 41 | "sourceSize": {"w":72,"h":72} 42 | }, 43 | "1f47f": 44 | { 45 | "frame": {"x":223,"y":1,"w":72,"h":72}, 46 | "rotated": false, 47 | "trimmed": false, 48 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 49 | "sourceSize": {"w":72,"h":72} 50 | }, 51 | "1f60d": 52 | { 53 | "frame": {"x":445,"y":1,"w":72,"h":72}, 54 | "rotated": false, 55 | "trimmed": false, 56 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 57 | "sourceSize": {"w":72,"h":72} 58 | }, 59 | "1f61c": 60 | { 61 | "frame": {"x":519,"y":1,"w":72,"h":72}, 62 | "rotated": false, 63 | "trimmed": false, 64 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 65 | "sourceSize": {"w":72,"h":72} 66 | }, 67 | "1f62c": 68 | { 69 | "frame": {"x":667,"y":1,"w":72,"h":72}, 70 | "rotated": false, 71 | "trimmed": false, 72 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 73 | "sourceSize": {"w":72,"h":72} 74 | }, 75 | "1f62d": 76 | { 77 | "frame": {"x":741,"y":1,"w":72,"h":72}, 78 | "rotated": false, 79 | "trimmed": false, 80 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 81 | "sourceSize": {"w":72,"h":72} 82 | }, 83 | "1f62e": 84 | { 85 | "frame": {"x":815,"y":1,"w":72,"h":72}, 86 | "rotated": false, 87 | "trimmed": false, 88 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 89 | "sourceSize": {"w":72,"h":72} 90 | }, 91 | "1f92a": 92 | { 93 | "frame": {"x":1259,"y":1,"w":72,"h":72}, 94 | "rotated": false, 95 | "trimmed": false, 96 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 97 | "sourceSize": {"w":72,"h":72} 98 | }, 99 | "1f92c": 100 | { 101 | "frame": {"x":1333,"y":1,"w":72,"h":72}, 102 | "rotated": false, 103 | "trimmed": false, 104 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 105 | "sourceSize": {"w":72,"h":72} 106 | }, 107 | "1f92e": 108 | { 109 | "frame": {"x":1700,"y":1,"w":70,"h":72}, 110 | "rotated": false, 111 | "trimmed": true, 112 | "spriteSourceSize": {"x":1,"y":0,"w":70,"h":72}, 113 | "sourceSize": {"w":72,"h":72} 114 | }, 115 | "1f92f": 116 | { 117 | "frame": {"x":1555,"y":1,"w":71,"h":72}, 118 | "rotated": false, 119 | "trimmed": true, 120 | "spriteSourceSize": {"x":0,"y":0,"w":71,"h":72}, 121 | "sourceSize": {"w":72,"h":72} 122 | }, 123 | "1f608": 124 | { 125 | "frame": {"x":371,"y":1,"w":72,"h":72}, 126 | "rotated": false, 127 | "trimmed": false, 128 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 129 | "sourceSize": {"w":72,"h":72} 130 | }, 131 | "1f621": 132 | { 133 | "frame": {"x":593,"y":1,"w":72,"h":72}, 134 | "rotated": false, 135 | "trimmed": false, 136 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 137 | "sourceSize": {"w":72,"h":72} 138 | }, 139 | "1f631": 140 | { 141 | "frame": {"x":889,"y":1,"w":72,"h":72}, 142 | "rotated": false, 143 | "trimmed": false, 144 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 145 | "sourceSize": {"w":72,"h":72} 146 | }, 147 | "1f912": 148 | { 149 | "frame": {"x":963,"y":1,"w":72,"h":72}, 150 | "rotated": false, 151 | "trimmed": false, 152 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 153 | "sourceSize": {"w":72,"h":72} 154 | }, 155 | "1f913": 156 | { 157 | "frame": {"x":1037,"y":1,"w":72,"h":72}, 158 | "rotated": false, 159 | "trimmed": false, 160 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 161 | "sourceSize": {"w":72,"h":72} 162 | }, 163 | "1f915": 164 | { 165 | "frame": {"x":1111,"y":1,"w":72,"h":72}, 166 | "rotated": false, 167 | "trimmed": false, 168 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 169 | "sourceSize": {"w":72,"h":72} 170 | }, 171 | "1f922": 172 | { 173 | "frame": {"x":1185,"y":1,"w":72,"h":72}, 174 | "rotated": false, 175 | "trimmed": false, 176 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 177 | "sourceSize": {"w":72,"h":72} 178 | }, 179 | "1f975": 180 | { 181 | "frame": {"x":1407,"y":1,"w":72,"h":72}, 182 | "rotated": false, 183 | "trimmed": false, 184 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 185 | "sourceSize": {"w":72,"h":72} 186 | }, 187 | "1f976": 188 | { 189 | "frame": {"x":1481,"y":1,"w":72,"h":72}, 190 | "rotated": false, 191 | "trimmed": false, 192 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 193 | "sourceSize": {"w":72,"h":72} 194 | }}, 195 | "meta": { 196 | "app": "http://www.codeandweb.com/texturepacker", 197 | "version": "1.0", 198 | "image": "emoji.png", 199 | "format": "RGBA8888", 200 | "size": {"w":1771,"h":74}, 201 | "scale": "1", 202 | "smartupdate": "$TexturePacker:SmartUpdate:80919c52b607def3c7f647a71f5d2f19:8df71fe38bb708a3bec8b99fc4709ddb:3b6ee1b3efdb705ed941d972d580542a$" 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f31a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f31a.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f31d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f31d.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f31e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f31e.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f47d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f47d.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f47f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f47f.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f4a9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f4a9.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f608.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f608.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f60d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f60d.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f61c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f61c.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f621.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f621.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f62c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f62c.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f62d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f62d.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f62e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f62e.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f631.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f631.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f912.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f912.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f913.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f913.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f915.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f915.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f922.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f922.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f92a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f92a.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f92c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f92c.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f92e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f92e.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f92f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f92f.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f975.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f975.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/atlases/emoji/1f976.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/atlases/emoji/1f976.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/tilesets/kenney-tileset-64px-extruded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/tilesets/kenney-tileset-64px-extruded.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/assets/tilesets/kenney-tileset-64px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-example/src/assets/tilesets/kenney-tileset-64px.png -------------------------------------------------------------------------------- /workspaces/javascript-example/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Phaser Template 8 | 9 | 29 | 30 | 31 | 32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /workspaces/javascript-example/src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: Michael Hadley, mikewesthad.com 3 | * Asset Credits: 4 | * - Twemoji, https://github.com/twitter/twemoji, CC-BY 4.0 5 | * - Tilesets by Kenney, https://www.kenney.nl/assets/platformer-art-pixel-redux and 6 | * https://www.kenney.nl/assets/abstract-platformer, public domain 7 | */ 8 | 9 | import Phaser from "phaser"; 10 | import PhaserMatterCollisionPlugin from "phaser-matter-collision-plugin"; 11 | import MainScene from "./main-scene.js"; 12 | 13 | const config = { 14 | type: Phaser.AUTO, 15 | width: 800, 16 | height: 600, 17 | backgroundColor: "#000c1f", 18 | parent: "game-container", 19 | scene: MainScene, 20 | physics: { default: "matter" }, 21 | plugins: { 22 | scene: [ 23 | { 24 | plugin: PhaserMatterCollisionPlugin, // The plugin class 25 | key: "matterCollision", // Where to store in Scene.Systems, e.g. scene.sys.matterCollision 26 | mapping: "matterCollision", // Where to store in the Scene, e.g. scene.matterCollision 27 | }, 28 | ], 29 | }, 30 | }; 31 | 32 | const game = new Phaser.Game(config); 33 | -------------------------------------------------------------------------------- /workspaces/javascript-example/src/main-scene.js: -------------------------------------------------------------------------------- 1 | import Phaser from "phaser"; 2 | import PhaserMatterCollisionPlugin from "phaser-matter-collision-plugin"; 3 | 4 | export default class MainScene extends Phaser.Scene { 5 | /** 6 | * Only necessary if you want your code editor to know type information! 7 | * @type {PhaserMatterCollisionPlugin} 8 | */ 9 | matterCollision; 10 | 11 | preload() { 12 | this.load.tilemapTiledJSON("map", "../assets/tilemaps/level.json"); 13 | this.load.image( 14 | "kenney-tileset-64px-extruded", 15 | "../assets/tilesets/kenney-tileset-64px-extruded.png" 16 | ); 17 | this.load.atlas("emoji", "../assets/atlases/emoji.png", "../assets/atlases/emoji.json"); 18 | } 19 | 20 | create() { 21 | const map = this.make.tilemap({ key: "map" }); 22 | const tileset = map.addTilesetImage("kenney-tileset-64px-extruded"); 23 | const groundLayer = map.createLayer("Ground", tileset, 0, 0); 24 | const lavaLayer = map.createLayer("Lava", tileset, 0, 0); 25 | 26 | // Set colliding tiles before converting the layer to Matter bodies 27 | groundLayer.setCollisionByProperty({ collides: true }); 28 | lavaLayer.setCollisionByProperty({ collides: true }); 29 | this.matter.world.convertTilemapLayer(groundLayer); 30 | this.matter.world.convertTilemapLayer(lavaLayer); 31 | 32 | this.matter.world.setBounds(0, 0, map.widthInPixels, map.heightInPixels); 33 | this.cameras.main.setBounds(0, 0, map.widthInPixels, map.heightInPixels); 34 | 35 | // Create two simple animations - one angry => grimace emoji and one heart eyes => grimace 36 | this.anims.create({ 37 | key: "angry", 38 | frames: [ 39 | { key: "emoji", frame: "1f92c" }, 40 | { key: "emoji", frame: "1f62c" }, 41 | ], 42 | frameRate: 3, 43 | repeat: 0, 44 | }); 45 | this.anims.create({ 46 | key: "love", 47 | frames: [ 48 | { key: "emoji", frame: "1f60d" }, 49 | { key: "emoji", frame: "1f62c" }, 50 | ], 51 | frameRate: 3, 52 | repeat: 0, 53 | }); 54 | 55 | const bodyOptions = { restitution: 1, friction: 0, shape: "circle" }; 56 | const emoji1 = this.matter.add.sprite(350, 100, "emoji", "1f62c", bodyOptions); 57 | const emoji2 = this.matter.add.sprite(350, 275, "emoji", "1f62c", bodyOptions); 58 | const emoji3 = this.matter.add.sprite(350, 350, "emoji", "1f4a9", bodyOptions); 59 | 60 | // Only listen for collisions between emoji 1 & 2 - make them love-hate when they start 61 | // colliding or continue colliding 62 | this.matterCollision.addOnCollideStart({ 63 | objectA: emoji1, 64 | objectB: emoji2, 65 | callback: ({ gameObjectA, gameObjectB }) => { 66 | gameObjectA.play("angry", false); // gameObjectA will always match the given "objectA" 67 | gameObjectB.play("love", false); // gameObjectB will always match the given "objectB" 68 | }, 69 | }); 70 | this.matterCollision.addOnCollideActive({ 71 | objectA: emoji1, 72 | objectB: emoji2, 73 | callback: ({ gameObjectA, gameObjectB }) => { 74 | gameObjectA.play("angry", false); 75 | gameObjectB.play("love", false); 76 | }, 77 | }); 78 | 79 | // Kill poop emoji on collide with lava 80 | const unsubscribe = this.matterCollision.addOnCollideStart({ 81 | objectA: emoji3, 82 | callback: ({ gameObjectB }) => { 83 | if (!gameObjectB || !(gameObjectB instanceof Phaser.Tilemaps.Tile)) return; 84 | if (gameObjectB.index === 290) { 85 | emoji3.destroy(); 86 | unsubscribe(); 87 | } 88 | }, 89 | }); 90 | 91 | // Make the emoji draggable 92 | emoji1.setInteractive(); 93 | emoji2.setInteractive(); 94 | emoji3.setInteractive(); 95 | this.input.setDraggable(emoji1); 96 | this.input.setDraggable(emoji2); 97 | this.input.setDraggable(emoji3); 98 | this.input.on("drag", (pointer, gameObject, x, y) => gameObject.setPosition(x, y)); 99 | this.input.on("dragstart", (pointer, gameObject) => gameObject.setStatic(true)); 100 | this.input.on("dragend", (pointer, gameObject) => gameObject.setStatic(false)); 101 | 102 | const text = "Click and drag the emoji.\nArrow keys to move the camera."; 103 | const help = this.add.text(16, 16, text, { 104 | fontSize: "18px", 105 | padding: { x: 10, y: 5 }, 106 | backgroundColor: "#ffffff", 107 | fill: "#000000", 108 | }); 109 | help.setScrollFactor(0).setDepth(1000); 110 | 111 | const cursors = this.input.keyboard.createCursorKeys(); 112 | const controlConfig = { 113 | camera: this.cameras.main, 114 | left: cursors.left, 115 | right: cursors.right, 116 | up: cursors.up, 117 | down: cursors.down, 118 | speed: 0.5, 119 | }; 120 | this.controls = new Phaser.Cameras.Controls.FixedKeyControl(controlConfig); 121 | 122 | this.cameras.main.scrollX = 100; 123 | this.cameras.main.scrollY = 100; 124 | } 125 | 126 | update(time, delta) { 127 | this.controls.update(delta); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /workspaces/javascript-example/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | 3 | const webpack = require("webpack"); 4 | const path = require("path"); 5 | const root = path.resolve(__dirname); 6 | const HTMLWebpackPlugin = require("html-webpack-plugin"); 7 | const CopyWebpackPlugin = require("copy-webpack-plugin"); 8 | 9 | module.exports = function (env, argv) { 10 | const isDev = argv.mode === "development"; 11 | 12 | return { 13 | context: path.join(root, "src"), 14 | entry: "./index.js", 15 | output: { 16 | filename: "index.js", 17 | path: path.resolve(__dirname, "dist"), 18 | }, 19 | plugins: [ 20 | new HTMLWebpackPlugin({ template: "./index.html" }), 21 | new CopyWebpackPlugin({ 22 | patterns: [{ from: "assets", to: "assets" }], 23 | }), 24 | new webpack.DefinePlugin({ 25 | "typeof CANVAS_RENDERER": JSON.stringify(true), 26 | "typeof WEBGL_RENDERER": JSON.stringify(true), 27 | PRODUCTION: !isDev, 28 | }), 29 | ], 30 | devtool: isDev ? "eval-source-map" : "source-map", 31 | }; 32 | }; 33 | -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/README.md: -------------------------------------------------------------------------------- 1 | # JavaScript Example Without Modules for using Phaser Matter Collision Plugin 2 | 3 | This is a JavaScript example project that makes use of the Phaser Matter Collision Plugin. It does not use modules. It simply includes JS via scripts. It is harder to maintain a project this way, but it is common to encounter Phaser projects like this, so this example serves as a reference. 4 | 5 | If you use this as a template for a project, be sure to replace this line in `index.html`: 6 | 7 | ```html 8 | 9 | ``` 10 | 11 | To point to a copy of phaser-matter-collision that you downloaded, or that is hosted on jsdelivr. See the plugin documentation for more info. -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji.json: -------------------------------------------------------------------------------- 1 | {"frames": { 2 | 3 | "1f4a9": 4 | { 5 | "frame": {"x":297,"y":1,"w":72,"h":72}, 6 | "rotated": false, 7 | "trimmed": false, 8 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 9 | "sourceSize": {"w":72,"h":72} 10 | }, 11 | "1f31a": 12 | { 13 | "frame": {"x":1,"y":1,"w":72,"h":72}, 14 | "rotated": false, 15 | "trimmed": false, 16 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 17 | "sourceSize": {"w":72,"h":72} 18 | }, 19 | "1f31d": 20 | { 21 | "frame": {"x":75,"y":1,"w":72,"h":72}, 22 | "rotated": false, 23 | "trimmed": false, 24 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 25 | "sourceSize": {"w":72,"h":72} 26 | }, 27 | "1f31e": 28 | { 29 | "frame": {"x":149,"y":1,"w":72,"h":72}, 30 | "rotated": false, 31 | "trimmed": false, 32 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 33 | "sourceSize": {"w":72,"h":72} 34 | }, 35 | "1f47d": 36 | { 37 | "frame": {"x":1628,"y":1,"w":70,"h":72}, 38 | "rotated": false, 39 | "trimmed": true, 40 | "spriteSourceSize": {"x":1,"y":0,"w":70,"h":72}, 41 | "sourceSize": {"w":72,"h":72} 42 | }, 43 | "1f47f": 44 | { 45 | "frame": {"x":223,"y":1,"w":72,"h":72}, 46 | "rotated": false, 47 | "trimmed": false, 48 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 49 | "sourceSize": {"w":72,"h":72} 50 | }, 51 | "1f60d": 52 | { 53 | "frame": {"x":445,"y":1,"w":72,"h":72}, 54 | "rotated": false, 55 | "trimmed": false, 56 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 57 | "sourceSize": {"w":72,"h":72} 58 | }, 59 | "1f61c": 60 | { 61 | "frame": {"x":519,"y":1,"w":72,"h":72}, 62 | "rotated": false, 63 | "trimmed": false, 64 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 65 | "sourceSize": {"w":72,"h":72} 66 | }, 67 | "1f62c": 68 | { 69 | "frame": {"x":667,"y":1,"w":72,"h":72}, 70 | "rotated": false, 71 | "trimmed": false, 72 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 73 | "sourceSize": {"w":72,"h":72} 74 | }, 75 | "1f62d": 76 | { 77 | "frame": {"x":741,"y":1,"w":72,"h":72}, 78 | "rotated": false, 79 | "trimmed": false, 80 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 81 | "sourceSize": {"w":72,"h":72} 82 | }, 83 | "1f62e": 84 | { 85 | "frame": {"x":815,"y":1,"w":72,"h":72}, 86 | "rotated": false, 87 | "trimmed": false, 88 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 89 | "sourceSize": {"w":72,"h":72} 90 | }, 91 | "1f92a": 92 | { 93 | "frame": {"x":1259,"y":1,"w":72,"h":72}, 94 | "rotated": false, 95 | "trimmed": false, 96 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 97 | "sourceSize": {"w":72,"h":72} 98 | }, 99 | "1f92c": 100 | { 101 | "frame": {"x":1333,"y":1,"w":72,"h":72}, 102 | "rotated": false, 103 | "trimmed": false, 104 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 105 | "sourceSize": {"w":72,"h":72} 106 | }, 107 | "1f92e": 108 | { 109 | "frame": {"x":1700,"y":1,"w":70,"h":72}, 110 | "rotated": false, 111 | "trimmed": true, 112 | "spriteSourceSize": {"x":1,"y":0,"w":70,"h":72}, 113 | "sourceSize": {"w":72,"h":72} 114 | }, 115 | "1f92f": 116 | { 117 | "frame": {"x":1555,"y":1,"w":71,"h":72}, 118 | "rotated": false, 119 | "trimmed": true, 120 | "spriteSourceSize": {"x":0,"y":0,"w":71,"h":72}, 121 | "sourceSize": {"w":72,"h":72} 122 | }, 123 | "1f608": 124 | { 125 | "frame": {"x":371,"y":1,"w":72,"h":72}, 126 | "rotated": false, 127 | "trimmed": false, 128 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 129 | "sourceSize": {"w":72,"h":72} 130 | }, 131 | "1f621": 132 | { 133 | "frame": {"x":593,"y":1,"w":72,"h":72}, 134 | "rotated": false, 135 | "trimmed": false, 136 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 137 | "sourceSize": {"w":72,"h":72} 138 | }, 139 | "1f631": 140 | { 141 | "frame": {"x":889,"y":1,"w":72,"h":72}, 142 | "rotated": false, 143 | "trimmed": false, 144 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 145 | "sourceSize": {"w":72,"h":72} 146 | }, 147 | "1f912": 148 | { 149 | "frame": {"x":963,"y":1,"w":72,"h":72}, 150 | "rotated": false, 151 | "trimmed": false, 152 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 153 | "sourceSize": {"w":72,"h":72} 154 | }, 155 | "1f913": 156 | { 157 | "frame": {"x":1037,"y":1,"w":72,"h":72}, 158 | "rotated": false, 159 | "trimmed": false, 160 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 161 | "sourceSize": {"w":72,"h":72} 162 | }, 163 | "1f915": 164 | { 165 | "frame": {"x":1111,"y":1,"w":72,"h":72}, 166 | "rotated": false, 167 | "trimmed": false, 168 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 169 | "sourceSize": {"w":72,"h":72} 170 | }, 171 | "1f922": 172 | { 173 | "frame": {"x":1185,"y":1,"w":72,"h":72}, 174 | "rotated": false, 175 | "trimmed": false, 176 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 177 | "sourceSize": {"w":72,"h":72} 178 | }, 179 | "1f975": 180 | { 181 | "frame": {"x":1407,"y":1,"w":72,"h":72}, 182 | "rotated": false, 183 | "trimmed": false, 184 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 185 | "sourceSize": {"w":72,"h":72} 186 | }, 187 | "1f976": 188 | { 189 | "frame": {"x":1481,"y":1,"w":72,"h":72}, 190 | "rotated": false, 191 | "trimmed": false, 192 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 193 | "sourceSize": {"w":72,"h":72} 194 | }}, 195 | "meta": { 196 | "app": "http://www.codeandweb.com/texturepacker", 197 | "version": "1.0", 198 | "image": "emoji.png", 199 | "format": "RGBA8888", 200 | "size": {"w":1771,"h":74}, 201 | "scale": "1", 202 | "smartupdate": "$TexturePacker:SmartUpdate:80919c52b607def3c7f647a71f5d2f19:8df71fe38bb708a3bec8b99fc4709ddb:3b6ee1b3efdb705ed941d972d580542a$" 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f31a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f31a.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f31d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f31d.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f31e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f31e.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f47d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f47d.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f47f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f47f.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f4a9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f4a9.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f608.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f608.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f60d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f60d.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f61c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f61c.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f621.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f621.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f62c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f62c.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f62d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f62d.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f62e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f62e.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f631.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f631.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f912.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f912.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f913.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f913.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f915.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f915.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f922.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f922.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f92a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f92a.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f92c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f92c.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f92e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f92e.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f92f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f92f.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f975.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f975.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/atlases/emoji/1f976.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/atlases/emoji/1f976.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/tilesets/kenney-tileset-64px-extruded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/tilesets/kenney-tileset-64px-extruded.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/assets/tilesets/kenney-tileset-64px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/javascript-no-module-example/assets/tilesets/kenney-tileset-64px.png -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Phaser Template 8 | 9 | 29 | 30 | 31 | 32 |
33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /workspaces/javascript-no-module-example/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: Michael Hadley, mikewesthad.com 3 | * Asset Credits: 4 | * - Twemoji, https://github.com/twitter/twemoji, CC-BY 4.0 5 | * - Tilesets by Kenney, https://www.kenney.nl/assets/platformer-art-pixel-redux and 6 | * https://www.kenney.nl/assets/abstract-platformer, public domain 7 | */ 8 | class MainScene extends Phaser.Scene { 9 | /** 10 | * Only necessary if you want your code editor to know type information! 11 | * @type {PhaserMatterCollisionPlugin} 12 | */ 13 | matterCollision; 14 | 15 | preload() { 16 | this.load.tilemapTiledJSON("map", "./assets/tilemaps/level.json"); 17 | this.load.image( 18 | "kenney-tileset-64px-extruded", 19 | "./assets/tilesets/kenney-tileset-64px-extruded.png" 20 | ); 21 | this.load.atlas("emoji", "./assets/atlases/emoji.png", "./assets/atlases/emoji.json"); 22 | } 23 | 24 | create() { 25 | const map = this.make.tilemap({ key: "map" }); 26 | const tileset = map.addTilesetImage("kenney-tileset-64px-extruded"); 27 | const groundLayer = map.createLayer("Ground", tileset, 0, 0); 28 | const lavaLayer = map.createLayer("Lava", tileset, 0, 0); 29 | 30 | // Set colliding tiles before converting the layer to Matter bodies 31 | groundLayer.setCollisionByProperty({ collides: true }); 32 | lavaLayer.setCollisionByProperty({ collides: true }); 33 | this.matter.world.convertTilemapLayer(groundLayer); 34 | this.matter.world.convertTilemapLayer(lavaLayer); 35 | 36 | this.matter.world.setBounds(0, 0, map.widthInPixels, map.heightInPixels); 37 | this.cameras.main.setBounds(0, 0, map.widthInPixels, map.heightInPixels); 38 | 39 | // Create two simple animations - one angry => grimace emoji and one heart eyes => grimace 40 | this.anims.create({ 41 | key: "angry", 42 | frames: [ 43 | { key: "emoji", frame: "1f92c" }, 44 | { key: "emoji", frame: "1f62c" }, 45 | ], 46 | frameRate: 3, 47 | repeat: 0, 48 | }); 49 | this.anims.create({ 50 | key: "love", 51 | frames: [ 52 | { key: "emoji", frame: "1f60d" }, 53 | { key: "emoji", frame: "1f62c" }, 54 | ], 55 | frameRate: 3, 56 | repeat: 0, 57 | }); 58 | 59 | const bodyOptions = { restitution: 1, friction: 0, shape: "circle" }; 60 | const emoji1 = this.matter.add.sprite(350, 100, "emoji", "1f62c", bodyOptions); 61 | const emoji2 = this.matter.add.sprite(350, 275, "emoji", "1f62c", bodyOptions); 62 | const emoji3 = this.matter.add.sprite(350, 350, "emoji", "1f4a9", bodyOptions); 63 | 64 | // Only listen for collisions between emoji 1 & 2 - make them love-hate when they start 65 | // colliding or continue colliding 66 | this.matterCollision.addOnCollideStart({ 67 | objectA: emoji1, 68 | objectB: emoji2, 69 | callback: ({ gameObjectA, gameObjectB }) => { 70 | gameObjectA.play("angry", false); // gameObjectA will always match the given "objectA" 71 | gameObjectB.play("love", false); // gameObjectB will always match the given "objectB" 72 | }, 73 | }); 74 | this.matterCollision.addOnCollideActive({ 75 | objectA: emoji1, 76 | objectB: emoji2, 77 | callback: ({ gameObjectA, gameObjectB }) => { 78 | gameObjectA.play("angry", false); 79 | gameObjectB.play("love", false); 80 | }, 81 | }); 82 | 83 | // Kill poop emoji on collide with lava 84 | const unsubscribe = this.matterCollision.addOnCollideStart({ 85 | objectA: emoji3, 86 | callback: ({ gameObjectB }) => { 87 | if (!gameObjectB || !(gameObjectB instanceof Phaser.Tilemaps.Tile)) return; 88 | if (gameObjectB.index === 290) { 89 | emoji3.destroy(); 90 | unsubscribe(); 91 | } 92 | }, 93 | }); 94 | 95 | // Make the emoji draggable 96 | emoji1.setInteractive(); 97 | emoji2.setInteractive(); 98 | emoji3.setInteractive(); 99 | this.input.setDraggable(emoji1); 100 | this.input.setDraggable(emoji2); 101 | this.input.setDraggable(emoji3); 102 | this.input.on("drag", (pointer, gameObject, x, y) => gameObject.setPosition(x, y)); 103 | this.input.on("dragstart", (pointer, gameObject) => gameObject.setStatic(true)); 104 | this.input.on("dragend", (pointer, gameObject) => gameObject.setStatic(false)); 105 | 106 | const text = "Click and drag the emoji.\nArrow keys to move the camera."; 107 | const help = this.add.text(16, 16, text, { 108 | fontSize: "18px", 109 | padding: { x: 10, y: 5 }, 110 | backgroundColor: "#ffffff", 111 | fill: "#000000", 112 | }); 113 | help.setScrollFactor(0).setDepth(1000); 114 | 115 | const cursors = this.input.keyboard.createCursorKeys(); 116 | const controlConfig = { 117 | camera: this.cameras.main, 118 | left: cursors.left, 119 | right: cursors.right, 120 | up: cursors.up, 121 | down: cursors.down, 122 | speed: 0.5, 123 | }; 124 | this.controls = new Phaser.Cameras.Controls.FixedKeyControl(controlConfig); 125 | 126 | this.cameras.main.scrollX = 100; 127 | this.cameras.main.scrollY = 100; 128 | } 129 | 130 | update(time, delta) { 131 | this.controls.update(delta); 132 | } 133 | } 134 | 135 | const config = { 136 | type: Phaser.AUTO, 137 | width: 800, 138 | height: 600, 139 | backgroundColor: "#000c1f", 140 | parent: "game-container", 141 | scene: MainScene, 142 | physics: { default: "matter" }, 143 | plugins: { 144 | scene: [ 145 | { 146 | plugin: PhaserMatterCollisionPlugin.default, // The plugin class 147 | key: "matterCollision", // Where to store in Scene.Systems, e.g. scene.sys.matterCollision 148 | mapping: "matterCollision", // Where to store in the Scene, e.g. scene.matterCollision 149 | }, 150 | ], 151 | }, 152 | }; 153 | 154 | const game = new Phaser.Game(config); 155 | -------------------------------------------------------------------------------- /workspaces/plugin/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "browsers": ["last 2 versions"] 8 | }, 9 | "modules": false 10 | } 11 | ] 12 | ], 13 | "env": { 14 | "test": { 15 | "presets": ["@babel/preset-env"] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /workspaces/plugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | docs 3 | cypress/screenshots 4 | cypress/videos 5 | tests/*/build 6 | 7 | # Ignore files used for publishing to gh-pages 8 | .publish 9 | -------------------------------------------------------------------------------- /workspaces/plugin/cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "chromeWebSecurity": false, 3 | "fileServerFolder": ".", 4 | "viewportHeight": 800, 5 | "viewportWidth": 1200, 6 | "defaultCommandTimeout": 10000, 7 | "fixturesFolder": false 8 | } 9 | -------------------------------------------------------------------------------- /workspaces/plugin/cypress/integration/collision-events.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | const testName = "collision-events"; 4 | 5 | context(`Run ${testName}`, () => { 6 | it("should run with no errors", () => { 7 | cy.runPhaserTest(`/tests/${testName}`); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /workspaces/plugin/cypress/integration/gameobject-collide-gameobject.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | const testName = "gameobject-collide-gameobject"; 4 | 5 | context(`Run ${testName}`, () => { 6 | it("should run with no errors", () => { 7 | cy.runPhaserTest(`/tests/${testName}`); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /workspaces/plugin/cypress/integration/gameobject-collide-tiles.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | const testName = "gameobject-collide-tiles"; 4 | 5 | context(`Run ${testName}`, () => { 6 | it("should run with no errors", () => { 7 | cy.runPhaserTest(`/tests/${testName}`); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /workspaces/plugin/cypress/integration/pair-collision-events.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | const testName = "pair-collision-events"; 4 | 5 | context(`Run ${testName}`, () => { 6 | it("should run with no errors", () => { 7 | cy.runPhaserTest(`/tests/${testName}`); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /workspaces/plugin/cypress/plugins/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example plugins/index.js can be used to load plugins 3 | // 4 | // You can change the location of this file or turn off loading 5 | // the plugins file with the 'pluginsFile' configuration option. 6 | // 7 | // You can read more here: 8 | // https://on.cypress.io/plugins-guide 9 | // *********************************************************** 10 | 11 | // This function is called when a project is opened or re-opened (e.g. due to 12 | // the project's config changing) 13 | 14 | module.exports = (on, config) => { 15 | // `on` is used to hook into various events Cypress emits 16 | // `config` is the resolved Cypress config 17 | }; 18 | -------------------------------------------------------------------------------- /workspaces/plugin/cypress/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | 11 | Cypress.Commands.add("runPhaserTest", (path) => { 12 | cy.visit(path); 13 | cy.get(".test-pass").should("be.visible"); 14 | }); 15 | -------------------------------------------------------------------------------- /workspaces/plugin/cypress/support/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | import "./commands"; 17 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-source-assets/collision-plugin-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/doc-source-assets/collision-plugin-demo.gif -------------------------------------------------------------------------------- /workspaces/plugin/doc-source-assets/collision-simple-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/doc-source-assets/collision-simple-demo.gif -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/doc-theme/assets/images/icons.png -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/doc-theme/assets/images/icons@2x.png -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/doc-theme/assets/images/widgets.png -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/doc-theme/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/layouts/default.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{#ifCond model.name '==' project.name}}{{project.name}}{{else}}{{model.name}} | {{project.name}}{{/ifCond}} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {{> header}} 16 | 17 |
18 |
19 |
20 | {{{contents}}} 21 |
22 | 39 |
40 |
41 | 42 | {{> footer}} 43 | 44 |
45 | 46 | 47 | {{> analytics}} 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/analytics.hbs: -------------------------------------------------------------------------------- 1 | {{#if settings.gaID}} 2 | 11 | {{/if}} -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/breadcrumb.hbs: -------------------------------------------------------------------------------- 1 | {{#if parent}} 2 | {{#with parent}}{{> breadcrumb}}{{/with}} 3 |
  • 4 | {{#if url}} 5 | {{name}} 6 | {{else}} 7 | {{name}} 8 | {{/if}} 9 |
  • 10 | {{else}} 11 | {{#if url}} 12 |
  • 13 | {{ name }} 14 |
  • 15 | {{/if}} 16 | {{/if}} 17 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/comment.hbs: -------------------------------------------------------------------------------- 1 | {{#with comment}} 2 | {{#if hasVisibleComponent}} 3 |
    4 | {{#if shortText}} 5 |
    6 | {{#markdown}}{{{shortText}}}{{/markdown}} 7 |
    8 | {{/if}} 9 | {{#if text}} 10 | {{#markdown}}{{{text}}}{{/markdown}} 11 | {{/if}} 12 | {{#if tags}} 13 |
    14 | {{#each tags}} 15 |
    {{tagName}}
    16 |
    {{#markdown}}{{{text}}}{{/markdown}}
    17 | {{/each}} 18 |
    19 | {{/if}} 20 |
    21 | {{/if}} 22 | {{/with}} -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/footer.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 |
    4 |

    Legend

    5 |
    6 | {{#each legend}} 7 |
      8 | {{#each .}} 9 |
    • {{name}}
    • 10 | {{/each}} 11 |
    12 | {{/each}} 13 |
    14 |
    15 | 16 | 17 | {{#unless settings.hideGenerator}} 18 |
    19 |

    Generated using TypeDoc

    20 |
    21 | {{/unless}} -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/header.hbs: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 | 18 | 19 |
    20 |
    21 | Options 22 |
    23 |
    24 | All 25 |
      26 |
    • Public
    • 27 |
    • Public/Protected
    • 28 |
    • All
    • 29 |
    30 |
    31 | 32 | 33 | 34 | 35 | {{#unless settings.excludeExternals}} 36 | 37 | 38 | {{/unless}} 39 |
    40 |
    41 | 42 | Menu 43 |
    44 |
    45 |
    46 |
    47 |
    48 |
    49 | {{#if model.parent}} {{! Don't show breadcrumbs on main project page, it is the root page. !}} 50 |
      51 | {{#with model}}{{> breadcrumb}}{{/with}} 52 |
    53 | {{/if}} 54 |

    {{#compact}} 55 | {{#ifCond model.kindString "!==" "Project" }} 56 | {{model.kindString}}  57 | {{/ifCond}} 58 | {{model.name}} 59 | {{#if model.typeParameters}} 60 | < 61 | {{#each model.typeParameters}} 62 | {{#if @index}}, {{/if}} 63 | {{name}} 64 | {{/each}} 65 | > 66 | {{/if}} 67 | {{/compact}}

    68 |
    69 |
    70 |
    71 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/hierarchy.hbs: -------------------------------------------------------------------------------- 1 |
      2 | {{#each types}} 3 |
    • 4 | {{#if ../isTarget}} 5 | {{this}} 6 | {{else}} 7 | {{#compact}}{{> type}}{{/compact}} 8 | {{/if}} 9 | 10 | {{#if @last}} 11 | {{#with ../next}} 12 | {{> hierarchy}} 13 | {{/with}} 14 | {{/if}} 15 |
    • 16 | {{/each}} 17 |
    18 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/index.hbs: -------------------------------------------------------------------------------- 1 | {{#if categories}} 2 |
    3 |

    Index

    4 |
    5 |
    6 | {{#each categories}} 7 |
    8 |

    {{title}}

    9 | 14 |
    15 | {{/each}} 16 |
    17 |
    18 |
    19 | {{else}} 20 | {{#if groups}} 21 |
    22 |

    Index

    23 |
    24 |
    25 | {{#each groups}} 26 |
    27 | {{#if categories}} 28 | {{#each categories}} 29 |

    {{#if title}}{{title}} {{/if}}{{../title}}

    30 | 35 | {{/each}} 36 | {{else}} 37 |

    {{title}}

    38 | 43 | {{/if}} 44 |
    45 | {{/each}} 46 |
    47 |
    48 |
    49 | {{/if}} 50 | {{/if}} 51 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/member.declaration.hbs: -------------------------------------------------------------------------------- 1 |
    {{#compact}} 2 | {{{wbr name}}} 3 | {{#if typeParameters}} 4 | < 5 | {{#each typeParameters}} 6 | {{#if @index}}, {{/if}} 7 | {{name}} 8 | {{/each}} 9 | > 10 | {{/if}} 11 | {{#if isOptional}}?{{/if}}: {{#with type}}{{>type}}{{/with}} 12 | {{#if defaultValue}} 13 | 14 |  =  15 | {{defaultValue}} 16 | 17 | {{/if}} 18 | {{/compact}}
    19 | 20 | {{> member.sources}} 21 | 22 | {{> comment}} 23 | 24 | {{#if typeParameters}} 25 |

    Type parameters

    26 | {{> typeParameters}} 27 | {{/if}} 28 | 29 | {{#if type.declaration}} 30 |
    31 |

    Type declaration

    32 | {{#with type.declaration}} 33 | {{> parameter}} 34 | {{/with}} 35 |
    36 | {{/if}} 37 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/member.getterSetter.hbs: -------------------------------------------------------------------------------- 1 |
      2 | {{#if getSignature}} 3 | {{#with getSignature}} 4 |
    • {{#compact}} 5 | get  6 | {{../name}} 7 | {{> member.signature.title hideName=true }} 8 | {{/compact}}
    • 9 | {{/with}} 10 | {{/if}} 11 | {{#if setSignature}} 12 | {{#with setSignature}} 13 |
    • {{#compact}} 14 | set  15 | {{../name}} 16 | {{> member.signature.title hideName=true }} 17 | {{/compact}}
    • 18 | {{/with}} 19 | {{/if}} 20 |
    21 | 22 |
      23 | {{#if getSignature}} 24 | {{#with getSignature}} 25 |
    • 26 | {{> member.signature.body }} 27 |
    • 28 | {{/with}} 29 | {{/if}} 30 | {{#if setSignature}} 31 | {{#with setSignature}} 32 |
    • 33 | {{> member.signature.body }} 34 |
    • 35 | {{/with}} 36 | {{/if}} 37 |
    38 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/member.hbs: -------------------------------------------------------------------------------- 1 |
    2 | 3 | {{#if name}} 4 |

    {{#each flags}}{{this}} {{/each}}{{{wbr name}}}

    5 | {{/if}} 6 | 7 | {{#if signatures}} 8 | {{> member.signatures}} 9 | {{else}}{{#if hasGetterOrSetter}} 10 | {{> member.getterSetter}} 11 | {{else}}{{#if isReference}} 12 | {{> member.reference}} 13 | {{else}} 14 | {{> member.declaration}} 15 | {{/if}}{{/if}}{{/if}} 16 | 17 | {{#each groups}} 18 | {{#each children}} 19 | {{#unless hasOwnDocument}} 20 | {{> member}} 21 | {{/unless}} 22 | {{/each}} 23 | {{/each}} 24 |
    25 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/member.reference.hbs: -------------------------------------------------------------------------------- 1 | {{#with tryGetTargetReflectionDeep}} 2 | {{#ifCond ../name '===' name}} 3 | Re-exports {{name}} 4 | {{else if flags.isExported}} 5 | Renames and re-exports {{name}} 6 | {{else}} 7 | Renames and exports {{name}} 8 | {{/ifCond}} 9 | {{else}} 10 | Re-exports {{name}} 11 | {{/with}} 12 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/member.signature.body.hbs: -------------------------------------------------------------------------------- 1 | {{#unless hideSources}} 2 | {{> member.sources}} 3 | {{/unless}} 4 | 5 | {{> comment}} 6 | 7 | {{#if typeParameters}} 8 |

    Type parameters

    9 | {{> typeParameters}} 10 | {{/if}} 11 | 12 | {{#if parameters}} 13 |

    Parameters

    14 |
      15 | {{#each parameters}} 16 |
    • 17 |
      {{#compact}} 18 | {{#each flags}} 19 | {{this}}  20 | {{/each}} 21 | {{#if flags.isRest}}...{{/if}} 22 | {{name}}:  23 | {{#with type}}{{>type}}{{/with}} 24 | {{#if defaultValue}} 25 | 26 |  =  27 | {{defaultValue}} 28 | 29 | {{/if}} 30 | {{/compact}}
      31 | 32 | {{> comment}} 33 | 34 | {{#if type.declaration}} 35 | {{#with type.declaration}} 36 | {{> parameter}} 37 | {{/with}} 38 | {{/if}} 39 |
    • 40 | {{/each}} 41 |
    42 | {{/if}} 43 | 44 | {{#if type}} 45 |

    Returns {{#compact}}{{#with type}}{{>type}}{{/with}}{{/compact}}

    46 | 47 | {{#if comment.returns}} 48 | {{#markdown}}{{{comment.returns}}}{{/markdown}} 49 | {{/if}} 50 | 51 | {{#if type.declaration}} 52 | {{#with type.declaration}} 53 | {{> parameter}} 54 | {{/with}} 55 | {{/if}} 56 | {{/if}} 57 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/member.signature.title.hbs: -------------------------------------------------------------------------------- 1 | {{#unless hideName}} 2 | {{{wbr name}}} 3 | {{else}} {{! This ugliness goes away when we stop naming constructor signatures "new X"}} 4 | {{#ifCond kindString "===" "Constructor signature"}} 5 | {{#if flags.isAbstract}} 6 | abstract 7 | {{/if}} 8 | new 9 | {{/ifCond}} 10 | {{/unless}} 11 | {{#if typeParameters}} 12 | < 13 | {{#each typeParameters}} 14 | {{#if @index}}, {{/if}} 15 | {{name}} 16 | {{/each}} 17 | > 18 | {{/if}} 19 | ( 20 | {{#each parameters}} 21 | {{#if @index}}, {{/if}} 22 | {{#if flags.isRest}}...{{/if}} 23 | {{name}} 24 | 25 | {{#if flags.isOptional}}?{{/if}} 26 | {{#if defaultValue}}?{{/if}} 27 | :  28 | 29 | {{#with type}}{{>type}}{{/with}} 30 | {{/each}} 31 | ) 32 | {{#if type}} 33 | {{#if arrowStyle}} 34 | => 35 | {{else}} 36 | : 37 | {{/if}} 38 | {{#with type}} 39 | {{>type}} 40 | {{/with}} 41 | {{/if}} 42 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/member.signatures.hbs: -------------------------------------------------------------------------------- 1 |
      2 | {{#each signatures}} 3 |
    • {{#compact}}{{> member.signature.title }}{{/compact}}
    • 4 | {{/each}} 5 |
    6 | 7 |
      8 | {{#each signatures}} 9 |
    • 10 | {{> member.signature.body }} 11 |
    • 12 | {{/each}} 13 |
    14 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/member.sources.hbs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/members.group.hbs: -------------------------------------------------------------------------------- 1 | {{#if categories}} 2 | {{#each categories}} 3 |
    4 |

    {{#if title}}{{title}} {{/if}}{{../title}}

    5 | {{#each children}} 6 | {{#unless hasOwnDocument}} 7 | {{> member}} 8 | {{/unless}} 9 | {{/each}} 10 |
    11 | {{/each}} 12 | {{else}} 13 |
    14 |

    {{title}}

    15 | {{#each children}} 16 | {{#unless hasOwnDocument}} 17 | {{> member}} 18 | {{/unless}} 19 | {{/each}} 20 |
    21 | {{/if}} -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/members.hbs: -------------------------------------------------------------------------------- 1 | {{#if categories}} 2 | {{#each categories}} 3 | {{#unless allChildrenHaveOwnDocument}} 4 |
    5 |

    {{title}}

    6 | {{#each children}} 7 | {{#unless hasOwnDocument}} 8 | {{> member}} 9 | {{/unless}} 10 | {{/each}} 11 |
    12 | {{/unless}} 13 | {{/each}} 14 | {{else}} 15 | {{#each groups}} 16 | {{#unless allChildrenHaveOwnDocument}} 17 | {{> members.group}} 18 | {{/unless}} 19 | {{/each}} 20 | {{/if}} -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/navigation.hbs: -------------------------------------------------------------------------------- 1 | {{#if isVisible}} 2 | {{#if isLabel}} 3 |
  • 4 | {{{wbr title}}} 5 |
  • 6 | {{else}} 7 | {{#if isGlobals}} 8 |
  • 9 | {{{wbr title}}} 10 |
  • 11 | {{else}} 12 |
  • 13 | {{{wbr title}}} 14 | {{#if isInPath}} 15 | {{#if children}} 16 |
      17 | {{#each children}} 18 | {{> navigation}} 19 | {{/each}} 20 |
    21 | {{/if}} 22 | {{/if}} 23 |
  • 24 | {{/if}} 25 | {{/if}} 26 | {{/if}} 27 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/parameter.hbs: -------------------------------------------------------------------------------- 1 |
      2 | {{#if signatures}} 3 |
    • 4 |
        5 | {{#each signatures}} 6 |
      • {{#compact}} 7 | {{> member.signature.title hideName=true }} 8 | {{/compact}}
      • 9 | {{/each}} 10 |
      11 | 12 |
        13 | {{#each signatures}} 14 |
      • {{> member.signature.body hideSources=true }}
      • 15 | {{/each}} 16 |
      17 |
    • 18 | {{/if}} 19 | {{#if indexSignature}} 20 |
    • 21 |
      {{#compact}} 22 | [ 23 | {{#each indexSignature.parameters}} 24 | {{#if flags.isRest}}...{{/if}}{{name}}: {{#with type}}{{>type}}{{/with}} 25 | {{/each}} 26 | ]:  27 | {{#with indexSignature.type}}{{>type}}{{/with}} 28 | {{/compact}}
      29 | 30 | {{#with indexSignature}} 31 | {{> comment}} 32 | {{/with}} 33 | 34 | {{#if indexSignature.type.declaration}} 35 | {{#with indexSignature.type.declaration}} 36 | {{> parameter}} 37 | {{/with}} 38 | {{/if}} 39 |
    • 40 | {{/if}} 41 | {{#each children}} 42 | {{#if signatures}} 43 |
    • 44 |
      {{#compact}} 45 | {{#if flags.isRest}}...{{/if}} 46 | {{{wbr name}}} 47 | 48 | {{#if isOptional}}?{{/if}} 49 | :  50 | 51 | function 52 | {{/compact}}
      53 | 54 | {{> member.signatures}} 55 |
    • 56 | {{else}}{{#if type}} {{! standard type }} 57 |
    • 58 |
      {{#compact}} 59 | {{#each flags}} 60 | {{this}}  61 | {{/each}} 62 | {{#if flags.isRest}}...{{/if}} 63 | {{#with type}} 64 | {{{wbr ../name}}} 65 | 66 | {{#if ../flags.isOptional}}?{{/if}} 67 | :  68 | 69 | {{>type}} 70 | {{/with}} 71 | {{/compact}}
      72 | 73 | {{> comment}} 74 | 75 | {{#if children}} 76 | {{> parameter}} 77 | {{/if}} 78 | 79 | {{#if type.declaration}} 80 | {{#with type.declaration}} 81 | {{> parameter}} 82 | {{/with}} 83 | {{/if}} 84 |
    • 85 | {{else}} {{! getter/setter }} 86 | {{#with getSignature}} {{! getter }} 87 |
    • 88 |
      {{#compact}} 89 | {{#each flags}} 90 | {{this}}  91 | {{/each}} 92 | get  93 | {{{wbr ../name}}} 94 | ():  95 | {{#with type}} 96 | {{> type}} 97 | {{/with}} 98 | {{/compact}}
      99 | 100 | {{> comment }} 101 |
    • 102 | {{/with}} 103 | {{#with setSignature}} {{! setter }} 104 |
    • 105 |
      {{#compact}} 106 | {{#each flags}} 107 | {{this}}  108 | {{/each}} 109 | set  110 | {{{wbr ../name}}} 111 | ( 112 | {{#each parameters}} 113 | {{name}} 114 | : 115 | {{#with type}} 116 | {{> type}} 117 | {{else}} 118 | any 119 | {{/with}} 120 | {{/each}} 121 | ):  122 | {{#with type}} 123 | {{> type}} 124 | {{/with}} 125 | {{/compact}}
      126 | 127 | {{> comment }} 128 |
    • 129 | {{/with}} 130 | {{/if}}{{/if}} 131 | {{/each}} 132 |
    133 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/toc.hbs: -------------------------------------------------------------------------------- 1 |
  • 2 | {{{wbr title}}} 3 | {{#if children}} 4 |
      5 | {{#each children}} 6 | {{> toc}} 7 | {{/each}} 8 |
    9 | {{/if}} 10 |
  • 11 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/toc.root.hbs: -------------------------------------------------------------------------------- 1 | {{#if isInPath}} 2 | 3 |
      4 | {{/if}} 5 |
    • 6 | {{{wbr title}}} 7 | {{#if children}} 8 |
        9 | {{#each children}} 10 | {{> toc}} 11 | {{/each}} 12 |
      13 | {{/if}} 14 |
    • 15 | {{#if isInPath}} 16 |
    17 |
      18 | {{/if}} 19 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/typeAndParent.hbs: -------------------------------------------------------------------------------- 1 | {{#compact}} 2 | {{#if this}} 3 | {{#if elementType}} 4 | {{#with elementType}} 5 | {{> typeAndParent}} 6 | {{/with}} 7 | [] 8 | {{else}} 9 | {{#if reflection}} 10 | {{#ifSignature reflection}} 11 | {{#if reflection.parent.parent.url}} 12 | {{reflection.parent.parent.name}} 13 | {{else}} 14 | {{reflection.parent.parent.name}} 15 | {{/if}} 16 | . 17 | {{#if reflection.parent.url}} 18 | {{reflection.parent.name}} 19 | {{else}} 20 | {{reflection.parent.name}} 21 | {{/if}} 22 | {{else}} 23 | {{#if reflection.parent.url}} 24 | {{reflection.parent.name}} 25 | {{else}} 26 | {{reflection.parent.name}} 27 | {{/if}} 28 | . 29 | {{#if reflection.url}} 30 | {{reflection.name}} 31 | {{else}} 32 | {{reflection.name}} 33 | {{/if}} 34 | {{/ifSignature}} 35 | {{else}} 36 | {{this}} 37 | {{/if}} 38 | {{/if}} 39 | {{else}} 40 | void 41 | {{/if}} 42 | {{/compact}} -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/partials/typeParameters.hbs: -------------------------------------------------------------------------------- 1 |
        2 | {{#each typeParameters}} 3 |
      • 4 |

        {{#compact}} 5 | {{name}} 6 | {{#if type}} 7 | 8 | {{#with type}}{{> type}}{{/with}} 9 | {{/if}} 10 | {{#if default}} 11 |  = {{#with default}}{{> type}}{{/with}} 12 | {{/if}} 13 | {{/compact}}

        14 | {{> comment}} 15 |
      • 16 | {{/each}} 17 |
      18 | -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/templates/index.hbs: -------------------------------------------------------------------------------- 1 |
      2 | {{#markdown}}{{{model.readme}}}{{/markdown}} 3 |
      -------------------------------------------------------------------------------- /workspaces/plugin/doc-theme/templates/reflection.hbs: -------------------------------------------------------------------------------- 1 | {{#with model}} 2 | {{#if hasComment}} 3 |
      4 | {{> comment}} 5 |
      6 | {{/if}} 7 | {{/with}} 8 | 9 | {{#if model.typeParameters}} 10 |
      11 |

      Type parameters

      12 | {{#with model}}{{> typeParameters}}{{/with}} 13 |
      14 | {{/if}} 15 | 16 | {{#if model.typeHierarchy}} 17 |
      18 |

      Hierarchy

      19 | {{#with model.typeHierarchy}}{{> hierarchy}}{{/with}} 20 |
      21 | {{/if}} 22 | 23 | {{#if model.implementedTypes}} 24 |
      25 |

      Implements

      26 |
        27 | {{#each model.implementedTypes}} 28 |
      • {{#compact}}{{> type}}{{/compact}}
      • 29 | {{/each}} 30 |
      31 |
      32 | {{/if}} 33 | 34 | {{#if model.implementedBy}} 35 |
      36 |

      Implemented by

      37 |
        38 | {{#each model.implementedBy}} 39 |
      • {{#compact}}{{> type}}{{/compact}}
      • 40 | {{/each}} 41 |
      42 |
      43 | {{/if}} 44 | 45 | {{#if model.signatures}} 46 |
      47 |

      Callable

      48 | {{#with model}}{{> member.signatures}}{{/with}} 49 |
      50 | {{/if}} 51 | 52 | {{#if model.indexSignature}} 53 |
      54 |

      Indexable

      55 |
      {{#compact}} 56 | [ 57 | {{#each model.indexSignature.parameters}} 58 | {{name}}: {{#with type}}{{>type}}{{/with}} 59 | {{/each}} 60 | ]:  61 | {{#with model.indexSignature.type}}{{>type}}{{/with}} 62 | {{/compact}}
      63 | 64 | {{#with model.indexSignature}} 65 | {{> comment}} 66 | {{/with}} 67 | 68 | {{#if model.indexSignature.type.declaration}} 69 | {{#with model.indexSignature.type.declaration}} 70 | {{> parameter}} 71 | {{/with}} 72 | {{/if}} 73 |
      74 | {{/if}} 75 | 76 | {{#with model}} 77 | {{> index}} 78 | {{> members}} 79 | {{/with}} 80 | -------------------------------------------------------------------------------- /workspaces/plugin/eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["eslint:recommended", "prettier"], 3 | plugins: ["prettier"], 4 | rules: { 5 | "no-var": 1, 6 | "brace-style": ["warn", "1tbs"], 7 | "no-unused-vars": ["error", { args: "after-used" }], 8 | indent: ["warn", 2, { SwitchCase: 1 }], 9 | "max-len": ["warn", 100, { ignoreUrls: true, ignoreTemplateLiterals: true }], 10 | "no-console": "off" 11 | }, 12 | env: { 13 | browser: true, 14 | commonjs: true, 15 | es6: true 16 | }, 17 | parserOptions: { 18 | sourceType: "module" 19 | }, 20 | overrides: [ 21 | { 22 | files: ["**/*test.js"], 23 | env: { 24 | jest: true 25 | } 26 | } 27 | ] 28 | }; 29 | -------------------------------------------------------------------------------- /workspaces/plugin/jest.config.js: -------------------------------------------------------------------------------- 1 | // For a detailed explanation regarding each configuration property, visit: 2 | // https://jestjs.io/docs/en/configuration.html 3 | 4 | module.exports = { 5 | preset: "ts-jest", 6 | transform: { 7 | ".(js|ts|tsx)": "ts-jest", 8 | }, 9 | testRegex: "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$", 10 | moduleFileExtensions: ["ts", "tsx", "js"], 11 | 12 | // All imported modules in your tests should be mocked automatically 13 | automock: false, 14 | 15 | // Stop running tests after the first failure 16 | // bail: false, 17 | 18 | // Respect "browser" field in package.json when resolving modules 19 | // browser: false, 20 | 21 | // The directory where Jest should store its cached dependency information 22 | // cacheDirectory: "C:\\Users\\MIKEWE~1\\AppData\\Local\\Temp\\jest", 23 | 24 | // Automatically clear mock calls and instances between every test 25 | clearMocks: true, 26 | 27 | // Indicates whether the coverage information should be collected while executing the test 28 | // collectCoverage: false, 29 | 30 | // An array of glob patterns indicating a set of files for which coverage information should be collected 31 | // collectCoverageFrom: null, 32 | 33 | // The directory where Jest should output its coverage files 34 | // coverageDirectory: null, 35 | 36 | // An array of regexp pattern strings used to skip coverage collection 37 | // coveragePathIgnorePatterns: [ 38 | // "\\\\node_modules\\\\" 39 | // ], 40 | 41 | // A list of reporter names that Jest uses when writing coverage reports 42 | // coverageReporters: [ 43 | // "json", 44 | // "text", 45 | // "lcov", 46 | // "clover" 47 | // ], 48 | 49 | // An object that configures minimum threshold enforcement for coverage results 50 | // coverageThreshold: null, 51 | 52 | // Make calling deprecated APIs throw helpful error messages 53 | // errorOnDeprecated: false, 54 | 55 | // Force coverage collection from ignored files usin a array of glob patterns 56 | // forceCoverageMatch: [], 57 | 58 | // A path to a module which exports an async function that is triggered once before all test suites 59 | // globalSetup: null, 60 | 61 | // A path to a module which exports an async function that is triggered once after all test suites 62 | // globalTeardown: null, 63 | 64 | // A set of global variables that need to be available in all test environments 65 | // globals: {}, 66 | 67 | // An array of directory names to be searched recursively up from the requiring module's location 68 | // moduleDirectories: [ 69 | // "node_modules" 70 | // ], 71 | 72 | // An array of file extensions your modules use 73 | // moduleFileExtensions: [ 74 | // "js", 75 | // "json", 76 | // "jsx", 77 | // "node" 78 | // ], 79 | 80 | // A map from regular expressions to module names that allow to stub out resources with a single module 81 | moduleNameMapper: { 82 | "^phaser$": "/src/mocks/phaser.js", 83 | }, 84 | 85 | // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader 86 | // modulePathIgnorePatterns: [], 87 | 88 | // Activates notifications for test results 89 | // notify: false, 90 | 91 | // An enum that specifies notification mode. Requires { notify: true } 92 | // notifyMode: "always", 93 | 94 | // A preset that is used as a base for Jest's configuration 95 | // preset: null, 96 | 97 | // Run tests from one or more projects 98 | // projects: null, 99 | 100 | // Use this configuration option to add custom reporters to Jest 101 | // reporters: undefined, 102 | 103 | // Automatically reset mock state between every test 104 | // resetMocks: false, 105 | 106 | // Reset the module registry before running each individual test 107 | // resetModules: false, 108 | 109 | // A path to a custom resolver 110 | // resolver: null, 111 | 112 | // Automatically restore mock state between every test 113 | // restoreMocks: false, 114 | 115 | // The root directory that Jest should scan for tests and modules within 116 | rootDir: "./", 117 | 118 | // A list of paths to directories that Jest should use to search for files in 119 | roots: ["/src"], 120 | 121 | // Allows you to use a custom runner instead of Jest's default test runner 122 | // runner: "jest-runner", 123 | 124 | // The paths to modules that run some code to configure or set up the testing environment before each test 125 | // setupFiles: [], 126 | 127 | // The path to a module that runs some code to configure or set up the testing framework before each test 128 | // setupTestFrameworkScriptFile: null, 129 | 130 | // A list of paths to snapshot serializer modules Jest should use for snapshot testing 131 | // snapshotSerializers: [], 132 | 133 | // The test environment that will be used for testing 134 | testEnvironment: "node", 135 | 136 | // Options that will be passed to the testEnvironment 137 | // testEnvironmentOptions: {}, 138 | 139 | // Adds a location field to test results 140 | // testLocationInResults: false, 141 | 142 | // The glob patterns Jest uses to detect test files 143 | // testMatch: [ 144 | // "**/__tests__/**/*.js?(x)", 145 | // "**/?(*.)+(spec|test).js?(x)" 146 | // ], 147 | 148 | // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped 149 | // testPathIgnorePatterns: [ 150 | // "\\\\node_modules\\\\" 151 | // ], 152 | 153 | // The regexp pattern Jest uses to detect test files 154 | // testRegex: "", 155 | 156 | // This option allows the use of a custom results processor 157 | // testResultsProcessor: null, 158 | 159 | // This option allows use of a custom test runner 160 | // testRunner: "jasmine2", 161 | 162 | // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href 163 | // testURL: "http://localhost", 164 | 165 | // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" 166 | // timers: "real", 167 | 168 | // A map from regular expressions to paths to transformers 169 | // transform: null, 170 | 171 | // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation 172 | // transformIgnorePatterns: ["\\\\node_modules\\\\"], 173 | 174 | // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them 175 | // unmockedModulePathPatterns: undefined, 176 | 177 | // Indicates whether each individual test should be reported during the run 178 | verbose: true, 179 | 180 | // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode 181 | // watchPathIgnorePatterns: [], 182 | 183 | // Whether to use watchman for file crawling 184 | // watchman: true, 185 | }; 186 | -------------------------------------------------------------------------------- /workspaces/plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phaser-matter-collision-plugin", 3 | "version": "1.0.0", 4 | "description": "A plugin for making it easier to manage collisions with Phaser + Matter.js", 5 | "main": "dist/phaser-matter-collision.js", 6 | "files": [ 7 | "src/!(mocks|tests)", 8 | "dist" 9 | ], 10 | "types": "./dist/index.d.ts", 11 | "scripts": { 12 | "start": "yarn run dev", 13 | "prettier": "prettier --write \"{src,tests,config,cypress}/**/*.{js,ts}\"", 14 | "build:library": "webpack --mode production --config webpack.config.js", 15 | "build:tests": "webpack --mode development --config webpack.test.config.js", 16 | "watch:library": "webpack --mode development --config webpack.config.js --watch", 17 | "watch:tests": "webpack --mode development --config webpack.test.config.js --watch", 18 | "serve": "browser-sync start --server \".\" --directory --watch --startPath \"/tests\"", 19 | "dev": "concurrently \"npm run watch:tests\" \"npm run watch:library\" \"npm run serve\"", 20 | "dev:cypress": "concurrently \"npm run watch:tests\" \"npm run watch:library\" \"cypress open\"", 21 | "test:jest": "jest --config=./jest.config.js", 22 | "pretest:cypress": "npm run build:tests", 23 | "test:cypress": "cypress run", 24 | "doc": "typedoc --options typedoc.json && cp -r doc-source-assets/ docs/", 25 | "deploy:doc": "npm run doc && gh-pages --branch gh-pages --dist ./docs --dest docs", 26 | "prepublishOnly": "npm run build:library" 27 | }, 28 | "repository": { 29 | "type": "git", 30 | "url": "git+https://github.com/mikewesthad/phaser-matter-collision-plugin.git" 31 | }, 32 | "keywords": [ 33 | "matter.js", 34 | "phaser", 35 | "collision detection", 36 | "game engine", 37 | "physics engine" 38 | ], 39 | "author": "Michael Hadley", 40 | "license": "MIT", 41 | "bugs": { 42 | "url": "https://github.com/mikewesthad/phaser-matter-collision-plugin/issues" 43 | }, 44 | "homepage": "https://github.com/mikewesthad/phaser-matter-collision-plugin/workspaces/plugin#readme", 45 | "devDependencies": { 46 | "@babel/core": "^7.14.6", 47 | "@babel/preset-env": "^7.14.5", 48 | "@babel/preset-typescript": "^7.14.5", 49 | "@types/jest": "^26.0.23", 50 | "@types/node": "^15.12.2", 51 | "babel-loader": "^8.2.2", 52 | "browser-sync": "^2.26.14", 53 | "concurrently": "^6.2.0", 54 | "cypress": "^7.5.0", 55 | "eslint": "^7.28.0", 56 | "eslint-config-prettier": "^8.3.0", 57 | "eslint-plugin-prettier": "^3.4.0", 58 | "eventemitter3": "^4.0.7", 59 | "gh-pages": "^3.2.1", 60 | "jest": "^27.0.4", 61 | "phaser-slopes": "^0.1.1", 62 | "prettier": "^2.3.2", 63 | "regenerator-runtime": "^0.13.7", 64 | "ts-jest": "^27.0.3", 65 | "ts-loader": "^9.2.3", 66 | "typedoc": "^0.21.1", 67 | "typescript": "^4.3.2", 68 | "webpack": "^5.39.0", 69 | "webpack-cli": "^4.7.2" 70 | }, 71 | "prettier": { 72 | "printWidth": 100 73 | }, 74 | "peerDependencies": { 75 | "phaser": "^3.55.2" 76 | } 77 | } -------------------------------------------------------------------------------- /workspaces/plugin/src/collision-types.ts: -------------------------------------------------------------------------------- 1 | import { Physics, Types } from "phaser"; 2 | import { CollidingObject } from "./valid-collision-object"; 3 | 4 | type CO = CollidingObject; 5 | 6 | /** Helper to construct variants of the types where specific properties are optional. */ 7 | export type SelectivePartial = Omit & 8 | Partial; 9 | 10 | /** Alias to Matter type. */ 11 | export type MatterCollisionData = Types.Physics.Matter.MatterCollisionData; 12 | 13 | /** Extended matter collision event data with game objects. */ 14 | export interface ExtendedMatterCollisionData extends MatterCollisionData { 15 | gameObjectA?: CO; 16 | gameObjectB?: CO; 17 | } 18 | 19 | export type CollisionEvent = 20 | | Physics.Matter.Events.CollisionStartEvent 21 | | Physics.Matter.Events.CollisionActiveEvent 22 | | Physics.Matter.Events.CollisionEndEvent; 23 | 24 | export interface EventData { 25 | bodyA: MatterJS.Body; 26 | bodyB: MatterJS.Body; 27 | gameObjectA?: T; 28 | gameObjectB?: K; 29 | isReversed: boolean; 30 | pair: ExtendedMatterCollisionData; 31 | } 32 | 33 | /** 34 | * This generic type represents a start/active/end callback. It is used internally, but it can also 35 | * be used when you need to type a "callback" property manually, for example: 36 | * ```ts 37 | * const sprite = this.matter.add.sprite(350, 100, "emoji", "1f62c"); 38 | * const image = this.matter.add.image(350, 200, "emoji", "1f62c"); 39 | * const callback: CollideCallback = (e) => { 40 | * console.log("Hit!"); 41 | * }; 42 | * this.matterCollision.addOnCollideStart({ 43 | * objectA: sprite, 44 | * objectB: image, 45 | * callback: callback, 46 | * }); 47 | * ``` 48 | */ 49 | export interface CollideCallback { 50 | (event: EventData): void; 51 | } 52 | 53 | /** Config for specified A object(s) vs anything else collision listeners. */ 54 | export interface CollideAConfig { 55 | objectA: T | T[]; 56 | callback: CollideCallback; 57 | context?: CollideContext; 58 | } 59 | 60 | /** Config for specified A object(s) vs specified B object(s). */ 61 | export interface CollideABConfig { 62 | objectA: T | T[]; 63 | objectB: K | K[]; 64 | callback: CollideCallback; 65 | context?: CollideContext; 66 | } 67 | 68 | export interface InternalCollideConfig { 69 | objectA: CO | CO[]; 70 | objectB?: CO | CO[]; 71 | callback: CollideCallback; 72 | context?: CollideContext; 73 | } 74 | 75 | export type CollideContext = any; 76 | 77 | /** Variant of CollideAConfig to be used when removing listeners (where callback is optional). */ 78 | export type RemoveCollideConfigA = SelectivePartial, "callback">; 79 | 80 | /** Variant of CollideABConfig to be used when removing listeners (where callback is optional). */ 81 | export type RemoveCollideConfigAB = SelectivePartial< 82 | CollideABConfig, 83 | "callback" 84 | >; 85 | 86 | export type InternalCollideRemoveConfig = SelectivePartial; 87 | export interface ListenerInfo { 88 | target?: CO; 89 | callback: CollideCallback; 90 | context?: CollideContext; 91 | } 92 | 93 | export type ListenerMap = Map[]>; 94 | 95 | export interface Unsubscribe { 96 | (): void; 97 | } 98 | -------------------------------------------------------------------------------- /workspaces/plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import PhaserMatterCollisionPlugin from "./phaser-matter-collision-plugin"; 2 | import { getRootBody } from "./utils"; 3 | import { 4 | isCollidingObject, 5 | isMatterBody, 6 | ObjectWithBody, 7 | CollidingObject, 8 | } from "./valid-collision-object"; 9 | import { 10 | ExtendedMatterCollisionData, 11 | CollisionEvent, 12 | EventData, 13 | CollideCallback, 14 | CollideAConfig, 15 | CollideABConfig, 16 | CollideContext, 17 | Unsubscribe, 18 | } from "./collision-types"; 19 | 20 | export { 21 | PhaserMatterCollisionPlugin, 22 | getRootBody, 23 | isCollidingObject, 24 | isMatterBody, 25 | ObjectWithBody, 26 | CollidingObject, 27 | ExtendedMatterCollisionData, 28 | CollisionEvent, 29 | EventData, 30 | CollideCallback, 31 | CollideAConfig, 32 | CollideABConfig, 33 | CollideContext, 34 | Unsubscribe, 35 | }; 36 | 37 | export default PhaserMatterCollisionPlugin; 38 | -------------------------------------------------------------------------------- /workspaces/plugin/src/logger.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | log: console.log, 3 | warn: console.warn, 4 | error: console.error, 5 | }; 6 | -------------------------------------------------------------------------------- /workspaces/plugin/src/mocks/game-objects.js: -------------------------------------------------------------------------------- 1 | import { createBody } from "./matter"; 2 | 3 | export class Tile { 4 | constructor({ withMatter = false }) { 5 | this.physics = {}; 6 | 7 | if (withMatter) this.physics.matterBody = new MatterTileBody(this); 8 | } 9 | } 10 | 11 | export class MatterTileBody { 12 | constructor(tile) { 13 | this.body = createBody({ gameObject: this }); 14 | this.tile = tile; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /workspaces/plugin/src/mocks/matter.js: -------------------------------------------------------------------------------- 1 | import { Tile, MatterTileBody } from "./game-objects"; 2 | 3 | export function emitMatterCollisionEvent(scene, eventName, pairs) { 4 | scene.matter.world.emit(eventName, { pairs }); 5 | } 6 | 7 | export function createBody(options = {}) { 8 | // Necessary for faking body detection: gameObject, slop, parts, collisionFilter 9 | if (!options.collisionFilter) options.collisionFilter = 0; 10 | if (!options.slop) options.slop = 0.05; 11 | if (!options.gameObject) options.gameObject = null; 12 | const body = { ...options }; 13 | body.parts = [body]; 14 | body.parent = body; 15 | return body; 16 | } 17 | 18 | export function createPair(objectA, objectB) { 19 | let bodyA = objectA.body ? objectA.body : objectA; 20 | let bodyB = objectB.body ? objectB.body : objectB; 21 | if (objectA instanceof Tile) bodyA = objectA.physics.matterBody.body; 22 | if (objectB instanceof Tile) bodyB = objectB.physics.matterBody.body; 23 | return { bodyA, bodyB }; 24 | } 25 | -------------------------------------------------------------------------------- /workspaces/plugin/src/mocks/phaser.js: -------------------------------------------------------------------------------- 1 | import { MatterTileBody, Tile } from "./game-objects"; 2 | const EventEmitter = require("phaser/src/events/EventEmitter"); 3 | const SceneEvents = require("phaser/src/scene/events/index"); 4 | const MatterEvents = require("phaser/src/physics/matter-js/events/index"); 5 | 6 | const Plugins = { 7 | ScenePlugin: class ScenePlugin {}, 8 | }; 9 | const Physics = { 10 | Matter: { 11 | TileBody: MatterTileBody, 12 | Events: MatterEvents, 13 | }, 14 | }; 15 | const Tilemaps = { Tile }; 16 | const Events = { EventEmitter }; 17 | const Scenes = { 18 | Events: SceneEvents, 19 | }; 20 | const Types = {}; 21 | const Phaser = { 22 | Plugins, 23 | Physics, 24 | Tilemaps, 25 | Events, 26 | Scenes, 27 | Types, 28 | }; 29 | 30 | export default Phaser; 31 | export { Plugins, Physics, Tilemaps, Events, Types, Scenes }; 32 | -------------------------------------------------------------------------------- /workspaces/plugin/src/mocks/scene.js: -------------------------------------------------------------------------------- 1 | const EventEmitter = require("phaser/src/events/EventEmitter"); 2 | 3 | export default class Scene { 4 | constructor({ addMatter = true } = {}) { 5 | this.events = new EventEmitter(); 6 | if (addMatter) 7 | this.matter = { 8 | world: new EventEmitter(), 9 | }; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /workspaces/plugin/src/tests/plugin-gameobject-collisions.test.ts: -------------------------------------------------------------------------------- 1 | import Plugin from "../phaser-matter-collision-plugin"; 2 | import Scene from "../mocks/scene"; 3 | import { emitMatterCollisionEvent, createBody, createPair } from "../mocks/matter"; 4 | import { Tile } from "../mocks/game-objects"; 5 | 6 | describe("scene started with matter", () => { 7 | let scene: Phaser.Scene; 8 | let plugin: Plugin; 9 | 10 | beforeEach(() => { 11 | scene = new Scene({ addMatter: true }) as Phaser.Scene; 12 | plugin = new Plugin(scene as Phaser.Scene, {} as Phaser.Plugins.PluginManager, ""); 13 | scene.events.emit("start"); 14 | }); 15 | 16 | test("addOnCollideStart between body and physics-enabled Tile should fire callback with body and Tile", () => { 17 | const objectA = createBody() as Phaser.Types.Physics.Matter.MatterBody; 18 | const objectB = new Tile({ withMatter: true }) as Phaser.Tilemaps.Tile; 19 | const callback = jest.fn(); 20 | const pair = createPair(objectA, objectB); 21 | plugin.addOnCollideStart({ objectA, objectB, callback }); 22 | emitMatterCollisionEvent(scene, "collisionstart", [pair]); 23 | expect(callback.mock.calls.length).toBe(1); 24 | const callbackData = callback.mock.calls[0][0]; 25 | expect(callbackData.bodyA).toBe(objectA); 26 | expect(callbackData.bodyB).toBe((objectB.physics as any).matterBody.body); 27 | expect(callbackData.gameObjectA).toBe(undefined); 28 | expect(callbackData.gameObjectB).toBe(objectB); 29 | expect(callbackData.pair).toBe(pair); 30 | }); 31 | 32 | test("removeOnCollideStart between body and Tile should remove callbacks", () => { 33 | const objectA = createBody() as Phaser.Types.Physics.Matter.MatterBody; 34 | const objectB = new Tile({ withMatter: true }) as Phaser.Tilemaps.Tile; 35 | const callback = jest.fn(); 36 | const pair = createPair(objectA, objectB); 37 | plugin.addOnCollideStart({ objectA, objectB, callback }); 38 | plugin.removeOnCollideStart({ objectA, objectB, callback }); 39 | emitMatterCollisionEvent(scene, "collisionstart", [pair]); 40 | expect(callback.mock.calls.length).toBe(0); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /workspaces/plugin/src/tests/plugin-lifecycle.test.ts: -------------------------------------------------------------------------------- 1 | import Plugin from "../phaser-matter-collision-plugin"; 2 | import Scene from "../mocks/scene"; 3 | 4 | jest.mock("../logger"); 5 | import logger from "../logger"; 6 | 7 | describe("scene started without matter", () => { 8 | let scene: Phaser.Scene; 9 | let plugin: Plugin; 10 | 11 | beforeEach(() => { 12 | scene = new Scene({ addMatter: false }) as Phaser.Scene; 13 | plugin = new Plugin(scene as Phaser.Scene, {} as Phaser.Plugins.PluginManager, ""); 14 | scene.events.emit("start"); 15 | }); 16 | 17 | test("creating plugin without matter should warn the user", () => { 18 | expect(plugin).toBeDefined(); 19 | expect(logger.warn).toHaveBeenCalled(); 20 | }); 21 | }); 22 | 23 | describe("scene started with matter", () => { 24 | let scene: Phaser.Scene; 25 | let plugin: Plugin; 26 | 27 | beforeEach(() => { 28 | scene = new Scene({ addMatter: true }) as Phaser.Scene; 29 | plugin = new Plugin(scene as Phaser.Scene, {} as Phaser.Plugins.PluginManager, ""); 30 | scene.events.emit("start"); 31 | }); 32 | 33 | test("can create plugin with matter installed", () => { 34 | expect(plugin).toBeDefined(); 35 | expect(logger.warn).not.toHaveBeenCalled(); 36 | }); 37 | 38 | test("after destroying a scene, the plugin should not listen to any scene or matter world events", () => { 39 | scene.events.emit("destroy"); 40 | scene.events.eventNames().forEach((name) => { 41 | expect(scene.events.listenerCount(name)).toBe(0); 42 | }); 43 | scene.matter.world.eventNames().forEach((name) => { 44 | expect(scene.matter.world.listenerCount(name)).toBe(0); 45 | }); 46 | }); 47 | 48 | test("after shutting down a scene, the plugin should not listen to any scene or matter world events", () => { 49 | scene.events.emit("destroy"); 50 | scene.events.eventNames().forEach((name) => { 51 | expect(scene.events.listenerCount(name)).toBe(0); 52 | }); 53 | scene.matter.world.eventNames().forEach((name) => { 54 | expect(scene.matter.world.listenerCount(name)).toBe(0); 55 | }); 56 | }); 57 | 58 | test("after restarting a scene, the plugin should be subscribed to matter events", () => { 59 | scene.events.emit("shutdown"); 60 | scene.events.emit("start"); 61 | expect(scene.matter.world.listenerCount("collisionstart")).not.toBe(0); 62 | expect(scene.matter.world.listenerCount("collisionend")).not.toBe(0); 63 | expect(scene.matter.world.listenerCount("collisionactive")).not.toBe(0); 64 | }); 65 | }); 66 | -------------------------------------------------------------------------------- /workspaces/plugin/src/utils.ts: -------------------------------------------------------------------------------- 1 | import logger from "./logger"; 2 | 3 | /** 4 | * Get the root body of a compound Matter body. 5 | */ 6 | export function getRootBody(body: MatterJS.BodyType) { 7 | while (body.parent !== body) body = body.parent; 8 | return body; 9 | } 10 | 11 | /** 12 | * @param obj 13 | */ 14 | export function warnInvalidObject(obj: any) { 15 | logger.warn( 16 | `Expected a Matter body, a Tile, a GameObject, a Sprite, an Image, a TileBody, or an object with a body property, but instead, received: ${obj}` 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /workspaces/plugin/src/valid-collision-object.ts: -------------------------------------------------------------------------------- 1 | import { Tilemaps, Types } from "phaser"; 2 | 3 | import Tile = Tilemaps.Tile; 4 | import MatterBody = Types.Physics.Matter.MatterBody; 5 | 6 | /** A valid physics-enabled game object, or just an object that has "body" property */ 7 | export type ObjectWithBody = { 8 | body: MatterJS.BodyType; 9 | }; 10 | 11 | /** 12 | * A union of all the types of physics objects we could have in the simulation - from raw Matter.js 13 | * bodies to tiles and physics-enabled Phaser GameObjects. 14 | */ 15 | export type CollidingObject = MatterBody | MatterJS.BodyType | Tile | ObjectWithBody; 16 | 17 | /** Duck type to check if the given object is a Matter body (because there isn't a prototype). */ 18 | export function isMatterBody(obj: any): obj is MatterBody { 19 | return ( 20 | obj.hasOwnProperty("parts") && obj.hasOwnProperty("slop") && obj.hasOwnProperty("gameObject") 21 | ); 22 | } 23 | 24 | /** 25 | * Check if object is an acceptable physical object for this plugin - a Matter Body, a tile, or an 26 | * object with a body property. 27 | */ 28 | export function isCollidingObject(obj: any): obj is CollidingObject { 29 | // GameObjects, images, sprites and tile bodies should all have a body property. 30 | return isMatterBody(obj) || obj.body || obj instanceof Tile; 31 | } 32 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji.json: -------------------------------------------------------------------------------- 1 | {"frames": { 2 | 3 | "1f4a9": 4 | { 5 | "frame": {"x":297,"y":1,"w":72,"h":72}, 6 | "rotated": false, 7 | "trimmed": false, 8 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 9 | "sourceSize": {"w":72,"h":72} 10 | }, 11 | "1f31a": 12 | { 13 | "frame": {"x":1,"y":1,"w":72,"h":72}, 14 | "rotated": false, 15 | "trimmed": false, 16 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 17 | "sourceSize": {"w":72,"h":72} 18 | }, 19 | "1f31d": 20 | { 21 | "frame": {"x":75,"y":1,"w":72,"h":72}, 22 | "rotated": false, 23 | "trimmed": false, 24 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 25 | "sourceSize": {"w":72,"h":72} 26 | }, 27 | "1f31e": 28 | { 29 | "frame": {"x":149,"y":1,"w":72,"h":72}, 30 | "rotated": false, 31 | "trimmed": false, 32 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 33 | "sourceSize": {"w":72,"h":72} 34 | }, 35 | "1f47d": 36 | { 37 | "frame": {"x":1628,"y":1,"w":70,"h":72}, 38 | "rotated": false, 39 | "trimmed": true, 40 | "spriteSourceSize": {"x":1,"y":0,"w":70,"h":72}, 41 | "sourceSize": {"w":72,"h":72} 42 | }, 43 | "1f47f": 44 | { 45 | "frame": {"x":223,"y":1,"w":72,"h":72}, 46 | "rotated": false, 47 | "trimmed": false, 48 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 49 | "sourceSize": {"w":72,"h":72} 50 | }, 51 | "1f60d": 52 | { 53 | "frame": {"x":445,"y":1,"w":72,"h":72}, 54 | "rotated": false, 55 | "trimmed": false, 56 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 57 | "sourceSize": {"w":72,"h":72} 58 | }, 59 | "1f61c": 60 | { 61 | "frame": {"x":519,"y":1,"w":72,"h":72}, 62 | "rotated": false, 63 | "trimmed": false, 64 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 65 | "sourceSize": {"w":72,"h":72} 66 | }, 67 | "1f62c": 68 | { 69 | "frame": {"x":667,"y":1,"w":72,"h":72}, 70 | "rotated": false, 71 | "trimmed": false, 72 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 73 | "sourceSize": {"w":72,"h":72} 74 | }, 75 | "1f62d": 76 | { 77 | "frame": {"x":741,"y":1,"w":72,"h":72}, 78 | "rotated": false, 79 | "trimmed": false, 80 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 81 | "sourceSize": {"w":72,"h":72} 82 | }, 83 | "1f62e": 84 | { 85 | "frame": {"x":815,"y":1,"w":72,"h":72}, 86 | "rotated": false, 87 | "trimmed": false, 88 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 89 | "sourceSize": {"w":72,"h":72} 90 | }, 91 | "1f92a": 92 | { 93 | "frame": {"x":1259,"y":1,"w":72,"h":72}, 94 | "rotated": false, 95 | "trimmed": false, 96 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 97 | "sourceSize": {"w":72,"h":72} 98 | }, 99 | "1f92c": 100 | { 101 | "frame": {"x":1333,"y":1,"w":72,"h":72}, 102 | "rotated": false, 103 | "trimmed": false, 104 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 105 | "sourceSize": {"w":72,"h":72} 106 | }, 107 | "1f92e": 108 | { 109 | "frame": {"x":1700,"y":1,"w":70,"h":72}, 110 | "rotated": false, 111 | "trimmed": true, 112 | "spriteSourceSize": {"x":1,"y":0,"w":70,"h":72}, 113 | "sourceSize": {"w":72,"h":72} 114 | }, 115 | "1f92f": 116 | { 117 | "frame": {"x":1555,"y":1,"w":71,"h":72}, 118 | "rotated": false, 119 | "trimmed": true, 120 | "spriteSourceSize": {"x":0,"y":0,"w":71,"h":72}, 121 | "sourceSize": {"w":72,"h":72} 122 | }, 123 | "1f608": 124 | { 125 | "frame": {"x":371,"y":1,"w":72,"h":72}, 126 | "rotated": false, 127 | "trimmed": false, 128 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 129 | "sourceSize": {"w":72,"h":72} 130 | }, 131 | "1f621": 132 | { 133 | "frame": {"x":593,"y":1,"w":72,"h":72}, 134 | "rotated": false, 135 | "trimmed": false, 136 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 137 | "sourceSize": {"w":72,"h":72} 138 | }, 139 | "1f631": 140 | { 141 | "frame": {"x":889,"y":1,"w":72,"h":72}, 142 | "rotated": false, 143 | "trimmed": false, 144 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 145 | "sourceSize": {"w":72,"h":72} 146 | }, 147 | "1f912": 148 | { 149 | "frame": {"x":963,"y":1,"w":72,"h":72}, 150 | "rotated": false, 151 | "trimmed": false, 152 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 153 | "sourceSize": {"w":72,"h":72} 154 | }, 155 | "1f913": 156 | { 157 | "frame": {"x":1037,"y":1,"w":72,"h":72}, 158 | "rotated": false, 159 | "trimmed": false, 160 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 161 | "sourceSize": {"w":72,"h":72} 162 | }, 163 | "1f915": 164 | { 165 | "frame": {"x":1111,"y":1,"w":72,"h":72}, 166 | "rotated": false, 167 | "trimmed": false, 168 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 169 | "sourceSize": {"w":72,"h":72} 170 | }, 171 | "1f922": 172 | { 173 | "frame": {"x":1185,"y":1,"w":72,"h":72}, 174 | "rotated": false, 175 | "trimmed": false, 176 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 177 | "sourceSize": {"w":72,"h":72} 178 | }, 179 | "1f975": 180 | { 181 | "frame": {"x":1407,"y":1,"w":72,"h":72}, 182 | "rotated": false, 183 | "trimmed": false, 184 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 185 | "sourceSize": {"w":72,"h":72} 186 | }, 187 | "1f976": 188 | { 189 | "frame": {"x":1481,"y":1,"w":72,"h":72}, 190 | "rotated": false, 191 | "trimmed": false, 192 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 193 | "sourceSize": {"w":72,"h":72} 194 | }}, 195 | "meta": { 196 | "app": "http://www.codeandweb.com/texturepacker", 197 | "version": "1.0", 198 | "image": "emoji.png", 199 | "format": "RGBA8888", 200 | "size": {"w":1771,"h":74}, 201 | "scale": "1", 202 | "smartupdate": "$TexturePacker:SmartUpdate:80919c52b607def3c7f647a71f5d2f19:8df71fe38bb708a3bec8b99fc4709ddb:3b6ee1b3efdb705ed941d972d580542a$" 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f31a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f31a.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f31d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f31d.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f31e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f31e.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f47d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f47d.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f47f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f47f.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f4a9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f4a9.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f608.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f608.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f60d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f60d.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f61c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f61c.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f621.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f621.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f62c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f62c.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f62d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f62d.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f62e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f62e.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f631.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f631.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f912.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f912.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f913.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f913.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f915.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f915.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f922.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f922.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f92a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f92a.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f92c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f92c.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f92e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f92e.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f92f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f92f.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f975.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f975.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/atlases/emoji/1f976.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/atlases/emoji/1f976.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/cursors/pointer.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/cursors/pointer.cur -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/cursors/pointer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/cursors/pointer.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/cursors/pointer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 11 | 17 | 25 | 27 | 29 | 31 | 33 | 35 | 37 | 39 | 41 | 43 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/images/block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/images/block.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/images/chain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/images/chain.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/images/wooden-plank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/images/wooden-plank.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/spritesheets/0x72-industrial-player-32px-extruded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/spritesheets/0x72-industrial-player-32px-extruded.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/tilesets/kenney-tileset-64px-extruded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/tilesets/kenney-tileset-64px-extruded.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/assets/tilesets/kenney-tileset-64px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/plugin/tests/assets/tilesets/kenney-tileset-64px.png -------------------------------------------------------------------------------- /workspaces/plugin/tests/collision-events/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Phaser 3 Template 9 | 10 | 30 | 31 | 32 | 33 |
      34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/collision-events/src/index.js: -------------------------------------------------------------------------------- 1 | import Phaser from "phaser"; 2 | import PhaserMatterCollisionPlugin from "../../../src"; 3 | import MainScene from "./main-scene.js"; 4 | 5 | const config = { 6 | type: Phaser.AUTO, 7 | width: 800, 8 | height: 600, 9 | backgroundColor: "#000c1f", 10 | parent: "game-container", 11 | pixelArt: true, 12 | scene: MainScene, 13 | physics: { 14 | default: "matter", 15 | matter: { 16 | debug: false, 17 | }, 18 | }, 19 | plugins: { 20 | scene: [ 21 | { 22 | key: "MatterCollisionPlugin", 23 | plugin: PhaserMatterCollisionPlugin, 24 | mapping: "matterCollision", 25 | start: true, 26 | }, 27 | ], 28 | }, 29 | }; 30 | 31 | const game = new Phaser.Game(config); 32 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/collision-events/src/main-scene.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Verify that the matterCollision.events "collisionstart", "collisionend", "collisionactive" are 3 | * all firing for a bouncing ball hitting the ground, bouncing and then coming to rest. 4 | */ 5 | 6 | import Phaser from "phaser"; 7 | import { startTest, failTest, passTest } from "../../test-utils"; 8 | 9 | export default class MainScene extends Phaser.Scene { 10 | preload() { 11 | this.load.tilemapTiledJSON("map", "../assets/tilemaps/simple-map-collision-mapped.json"); 12 | this.load.image( 13 | "kenney-tileset-64px-extruded", 14 | "../assets/tilesets/kenney-tileset-64px-extruded.png" 15 | ); 16 | this.load.atlas("emoji", "../assets/atlases/emoji.png", "../assets/atlases/emoji.json"); 17 | } 18 | 19 | create() { 20 | const map = this.make.tilemap({ key: "map" }); 21 | const tileset = map.addTilesetImage("kenney-tileset-64px-extruded"); 22 | const groundLayer = map.createLayer("Ground", tileset, 0, 0); 23 | const lavaLayer = map.createLayer("Lava", tileset, 0, 0); 24 | 25 | groundLayer.setCollisionByProperty({ collides: true }); 26 | lavaLayer.setCollisionByProperty({ collides: true }); 27 | 28 | this.matter.world.convertTilemapLayer(groundLayer); 29 | this.matter.world.convertTilemapLayer(lavaLayer); 30 | 31 | const image = this.matter.add.image(250, 50, "emoji", "1f92c", { 32 | restitution: 0.25, 33 | friction: 0, 34 | shape: "circle", 35 | }); 36 | 37 | const state = { startFired: false, activeFired: false, endFired: false }; 38 | const updateState = ({ startFired, activeFired, endFired }) => { 39 | if (startFired) state.startFired = true; 40 | if (activeFired) state.activeFired = true; 41 | if (endFired) state.endFired = true; 42 | if (state.startFired && state.activeFired && state.endFired) passTest(); 43 | }; 44 | startTest(); 45 | 46 | this.matterCollision.events.on("collisionstart", (event) => { 47 | event.pairs.forEach(({ gameObjectA, gameObjectB }) => { 48 | if ([gameObjectA, gameObjectB].includes(image)) { 49 | updateState({ startFired: true }); 50 | } 51 | }); 52 | }); 53 | this.matterCollision.events.on("collisionactive", (event) => { 54 | event.pairs.forEach(({ gameObjectA, gameObjectB }) => { 55 | if ([gameObjectA, gameObjectB].includes(image)) { 56 | updateState({ activeFired: true }); 57 | } 58 | }); 59 | }); 60 | this.matterCollision.events.on("collisionend", (event) => { 61 | event.pairs.forEach(({ gameObjectA, gameObjectB }) => { 62 | if ([gameObjectA, gameObjectB].includes(image)) { 63 | updateState({ endFired: true }); 64 | } 65 | }); 66 | }); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/gameobject-collide-gameobject/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Phaser 3 Template 9 | 10 | 30 | 31 | 32 | 33 |
      34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/gameobject-collide-gameobject/src/index.js: -------------------------------------------------------------------------------- 1 | import Phaser from "phaser"; 2 | import PhaserMatterCollisionPlugin from "../../../src"; 3 | import MainScene from "./main-scene.js"; 4 | 5 | const config = { 6 | type: Phaser.AUTO, 7 | width: 800, 8 | height: 600, 9 | backgroundColor: "#000c1f", 10 | parent: "game-container", 11 | pixelArt: true, 12 | scene: MainScene, 13 | physics: { 14 | default: "matter", 15 | matter: { 16 | debug: false, 17 | }, 18 | }, 19 | plugins: { 20 | scene: [ 21 | { 22 | key: "MatterCollisionPlugin", 23 | plugin: PhaserMatterCollisionPlugin, 24 | mapping: "matterCollision", 25 | start: true, 26 | }, 27 | ], 28 | }, 29 | }; 30 | 31 | const game = new Phaser.Game(config); 32 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/gameobject-collide-gameobject/src/main-scene.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Verify that the matterCollision's addOnCollideStart, addOnCollideActive and addOnCollideEnd fire 3 | * correctly for GO vs GO collisions. Three objects are created and only collisions between two of 4 | * them should fire. 5 | */ 6 | 7 | import Phaser from "phaser"; 8 | import { startTest, failTest, passTest } from "../../test-utils"; 9 | 10 | export default class MainScene extends Phaser.Scene { 11 | preload() { 12 | this.load.tilemapTiledJSON("map", "../assets/tilemaps/simple-map-collision-mapped.json"); 13 | this.load.image( 14 | "kenney-tileset-64px-extruded", 15 | "../assets/tilesets/kenney-tileset-64px-extruded.png" 16 | ); 17 | this.load.atlas("emoji", "../assets/atlases/emoji.png", "../assets/atlases/emoji.json"); 18 | } 19 | 20 | create() { 21 | const map = this.make.tilemap({ key: "map" }); 22 | const tileset = map.addTilesetImage("kenney-tileset-64px-extruded"); 23 | const groundLayer = map.createLayer("Ground", tileset, 0, 0); 24 | const lavaLayer = map.createLayer("Lava", tileset, 0, 0); 25 | 26 | groundLayer.setCollisionByProperty({ collides: true }); 27 | lavaLayer.setCollisionByProperty({ collides: true }); 28 | 29 | this.matter.world.convertTilemapLayer(groundLayer); 30 | this.matter.world.convertTilemapLayer(lavaLayer); 31 | 32 | const image1 = this.matter.add.image(250, 50, "emoji", "1f92c", { 33 | restitution: 0, 34 | friction: 1, 35 | shape: "circle", 36 | }); 37 | 38 | const image2 = this.matter.add 39 | .image(250, 150, "emoji", "1f4a9", { 40 | restitution: 0, 41 | friction: 1, 42 | shape: "circle", 43 | }) 44 | .setScale(0.5); 45 | 46 | const image3 = this.matter.add 47 | .image(250, 0, "emoji", "1f31e", { 48 | restitution: 0, 49 | friction: 1, 50 | shape: "circle", 51 | }) 52 | .setScale(0.25); 53 | 54 | const state = { startFired: false, activeFired: false, endFired: false }; 55 | const updateState = ({ startFired, activeFired, endFired }) => { 56 | if (startFired) state.startFired = true; 57 | if (activeFired) state.activeFired = true; 58 | if (endFired) state.endFired = true; 59 | if (state.startFired && state.activeFired && state.endFired) passTest(); 60 | }; 61 | 62 | startTest(); 63 | 64 | const scene = this; 65 | 66 | this.matterCollision.addOnCollideStart({ 67 | objectA: image1, 68 | objectB: image2, 69 | callback: function (pairData) { 70 | const { bodyA, gameObjectA, bodyB, gameObjectB, pair } = pairData; 71 | if ( 72 | !this === scene || 73 | gameObjectA !== image1 || 74 | gameObjectB !== image2 || 75 | bodyA !== image1.body || 76 | bodyB !== image2.body || 77 | !pair 78 | ) { 79 | failTest(); 80 | this.game.destroy(true); 81 | } else { 82 | updateState({ startFired: true }); 83 | } 84 | }, 85 | context: this, 86 | }); 87 | 88 | this.matterCollision.addOnCollideActive({ 89 | objectA: image1, 90 | objectB: image2, 91 | callback: function (pairData) { 92 | const { bodyA, gameObjectA, bodyB, gameObjectB, pair } = pairData; 93 | if ( 94 | !this === scene || 95 | gameObjectA !== image1 || 96 | gameObjectB !== image2 || 97 | bodyA !== image1.body || 98 | bodyB !== image2.body || 99 | !pair 100 | ) { 101 | failTest(); 102 | this.game.destroy(true); 103 | } else { 104 | updateState({ activeFired: true }); 105 | } 106 | }, 107 | context: this, 108 | }); 109 | 110 | this.matterCollision.addOnCollideEnd({ 111 | objectA: image1, 112 | objectB: image2, 113 | callback: function (pairData) { 114 | const { bodyA, gameObjectA, bodyB, gameObjectB, pair } = pairData; 115 | if ( 116 | !this === scene || 117 | gameObjectA !== image1 || 118 | gameObjectB !== image2 || 119 | bodyA !== image1.body || 120 | bodyB !== image2.body || 121 | !pair 122 | ) { 123 | failTest(); 124 | this.game.destroy(true); 125 | } else { 126 | updateState({ endFired: true }); 127 | } 128 | }, 129 | context: this, 130 | }); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/gameobject-collide-tiles/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Phaser 3 Template 9 | 10 | 30 | 31 | 32 | 33 |
      34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/gameobject-collide-tiles/src/index.js: -------------------------------------------------------------------------------- 1 | import Phaser from "phaser"; 2 | import PhaserMatterCollisionPlugin from "../../../src"; 3 | import MainScene from "./main-scene.js"; 4 | 5 | const config = { 6 | type: Phaser.AUTO, 7 | width: 800, 8 | height: 600, 9 | backgroundColor: "#000c1f", 10 | parent: "game-container", 11 | pixelArt: true, 12 | scene: MainScene, 13 | physics: { 14 | default: "matter", 15 | matter: { 16 | debug: false, 17 | }, 18 | }, 19 | plugins: { 20 | scene: [ 21 | { 22 | key: "MatterCollisionPlugin", 23 | plugin: PhaserMatterCollisionPlugin, 24 | mapping: "matterCollision", 25 | start: true, 26 | }, 27 | ], 28 | }, 29 | }; 30 | 31 | const game = new Phaser.Game(config); 32 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/gameobject-collide-tiles/src/main-scene.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Verify collisions fire properly for compound GO vs invidual tiles and vs all tiles 3 | */ 4 | 5 | import Phaser from "phaser"; 6 | import { startTest, failTest, passTest } from "../../test-utils"; 7 | 8 | export default class MainScene extends Phaser.Scene { 9 | preload() { 10 | this.load.tilemapTiledJSON("map", "../assets/tilemaps/simple-map-collision-mapped.json"); 11 | this.load.image( 12 | "kenney-tileset-64px-extruded", 13 | "../assets/tilesets/kenney-tileset-64px-extruded.png" 14 | ); 15 | this.load.atlas("emoji", "../assets/atlases/emoji.png", "../assets/atlases/emoji.json"); 16 | } 17 | 18 | create() { 19 | const map = this.make.tilemap({ key: "map" }); 20 | const tileset = map.addTilesetImage("kenney-tileset-64px-extruded"); 21 | const groundLayer = map.createLayer("Ground", tileset, 0, 0); 22 | const lavaLayer = map.createLayer("Lava", tileset, 0, 0); 23 | 24 | groundLayer.setCollisionByProperty({ collides: true }); 25 | lavaLayer.setCollisionByProperty({ collides: true }); 26 | 27 | this.matter.world.convertTilemapLayer(groundLayer); 28 | this.matter.world.convertTilemapLayer(lavaLayer); 29 | 30 | // Compound body cross 31 | const graphics = this.add.graphics().setData("name", "bars"); 32 | const M = Phaser.Physics.Matter.Matter; 33 | const compoundBody = M.Body.create({ 34 | parts: [ 35 | M.Bodies.rectangle(0, 0, 20, 200), 36 | M.Bodies.rectangle(100, 0, 20, 200), 37 | M.Bodies.rectangle(200, 0, 20, 200), 38 | M.Bodies.rectangle(300, 0, 20, 200), 39 | ], 40 | }); 41 | graphics.fillStyle(0xff0000, 1); 42 | graphics.fillRect(-160, -100, 20, 200); 43 | graphics.fillRect(-60, -100, 20, 200); 44 | graphics.fillRect(40, -100, 20, 200); 45 | graphics.fillRect(140, -100, 20, 200); 46 | this.matter.add.gameObject(graphics).setExistingBody(compoundBody).setPosition(400, 0); 47 | 48 | const signTile = groundLayer.getTileAt(4, 5); 49 | 50 | const state = { hitSign: false, tilesHit: 0 }; 51 | const updateState = () => { 52 | if (state.hitSign && state.tilesHit >= 5) passTest(); 53 | }; 54 | startTest(); 55 | 56 | this.matterCollision.addOnCollideStart({ 57 | objectA: graphics, 58 | callback: (pairData) => { 59 | const { bodyA, bodyB, gameObjectA, gameObjectB } = pairData; 60 | if (gameObjectB instanceof Phaser.Tilemaps.Tile) { 61 | state.tilesHit++; 62 | updateState(); 63 | } 64 | }, 65 | }); 66 | 67 | this.matterCollision.addOnCollideStart({ 68 | objectA: graphics, 69 | objectB: signTile, 70 | callback: () => { 71 | state.hitSign = true; 72 | updateState(); 73 | }, 74 | }); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/pair-collision-events/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Phaser 3 Template 9 | 10 | 30 | 31 | 32 | 33 |
      34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/pair-collision-events/src/index.js: -------------------------------------------------------------------------------- 1 | import Phaser from "phaser"; 2 | import PhaserMatterCollisionPlugin from "../../../src"; 3 | import MainScene from "./main-scene.js"; 4 | 5 | const config = { 6 | type: Phaser.AUTO, 7 | width: 800, 8 | height: 600, 9 | backgroundColor: "#000c1f", 10 | parent: "game-container", 11 | pixelArt: true, 12 | scene: MainScene, 13 | physics: { 14 | default: "matter", 15 | matter: { 16 | debug: false, 17 | }, 18 | }, 19 | plugins: { 20 | scene: [ 21 | { 22 | key: "MatterCollisionPlugin", 23 | plugin: PhaserMatterCollisionPlugin, 24 | mapping: "matterCollision", 25 | start: true, 26 | }, 27 | ], 28 | }, 29 | }; 30 | 31 | const game = new Phaser.Game(config); 32 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/pair-collision-events/src/main-scene.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Verify that the matterCollision.events "paircollisionstart", "paircollisionend", 3 | * "paircollisionactive" are all firing for a bouncing ball hitting the ground, bouncing and then 4 | * coming to rest. 5 | */ 6 | 7 | import Phaser from "phaser"; 8 | import { startTest, failTest, passTest } from "../../test-utils"; 9 | 10 | export default class MainScene extends Phaser.Scene { 11 | preload() { 12 | this.load.tilemapTiledJSON("map", "../assets/tilemaps/simple-map-collision-mapped.json"); 13 | this.load.image( 14 | "kenney-tileset-64px-extruded", 15 | "../assets/tilesets/kenney-tileset-64px-extruded.png" 16 | ); 17 | this.load.atlas("emoji", "../assets/atlases/emoji.png", "../assets/atlases/emoji.json"); 18 | } 19 | 20 | create() { 21 | const map = this.make.tilemap({ key: "map" }); 22 | const tileset = map.addTilesetImage("kenney-tileset-64px-extruded"); 23 | const groundLayer = map.createLayer("Ground", tileset, 0, 0); 24 | const lavaLayer = map.createLayer("Lava", tileset, 0, 0); 25 | 26 | groundLayer.setCollisionByProperty({ collides: true }); 27 | lavaLayer.setCollisionByProperty({ collides: true }); 28 | 29 | this.matter.world.convertTilemapLayer(groundLayer); 30 | this.matter.world.convertTilemapLayer(lavaLayer); 31 | 32 | const image = this.matter.add.image(250, 50, "emoji", "1f92c", { 33 | restitution: 0.25, 34 | friction: 0, 35 | shape: "circle", 36 | }); 37 | 38 | const state = { startFired: false, activeFired: false, endFired: false }; 39 | const updateState = ({ startFired, activeFired, endFired }) => { 40 | if (startFired) state.startFired = true; 41 | if (activeFired) state.activeFired = true; 42 | if (endFired) state.endFired = true; 43 | if (state.startFired && state.activeFired && state.endFired) passTest(); 44 | }; 45 | startTest(); 46 | 47 | this.matterCollision.events.on("paircollisionstart", (pair) => { 48 | const { gameObjectA, gameObjectB } = pair; 49 | if ([gameObjectA, gameObjectB].includes(image)) { 50 | updateState({ startFired: true }); 51 | } 52 | }); 53 | this.matterCollision.events.on("paircollisionactive", (pair) => { 54 | const { gameObjectA, gameObjectB } = pair; 55 | if ([gameObjectA, gameObjectB].includes(image)) { 56 | updateState({ activeFired: true }); 57 | } 58 | }); 59 | this.matterCollision.events.on("paircollisionend", (pair) => { 60 | const { gameObjectA, gameObjectB } = pair; 61 | if ([gameObjectA, gameObjectB].includes(image)) { 62 | updateState({ endFired: true }); 63 | } 64 | }); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/restarting/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Phaser 3 Template 9 | 10 | 30 | 31 | 32 | 33 |
      34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/restarting/src/index.js: -------------------------------------------------------------------------------- 1 | import Phaser from "phaser"; 2 | import PhaserMatterCollisionPlugin from "../../../src"; 3 | import MainScene from "./main-scene.js"; 4 | 5 | const config = { 6 | type: Phaser.AUTO, 7 | width: 800, 8 | height: 600, 9 | backgroundColor: "#000c1f", 10 | parent: "game-container", 11 | pixelArt: true, 12 | scene: MainScene, 13 | physics: { 14 | default: "matter", 15 | matter: { 16 | debug: false, 17 | }, 18 | }, 19 | plugins: { 20 | scene: [ 21 | { 22 | key: "MatterCollisionPlugin", 23 | plugin: PhaserMatterCollisionPlugin, 24 | mapping: "matterCollision", 25 | start: true, 26 | }, 27 | ], 28 | }, 29 | }; 30 | 31 | const game = new Phaser.Game(config); 32 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/restarting/src/main-scene.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Verify that the matterCollision's addOnCollideStart, addOnCollideActive and addOnCollideEnd fire 3 | * correctly for GO vs GO collisions. Three objects are created and only collisions between two of 4 | * them should fire. 5 | */ 6 | 7 | import Phaser from "phaser"; 8 | import { startTest, failTest, passTest } from "../../test-utils"; 9 | 10 | startTest(); 11 | 12 | export default class MainScene extends Phaser.Scene { 13 | constructor() { 14 | super(); 15 | this.restartCount = 0; 16 | } 17 | 18 | preload() { 19 | this.load.tilemapTiledJSON("map", "../assets/tilemaps/simple-map-collision-mapped.json"); 20 | this.load.image( 21 | "kenney-tileset-64px-extruded", 22 | "../assets/tilesets/kenney-tileset-64px-extruded.png" 23 | ); 24 | this.load.atlas("emoji", "../assets/atlases/emoji.png", "../assets/atlases/emoji.json"); 25 | } 26 | 27 | create() { 28 | const map = this.make.tilemap({ key: "map" }); 29 | const tileset = map.addTilesetImage("kenney-tileset-64px-extruded"); 30 | const groundLayer = map.createLayer("Ground", tileset, 0, 0); 31 | const lavaLayer = map.createLayer("Lava", tileset, 0, 0); 32 | 33 | groundLayer.setCollisionByProperty({ collides: true }); 34 | lavaLayer.setCollisionByProperty({ collides: true }); 35 | 36 | this.matter.world.convertTilemapLayer(groundLayer); 37 | this.matter.world.convertTilemapLayer(lavaLayer); 38 | 39 | const image = this.matter.add.image(250, 50, "emoji", "1f92c", { 40 | restitution: 0, 41 | friction: 1, 42 | shape: "circle", 43 | }); 44 | 45 | this.matterCollision.addOnCollideStart({ 46 | objectA: image, 47 | callback: () => { 48 | this.matterCollision.removeOnCollideStart({ objectA: image }); 49 | this.restartCount += 1; 50 | this.scene.restart(); 51 | if (this.restartCount === 3) { 52 | passTest(); 53 | this.game.destroy(true); 54 | } 55 | }, 56 | }); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/slopes-plugin/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Phaser 3 Template 9 | 10 | 30 | 31 | 32 | 33 |
      34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/slopes-plugin/src/create-rotating-platform.js: -------------------------------------------------------------------------------- 1 | export default function createRotatingPlatform(scene, x, y, numTiles = 5) { 2 | // A TileSprite is a Sprite whose texture repeats to fill the given width and height. We can use 3 | // this with an image from our tileset to create a platform composed of tiles: 4 | const platform = scene.add.tileSprite(x, y, 64 * numTiles, 18, "wooden-plank"); 5 | 6 | scene.matter.add.gameObject(platform, { 7 | restitution: 0, // No bounciness 8 | frictionAir: 0, // Spin forever without slowing down from air resistance 9 | friction: 0.2, // A little extra friction so the player sticks better 10 | // Density sets the mass and inertia based on area - 0.001 is the default. We're going lower 11 | // here so that the platform tips/rotates easily 12 | density: 0.0005, 13 | }); 14 | 15 | // Alias the native Matter.js API 16 | const { Constraint } = Phaser.Physics.Matter.Matter; 17 | 18 | // Create a point constraint that pins the center of the platform to a fixed point in space, so 19 | // it can't move 20 | const constraint = Constraint.create({ 21 | pointA: { x: platform.x, y: platform.y }, 22 | bodyB: platform.body, 23 | length: 0, 24 | }); 25 | 26 | // We need to add the constraint to the Matter world to activate it 27 | scene.matter.world.add(constraint); 28 | 29 | // Give the platform a random initial tilt, as a hint to the player that these platforms rotate 30 | const sign = Math.random() < 0.5 ? -1 : 1; 31 | const angle = sign * Phaser.Math.Between(15, 25); 32 | platform.setAngle(angle); 33 | } 34 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/slopes-plugin/src/index.js: -------------------------------------------------------------------------------- 1 | import Phaser from "phaser"; 2 | import PhaserMatterCollisionPlugin from "../../../src"; 3 | import Slopes from "phaser-slopes"; 4 | import MainScene from "./main-scene.js"; 5 | 6 | const config = { 7 | type: Phaser.AUTO, 8 | width: 800, 9 | height: 600, 10 | backgroundColor: "#000c1f", 11 | parent: "game-container", 12 | pixelArt: true, 13 | scene: MainScene, 14 | physics: { 15 | default: "matter", 16 | matter: { 17 | debug: false, 18 | }, 19 | }, 20 | plugins: { 21 | scene: [ 22 | { 23 | key: "MatterCollisionPlugin", 24 | plugin: PhaserMatterCollisionPlugin, 25 | mapping: "matterCollision", 26 | }, 27 | { 28 | key: "Slopes", 29 | plugin: Slopes, 30 | mapping: "slopes", 31 | }, 32 | ], 33 | }, 34 | }; 35 | 36 | const game = new Phaser.Game(config); 37 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/slopes-plugin/src/main-scene.js: -------------------------------------------------------------------------------- 1 | /** 2 | * NOTE AN AUTOMATED TEST YET. This isn't exactly trimmed down, but this a platformer and tests it 3 | * against the phaser slopes plugin. 4 | */ 5 | 6 | import Phaser from "phaser"; 7 | import { startTest, failTest, passTest } from "../../test-utils"; 8 | import Player from "./player.js"; 9 | import createRotatingPlatform from "./create-rotating-platform.js"; 10 | 11 | export default class MainScene extends Phaser.Scene { 12 | preload() { 13 | this.load.tilemapTiledJSON("map", "../assets/tilemaps/level.json"); 14 | this.load.image( 15 | "kenney-tileset-64px-extruded", 16 | "../assets/tilesets/kenney-tileset-64px-extruded.png" 17 | ); 18 | 19 | this.load.image("wooden-plank", "../assets/images/wooden-plank.png"); 20 | this.load.image("block", "../assets/images/block.png"); 21 | 22 | this.load.spritesheet( 23 | "player", 24 | "../assets/spritesheets/0x72-industrial-player-32px-extruded.png", 25 | { 26 | frameWidth: 32, 27 | frameHeight: 32, 28 | margin: 1, 29 | spacing: 2, 30 | } 31 | ); 32 | 33 | this.load.atlas("emoji", "../assets/atlases/emoji.png", "../assets/atlases/emoji.json"); 34 | } 35 | 36 | create() { 37 | const map = this.make.tilemap({ key: "map" }); 38 | const tileset = map.addTilesetImage("kenney-tileset-64px-extruded"); 39 | const groundLayer = map.createLayer("Ground", tileset, 0, 0); 40 | const lavaLayer = map.createLayer("Lava", tileset, 0, 0); 41 | map.createLayer("Background", tileset, 0, 0); 42 | map.createLayer("Foreground", tileset, 0, 0).setDepth(10); 43 | 44 | // Set colliding tiles before converting the layer to Matter bodies 45 | groundLayer.setCollisionByProperty({ collides: true }); 46 | lavaLayer.setCollisionByProperty({ collides: true }); 47 | 48 | // Get the layers registered with Matter. Any colliding tiles will be given a Matter body. We 49 | // haven't mapped our collision shapes in Tiled so each colliding tile will get a default 50 | // rectangle body (similar to AP). 51 | this.matter.world.convertTilemapLayer(groundLayer); 52 | this.matter.world.convertTilemapLayer(lavaLayer); 53 | 54 | this.cameras.main.setBounds(0, 0, map.widthInPixels, map.heightInPixels); 55 | this.matter.world.setBounds(0, 0, map.widthInPixels, map.heightInPixels); 56 | 57 | // The spawn point is set using a point object inside of Tiled (within the "Spawn" object layer) 58 | const { x, y } = map.findObject("Spawn", (obj) => obj.name === "Spawn Point"); 59 | this.player = new Player(this, x, y); 60 | 61 | // Smoothly follow the player 62 | this.cameras.main.startFollow(this.player.sprite, false, 0.5, 0.5); 63 | 64 | this.unsubscribePlayerCollide = this.matterCollision.addOnCollideStart({ 65 | objectA: this.player.sprite, 66 | callback: this.onPlayerCollideStart, 67 | context: this, 68 | }); 69 | 70 | this.unsubscribePlayerCollide = this.matterCollision.addOnCollideEnd({ 71 | objectA: this.player.sprite, 72 | callback: this.onPlayerCollideEnd, 73 | context: this, 74 | }); 75 | 76 | // Load up some crates from the "Crates" object layer created in Tiled 77 | map.getObjectLayer("Crates").objects.forEach((crateObject) => { 78 | const { x, y, width, height } = crateObject; 79 | 80 | // Tiled origin for coordinate system is (0, 1), but we want (0.5, 0.5) 81 | this.matter.add 82 | .image(x + width / 2, y - height / 2, "block") 83 | .setBody({ shape: "rectangle", density: 0.001 }); 84 | }); 85 | 86 | // Create platforms at the point locations in the "Platform Locations" layer created in Tiled 87 | map.getObjectLayer("Platform Locations").objects.forEach((point) => { 88 | createRotatingPlatform(this, point.x, point.y); 89 | }); 90 | 91 | // Create a sensor at rectangle object created in Tiled (under the "Sensors" layer) 92 | const rect = map.findObject("Sensors", (obj) => obj.name === "Celebration"); 93 | const celebrateSensor = this.matter.add.rectangle( 94 | rect.x + rect.width / 2, 95 | rect.y + rect.height / 2, 96 | rect.width, 97 | rect.height, 98 | { 99 | isSensor: true, // It shouldn't physically interact with other bodies 100 | isStatic: true, // It shouldn't move 101 | } 102 | ); 103 | this.unsubscribeCelebrate = this.matterCollision.addOnCollideStart({ 104 | objectA: this.player.sprite, 105 | objectB: celebrateSensor, 106 | callback: this.onPlayerWin, 107 | context: this, 108 | }); 109 | 110 | const help = this.add.text(16, 16, "Arrows/WASD to move the player.", { 111 | fontSize: "18px", 112 | padding: { x: 10, y: 5 }, 113 | backgroundColor: "#ffffff", 114 | fill: "#000000", 115 | }); 116 | help.setScrollFactor(0).setDepth(1000); 117 | } 118 | 119 | onPlayerCollideStart({ gameObjectB }) { 120 | if (!gameObjectB || !(gameObjectB instanceof Phaser.Tilemaps.Tile)) return; 121 | 122 | const tile = gameObjectB; 123 | tile.alpha = 0.5; 124 | 125 | // Check the tile property set in Tiled (you could also just check the index if you aren't using 126 | // Tiled in your game) 127 | if (tile.properties.isLethal) { 128 | // Unsubscribe from collision events so that this logic is run only once 129 | this.unsubscribePlayerCollide(); 130 | 131 | this.player.freeze(); 132 | const cam = this.cameras.main; 133 | cam.fade(250, 0, 0, 0); 134 | cam.once("camerafadeoutcomplete", () => this.scene.restart()); 135 | } 136 | } 137 | 138 | onPlayerCollideEnd({ gameObjectB }) { 139 | if (!gameObjectB || !(gameObjectB instanceof Phaser.Tilemaps.Tile)) return; 140 | 141 | const tile = gameObjectB; 142 | tile.alpha = 1; 143 | } 144 | 145 | onPlayerWin() { 146 | // Celebrate only once 147 | this.unsubscribeCelebrate(); 148 | 149 | // Drop some heart-eye emojis, of course 150 | for (let i = 0; i < 35; i++) { 151 | const x = this.player.sprite.x + Phaser.Math.RND.integerInRange(-50, 50); 152 | const y = this.player.sprite.y - 150 + Phaser.Math.RND.integerInRange(-10, 10); 153 | this.matter.add 154 | .image(x, y, "emoji", "1f60d", { 155 | restitution: 1, 156 | friction: 0, 157 | density: 0.0001, 158 | shape: "circle", 159 | }) 160 | .setScale(0.5); 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/slopes-plugin/src/multi-key.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A small class to allow multiple Phaser keys to treated as one input. E.g. the left arrow and "A" 3 | * key can be wrapped up into one "input" so that we can check whether the player pressed either 4 | * button. 5 | */ 6 | export default class MultiKey { 7 | constructor(scene, keys) { 8 | if (!Array.isArray(keys)) keys = [keys]; 9 | this.keys = keys.map((key) => scene.input.keyboard.addKey(key)); 10 | } 11 | 12 | // Are any of the keys down? 13 | isDown() { 14 | return this.keys.some((key) => key.isDown); 15 | } 16 | 17 | // Are all of the keys up? 18 | isUp() { 19 | return this.keys.every((key) => key.isUp); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/slopes-plugin/src/player.js: -------------------------------------------------------------------------------- 1 | import MultiKey from "./multi-key.js"; 2 | 3 | export default class Player { 4 | constructor(scene, x, y) { 5 | this.scene = scene; 6 | 7 | // Create the animations we need from the player spritesheet 8 | const anims = scene.anims; 9 | anims.create({ 10 | key: "player-idle", 11 | frames: anims.generateFrameNumbers("player", { start: 0, end: 3 }), 12 | frameRate: 3, 13 | repeat: -1, 14 | }); 15 | anims.create({ 16 | key: "player-run", 17 | frames: anims.generateFrameNumbers("player", { start: 8, end: 15 }), 18 | frameRate: 12, 19 | repeat: -1, 20 | }); 21 | 22 | // Create the physics-based sprite that we will move around and animate 23 | this.sprite = scene.matter.add.sprite(0, 0, "player", 0); 24 | 25 | // The player's body is going to be a compound body that looks something like this: 26 | // 27 | // A = main body 28 | // 29 | // +---------+ 30 | // | | 31 | // +-+ +-+ 32 | // B = left | | | | C = right 33 | // wall sensor |B| A |C| wall sensor 34 | // | | | | 35 | // +-+ +-+ 36 | // | | 37 | // +-+-----+-+ 38 | // | D | 39 | // +-----+ 40 | // 41 | // D = ground sensor 42 | // 43 | // The main body is what collides with the world. The sensors are used to determine if the 44 | // player is blocked by a wall or standing on the ground. 45 | 46 | const { Body, Bodies } = Phaser.Physics.Matter.Matter; // Native Matter modules 47 | const { width: w, height: h } = this.sprite; 48 | const mainBody = Bodies.rectangle(0, 0, w * 0.6, h, { chamfer: { radius: 10 } }); 49 | this.sensors = { 50 | bottom: Bodies.rectangle(0, h * 0.5, w * 0.25, 2, { isSensor: true }), 51 | left: Bodies.rectangle(-w * 0.35, 0, 2, h * 0.5, { isSensor: true }), 52 | right: Bodies.rectangle(w * 0.35, 0, 2, h * 0.5, { isSensor: true }), 53 | }; 54 | const compoundBody = Body.create({ 55 | parts: [mainBody, this.sensors.bottom, this.sensors.left, this.sensors.right], 56 | frictionStatic: 0, 57 | frictionAir: 0.02, 58 | friction: 0.1, 59 | }); 60 | this.sprite 61 | .setExistingBody(compoundBody) 62 | .setScale(2) 63 | .setFixedRotation() // Sets inertia to infinity so the player can't rotate 64 | .setPosition(x, y); 65 | 66 | // Track which sensors are touching something 67 | this.isTouching = { left: false, right: false, ground: false }; 68 | 69 | // Jumping is going to have a cooldown 70 | this.canJump = true; 71 | this.jumpCooldownTimer = null; 72 | 73 | // Before matter's update, reset our record of which surfaces the player is touching. 74 | scene.matter.world.on("beforeupdate", this.resetTouching, this); 75 | 76 | scene.matterCollision.addOnCollideStart({ 77 | objectA: [this.sensors.bottom, this.sensors.left, this.sensors.right], 78 | callback: this.onSensorCollide, 79 | context: this, 80 | }); 81 | scene.matterCollision.addOnCollideActive({ 82 | objectA: [this.sensors.bottom, this.sensors.left, this.sensors.right], 83 | callback: this.onSensorCollide, 84 | context: this, 85 | }); 86 | 87 | // Track the keys 88 | const { LEFT, RIGHT, UP, A, D, W } = Phaser.Input.Keyboard.KeyCodes; 89 | this.leftInput = new MultiKey(scene, [LEFT, A]); 90 | this.rightInput = new MultiKey(scene, [RIGHT, D]); 91 | this.jumpInput = new MultiKey(scene, [UP, W]); 92 | 93 | this.destroyed = false; 94 | this.scene.events.on("update", this.update, this); 95 | this.scene.events.once("shutdown", this.destroy, this); 96 | this.scene.events.once("destroy", this.destroy, this); 97 | } 98 | 99 | onSensorCollide({ bodyA, bodyB, pair }) { 100 | // Watch for the player colliding with walls/objects on either side and the ground below, so 101 | // that we can use that logic inside of update to move the player. 102 | // Note: we are using the "pair.separation" here. That number tells us how much bodyA and bodyB 103 | // overlap. We want to teleport the sprite away from walls just enough so that the player won't 104 | // be able to press up against the wall and use friction to hang in midair. This formula leaves 105 | // 0.5px of overlap with the sensor so that the sensor will stay colliding on the next tick if 106 | // the player doesn't move. 107 | if (bodyB.isSensor) return; // We only care about collisions with physical objects 108 | if (bodyA === this.sensors.left) { 109 | this.isTouching.left = true; 110 | if (pair.separation > 0.5) this.sprite.x += pair.separation - 0.5; 111 | } else if (bodyA === this.sensors.right) { 112 | this.isTouching.right = true; 113 | if (pair.separation > 0.5) this.sprite.x -= pair.separation - 0.5; 114 | } else if (bodyA === this.sensors.bottom) { 115 | this.isTouching.ground = true; 116 | } 117 | } 118 | 119 | resetTouching() { 120 | this.isTouching.left = false; 121 | this.isTouching.right = false; 122 | this.isTouching.ground = false; 123 | } 124 | 125 | freeze() { 126 | this.sprite.setStatic(true); 127 | } 128 | 129 | update() { 130 | if (this.destroyed) return; 131 | 132 | const sprite = this.sprite; 133 | const velocity = sprite.body.velocity; 134 | const isRightKeyDown = this.rightInput.isDown(); 135 | const isLeftKeyDown = this.leftInput.isDown(); 136 | const isJumpKeyDown = this.jumpInput.isDown(); 137 | const isOnGround = this.isTouching.ground; 138 | const isInAir = !isOnGround; 139 | 140 | // --- Move the player horizontally --- 141 | 142 | // Adjust the movement so that the player is slower in the air 143 | const moveForce = isOnGround ? 0.01 : 0.005; 144 | 145 | if (isLeftKeyDown) { 146 | sprite.setFlipX(true); 147 | 148 | // Don't let the player push things left if they in the air 149 | if (!(isInAir && this.isTouching.left)) { 150 | sprite.applyForce({ x: -moveForce, y: 0 }); 151 | } 152 | } else if (isRightKeyDown) { 153 | sprite.setFlipX(false); 154 | 155 | // Don't let the player push things right if they in the air 156 | if (!(isInAir && this.isTouching.right)) { 157 | sprite.applyForce({ x: moveForce, y: 0 }); 158 | } 159 | } 160 | 161 | // Limit horizontal speed, without this the player's velocity would just keep increasing to 162 | // absurd speeds. We don't want to touch the vertical velocity though, so that we don't 163 | // interfere with gravity. 164 | if (velocity.x > 7) sprite.setVelocityX(7); 165 | else if (velocity.x < -7) sprite.setVelocityX(-7); 166 | 167 | // --- Move the player vertically --- 168 | 169 | if (isJumpKeyDown && this.canJump && isOnGround) { 170 | sprite.setVelocityY(-11); 171 | 172 | // Add a slight delay between jumps since the bottom sensor will still collide for a few 173 | // frames after a jump is initiated 174 | this.canJump = false; 175 | this.jumpCooldownTimer = this.scene.time.addEvent({ 176 | delay: 250, 177 | callback: () => (this.canJump = true), 178 | }); 179 | } 180 | 181 | // Update the animation/texture based on the state of the player's state 182 | if (isOnGround) { 183 | if (sprite.body.force.x !== 0) sprite.anims.play("player-run", true); 184 | else sprite.anims.play("player-idle", true); 185 | } else { 186 | sprite.anims.stop(); 187 | sprite.setTexture("player", 10); 188 | } 189 | } 190 | 191 | destroy() { 192 | // Clean up any listeners that might trigger events after the player is officially destroyed 193 | this.scene.events.off("update", this.update, this); 194 | this.scene.events.off("shutdown", this.destroy, this); 195 | this.scene.events.off("destroy", this.destroy, this); 196 | if (this.scene.matter.world) { 197 | this.scene.matter.world.off("beforeupdate", this.resetTouching, this); 198 | } 199 | const sensors = [this.sensors.bottom, this.sensors.left, this.sensors.right]; 200 | this.scene.matterCollision.removeOnCollideStart({ objectA: sensors }); 201 | this.scene.matterCollision.removeOnCollideActive({ objectA: sensors }); 202 | if (this.jumpCooldownTimer) this.jumpCooldownTimer.destroy(); 203 | 204 | this.destroyed = true; 205 | this.sprite.destroy(); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /workspaces/plugin/tests/test-utils.js: -------------------------------------------------------------------------------- 1 | export function startTest() { 2 | const htmlString = ` 3 |
      4 | Test status: 5 |
      Running...
      6 | 7 | 8 |
      9 | `.trim(); 10 | const range = document.createRange(); 11 | range.selectNode(document.body); 12 | const documentFragment = range.createContextualFragment(htmlString); 13 | document.body.appendChild(documentFragment); 14 | } 15 | 16 | export function passTest() { 17 | document.querySelector(".test-running").style.display = "none"; 18 | document.querySelector(".test-pass").style.display = "initial"; 19 | document.querySelector(".test-fail").style.display = "none"; 20 | } 21 | export function failTest() { 22 | document.querySelector(".test-running").style.display = "none"; 23 | document.querySelector(".test-pass").style.display = "none"; 24 | document.querySelector(".test-fail").style.display = "initial"; 25 | } 26 | -------------------------------------------------------------------------------- /workspaces/plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "declaration": true, 5 | "target": "es6", 6 | "strict": true, 7 | "strictPropertyInitialization": false, 8 | "module": "es6", 9 | "moduleResolution": "node", 10 | "sourceMap": true, 11 | "allowSyntheticDefaultImports": true, // Necessary for default importing Phaser to pick up types properly 12 | "allowJs": true, 13 | "checkJs": false, 14 | "lib": ["dom", "esnext", "scripthost"] 15 | }, 16 | "include": ["src/**/*"] 17 | } -------------------------------------------------------------------------------- /workspaces/plugin/typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "entryPoints": [ 3 | "src/index.ts" 4 | ], 5 | "out": "docs", 6 | "name": "Phaser Matter Collision Plugin", 7 | "includeVersion": true, 8 | "readme": "./README.md", 9 | "theme": "./doc-theme", 10 | "sort": [ 11 | "visibility", 12 | "alphabetical" 13 | ], 14 | "hideGenerator": true 15 | } -------------------------------------------------------------------------------- /workspaces/plugin/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | 3 | const path = require("path"); 4 | const root = __dirname; 5 | 6 | module.exports = function (env, argv) { 7 | const isDev = argv.mode === "development"; 8 | 9 | return { 10 | context: path.join(root, "src"), 11 | entry: "./index.ts", 12 | output: { 13 | library: { 14 | name: "PhaserMatterCollisionPlugin", 15 | type: "umd", 16 | }, 17 | filename: "phaser-matter-collision.js", 18 | path: path.resolve(root, "dist"), 19 | globalObject: '(typeof self !== "undefined" ? self : this)', 20 | clean: true, 21 | }, 22 | externals: { 23 | phaser: { 24 | root: "Phaser", 25 | commonjs: "phaser", 26 | commonjs2: "phaser", 27 | amd: "phaser", 28 | }, 29 | }, 30 | module: { 31 | rules: [ 32 | { test: /\.(ts|tsx)$/, use: "ts-loader", exclude: /node_modules/ }, 33 | { 34 | test: /\.js$/, 35 | exclude: /node_modules/, 36 | use: ["babel-loader"], 37 | }, 38 | ], 39 | }, 40 | resolve: { 41 | extensions: [".tsx", ".ts", ".js"], 42 | }, 43 | devtool: isDev ? "eval-source-map" : "source-map", 44 | }; 45 | }; 46 | -------------------------------------------------------------------------------- /workspaces/plugin/webpack.test.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | 3 | const path = require("path"); 4 | const { readdirSync, statSync } = require("fs"); 5 | 6 | const root = __dirname; 7 | const dirs = (p) => readdirSync(p).filter((f) => statSync(path.join(p, f)).isDirectory()); 8 | 9 | // Configure the entry with appropriate keys and values to multi-compile all tests/*/src/index.js to 10 | // tests/*/build/index.js 11 | const entry = {}; 12 | dirs(path.join(root, "tests")) 13 | .filter((folder) => folder !== "assets") 14 | .forEach((folder) => { 15 | // Key is the path from output path ("tests") to where the HTML & JS should go, e.g. for a path 16 | // of "./tests/sample-test/src/index.js", it should be "sample-test/index" 17 | const key = `${folder}/build/index`; 18 | entry[key] = `./tests/${folder}/src/index.js`; 19 | }); 20 | 21 | module.exports = function (env, argv) { 22 | const isDev = argv.mode === "development"; 23 | 24 | return { 25 | entry, 26 | output: { 27 | path: path.resolve(root, "tests"), 28 | filename: "[name].js", 29 | }, 30 | module: { 31 | rules: [ 32 | { test: /\.(ts|tsx)$/, use: "ts-loader", exclude: /node_modules/ }, 33 | { 34 | test: /\.js$/, 35 | exclude: /node_modules/, 36 | use: ["babel-loader"], 37 | }, 38 | ], 39 | }, 40 | resolve: { 41 | extensions: [".tsx", ".ts", ".js"], 42 | }, 43 | optimization: { 44 | minimize: false, 45 | }, 46 | devtool: isDev ? "eval-source-map" : "source-map", 47 | }; 48 | }; 49 | -------------------------------------------------------------------------------- /workspaces/typescript-example/.gitignore: -------------------------------------------------------------------------------- 1 | dist -------------------------------------------------------------------------------- /workspaces/typescript-example/README.md: -------------------------------------------------------------------------------- 1 | # TypeScript Example for using Phaser Matter Collision Plugin 2 | 3 | This is a TypeScript example project that makes use of the Phaser Matter Collision Plugin. It uses a webpack-based build system. 4 | 5 | Note: 6 | - If you are trying to copy this project and use it outside of this repository, you'll need to modify `package.json`. Yarn workspaces express dependencies like this `"phaser-matter-collision-plugin": "workspace:*"`, so you'll need to replace that with a version number. -------------------------------------------------------------------------------- /workspaces/typescript-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-example", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "start": "webpack server --mode development --open", 7 | "tsc": "tsc" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "copy-webpack-plugin": "^9.0.0", 13 | "html-webpack-plugin": "^5.3.2", 14 | "ts-loader": "^9.2.1", 15 | "typescript": "^4.2.4", 16 | "webpack": "^5.37.1", 17 | "webpack-cli": "^4.7.0", 18 | "webpack-dev-server": "^3.11.2" 19 | }, 20 | "description": "", 21 | "dependencies": { 22 | "phaser": "^3.55.2", 23 | "phaser-matter-collision-plugin": "workspace:*" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji.json: -------------------------------------------------------------------------------- 1 | {"frames": { 2 | 3 | "1f4a9": 4 | { 5 | "frame": {"x":297,"y":1,"w":72,"h":72}, 6 | "rotated": false, 7 | "trimmed": false, 8 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 9 | "sourceSize": {"w":72,"h":72} 10 | }, 11 | "1f31a": 12 | { 13 | "frame": {"x":1,"y":1,"w":72,"h":72}, 14 | "rotated": false, 15 | "trimmed": false, 16 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 17 | "sourceSize": {"w":72,"h":72} 18 | }, 19 | "1f31d": 20 | { 21 | "frame": {"x":75,"y":1,"w":72,"h":72}, 22 | "rotated": false, 23 | "trimmed": false, 24 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 25 | "sourceSize": {"w":72,"h":72} 26 | }, 27 | "1f31e": 28 | { 29 | "frame": {"x":149,"y":1,"w":72,"h":72}, 30 | "rotated": false, 31 | "trimmed": false, 32 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 33 | "sourceSize": {"w":72,"h":72} 34 | }, 35 | "1f47d": 36 | { 37 | "frame": {"x":1628,"y":1,"w":70,"h":72}, 38 | "rotated": false, 39 | "trimmed": true, 40 | "spriteSourceSize": {"x":1,"y":0,"w":70,"h":72}, 41 | "sourceSize": {"w":72,"h":72} 42 | }, 43 | "1f47f": 44 | { 45 | "frame": {"x":223,"y":1,"w":72,"h":72}, 46 | "rotated": false, 47 | "trimmed": false, 48 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 49 | "sourceSize": {"w":72,"h":72} 50 | }, 51 | "1f60d": 52 | { 53 | "frame": {"x":445,"y":1,"w":72,"h":72}, 54 | "rotated": false, 55 | "trimmed": false, 56 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 57 | "sourceSize": {"w":72,"h":72} 58 | }, 59 | "1f61c": 60 | { 61 | "frame": {"x":519,"y":1,"w":72,"h":72}, 62 | "rotated": false, 63 | "trimmed": false, 64 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 65 | "sourceSize": {"w":72,"h":72} 66 | }, 67 | "1f62c": 68 | { 69 | "frame": {"x":667,"y":1,"w":72,"h":72}, 70 | "rotated": false, 71 | "trimmed": false, 72 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 73 | "sourceSize": {"w":72,"h":72} 74 | }, 75 | "1f62d": 76 | { 77 | "frame": {"x":741,"y":1,"w":72,"h":72}, 78 | "rotated": false, 79 | "trimmed": false, 80 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 81 | "sourceSize": {"w":72,"h":72} 82 | }, 83 | "1f62e": 84 | { 85 | "frame": {"x":815,"y":1,"w":72,"h":72}, 86 | "rotated": false, 87 | "trimmed": false, 88 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 89 | "sourceSize": {"w":72,"h":72} 90 | }, 91 | "1f92a": 92 | { 93 | "frame": {"x":1259,"y":1,"w":72,"h":72}, 94 | "rotated": false, 95 | "trimmed": false, 96 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 97 | "sourceSize": {"w":72,"h":72} 98 | }, 99 | "1f92c": 100 | { 101 | "frame": {"x":1333,"y":1,"w":72,"h":72}, 102 | "rotated": false, 103 | "trimmed": false, 104 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 105 | "sourceSize": {"w":72,"h":72} 106 | }, 107 | "1f92e": 108 | { 109 | "frame": {"x":1700,"y":1,"w":70,"h":72}, 110 | "rotated": false, 111 | "trimmed": true, 112 | "spriteSourceSize": {"x":1,"y":0,"w":70,"h":72}, 113 | "sourceSize": {"w":72,"h":72} 114 | }, 115 | "1f92f": 116 | { 117 | "frame": {"x":1555,"y":1,"w":71,"h":72}, 118 | "rotated": false, 119 | "trimmed": true, 120 | "spriteSourceSize": {"x":0,"y":0,"w":71,"h":72}, 121 | "sourceSize": {"w":72,"h":72} 122 | }, 123 | "1f608": 124 | { 125 | "frame": {"x":371,"y":1,"w":72,"h":72}, 126 | "rotated": false, 127 | "trimmed": false, 128 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 129 | "sourceSize": {"w":72,"h":72} 130 | }, 131 | "1f621": 132 | { 133 | "frame": {"x":593,"y":1,"w":72,"h":72}, 134 | "rotated": false, 135 | "trimmed": false, 136 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 137 | "sourceSize": {"w":72,"h":72} 138 | }, 139 | "1f631": 140 | { 141 | "frame": {"x":889,"y":1,"w":72,"h":72}, 142 | "rotated": false, 143 | "trimmed": false, 144 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 145 | "sourceSize": {"w":72,"h":72} 146 | }, 147 | "1f912": 148 | { 149 | "frame": {"x":963,"y":1,"w":72,"h":72}, 150 | "rotated": false, 151 | "trimmed": false, 152 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 153 | "sourceSize": {"w":72,"h":72} 154 | }, 155 | "1f913": 156 | { 157 | "frame": {"x":1037,"y":1,"w":72,"h":72}, 158 | "rotated": false, 159 | "trimmed": false, 160 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 161 | "sourceSize": {"w":72,"h":72} 162 | }, 163 | "1f915": 164 | { 165 | "frame": {"x":1111,"y":1,"w":72,"h":72}, 166 | "rotated": false, 167 | "trimmed": false, 168 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 169 | "sourceSize": {"w":72,"h":72} 170 | }, 171 | "1f922": 172 | { 173 | "frame": {"x":1185,"y":1,"w":72,"h":72}, 174 | "rotated": false, 175 | "trimmed": false, 176 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 177 | "sourceSize": {"w":72,"h":72} 178 | }, 179 | "1f975": 180 | { 181 | "frame": {"x":1407,"y":1,"w":72,"h":72}, 182 | "rotated": false, 183 | "trimmed": false, 184 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 185 | "sourceSize": {"w":72,"h":72} 186 | }, 187 | "1f976": 188 | { 189 | "frame": {"x":1481,"y":1,"w":72,"h":72}, 190 | "rotated": false, 191 | "trimmed": false, 192 | "spriteSourceSize": {"x":0,"y":0,"w":72,"h":72}, 193 | "sourceSize": {"w":72,"h":72} 194 | }}, 195 | "meta": { 196 | "app": "http://www.codeandweb.com/texturepacker", 197 | "version": "1.0", 198 | "image": "emoji.png", 199 | "format": "RGBA8888", 200 | "size": {"w":1771,"h":74}, 201 | "scale": "1", 202 | "smartupdate": "$TexturePacker:SmartUpdate:80919c52b607def3c7f647a71f5d2f19:8df71fe38bb708a3bec8b99fc4709ddb:3b6ee1b3efdb705ed941d972d580542a$" 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f31a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f31a.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f31d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f31d.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f31e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f31e.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f47d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f47d.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f47f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f47f.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f4a9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f4a9.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f608.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f608.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f60d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f60d.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f61c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f61c.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f621.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f621.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f62c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f62c.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f62d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f62d.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f62e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f62e.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f631.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f631.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f912.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f912.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f913.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f913.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f915.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f915.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f922.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f922.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f92a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f92a.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f92c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f92c.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f92e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f92e.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f92f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f92f.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f975.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f975.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/atlases/emoji/1f976.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/atlases/emoji/1f976.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/tilesets/kenney-tileset-64px-extruded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/tilesets/kenney-tileset-64px-extruded.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/assets/tilesets/kenney-tileset-64px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikewesthad/phaser-matter-collision-plugin/b20971a95a5278b097ea558d790ce3970fde4a1e/workspaces/typescript-example/src/assets/tilesets/kenney-tileset-64px.png -------------------------------------------------------------------------------- /workspaces/typescript-example/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Phaser Template 8 | 9 | 29 | 30 | 31 | 32 |
      33 | 34 | 35 | -------------------------------------------------------------------------------- /workspaces/typescript-example/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: Michael Hadley, mikewesthad.com 3 | * Asset Credits: 4 | * - Twemoji, https://github.com/twitter/twemoji, CC-BY 4.0 5 | * - Tilesets by Kenney, https://www.kenney.nl/assets/platformer-art-pixel-redux and 6 | * https://www.kenney.nl/assets/abstract-platformer, public domain 7 | */ 8 | 9 | import Phaser, { Game } from "phaser"; 10 | import MainScene from "./main-scene"; 11 | import PhaserMatterCollisionPlugin from "phaser-matter-collision-plugin"; 12 | 13 | const pluginConfig = { 14 | // The plugin class: 15 | plugin: PhaserMatterCollisionPlugin, 16 | // Where to store in Scene.Systems, e.g. scene.sys.matterCollision: 17 | key: "matterCollision" as "matterCollision", 18 | // Where to store in the Scene, e.g. scene.matterCollision: 19 | mapping: "matterCollision" as "matterCollision", 20 | }; 21 | 22 | declare module "phaser" { 23 | interface Scene { 24 | [pluginConfig.mapping]: PhaserMatterCollisionPlugin; 25 | } 26 | namespace Scenes { 27 | interface Systems { 28 | [pluginConfig.key]: PhaserMatterCollisionPlugin; 29 | } 30 | } 31 | } 32 | 33 | const config = { 34 | type: Phaser.AUTO, 35 | width: 800, 36 | height: 600, 37 | backgroundColor: "#000c1f", 38 | parent: "game-container", 39 | scene: MainScene, 40 | physics: { default: "matter" }, 41 | plugins: { 42 | scene: [pluginConfig], 43 | }, 44 | }; 45 | 46 | const game = new Game(config); 47 | -------------------------------------------------------------------------------- /workspaces/typescript-example/src/main-scene.ts: -------------------------------------------------------------------------------- 1 | import Phaser, { Physics, Scene, Cameras, Tilemaps, Types, Input, GameObjects } from "phaser"; 2 | 3 | export default class MainScene extends Scene { 4 | private controls: Cameras.Controls.FixedKeyControl; 5 | 6 | preload() { 7 | this.load.tilemapTiledJSON("map", "../assets/tilemaps/level.json"); 8 | this.load.image( 9 | "kenney-tileset-64px-extruded", 10 | "../assets/tilesets/kenney-tileset-64px-extruded.png" 11 | ); 12 | this.load.atlas("emoji", "../assets/atlases/emoji.png", "../assets/atlases/emoji.json"); 13 | } 14 | 15 | create() { 16 | const map = this.make.tilemap({ key: "map" }); 17 | const tileset = map.addTilesetImage("kenney-tileset-64px-extruded"); 18 | const groundLayer = map.createLayer("Ground", tileset, 0, 0); 19 | const lavaLayer = map.createLayer("Lava", tileset, 0, 0); 20 | 21 | // Set colliding tiles *before* converting the layer to Matter bodies. 22 | groundLayer.setCollisionByProperty({ collides: true }); 23 | lavaLayer.setCollisionByProperty({ collides: true }); 24 | this.matter.world.convertTilemapLayer(groundLayer); 25 | this.matter.world.convertTilemapLayer(lavaLayer); 26 | 27 | // Set up the bounds. 28 | this.matter.world.setBounds(0, 0, map.widthInPixels, map.heightInPixels); 29 | this.cameras.main.setBounds(0, 0, map.widthInPixels, map.heightInPixels); 30 | 31 | // Create two simple animations - one angry => grimace emoji and one heart eyes => grimace 32 | this.anims.create({ 33 | key: "angry", 34 | frames: [ 35 | { key: "emoji", frame: "1f92c" }, 36 | { key: "emoji", frame: "1f62c" }, 37 | ], 38 | frameRate: 3, 39 | repeat: 0, 40 | }); 41 | this.anims.create({ 42 | key: "love", 43 | frames: [ 44 | { key: "emoji", frame: "1f60d" }, 45 | { key: "emoji", frame: "1f62c" }, 46 | ], 47 | frameRate: 3, 48 | repeat: 0, 49 | }); 50 | 51 | // Create some Matter-enabled physics game objects. 52 | const bodyOptions = { restitution: 1, friction: 0, shape: "circle" }; 53 | const emoji1 = this.matter.add.sprite(350, 100, "emoji", "1f62c", bodyOptions); 54 | const emoji2 = this.matter.add.sprite(350, 275, "emoji", "1f62c", bodyOptions); 55 | const emoji3 = this.matter.add.image(350, 350, "emoji", "1f4a9", bodyOptions); 56 | 57 | // Only listen for collisions between emoji 1 & 2 - make them love-hate when they start 58 | // colliding or continue colliding 59 | this.matterCollision.addOnCollideStart({ 60 | objectA: emoji1, 61 | objectB: emoji2, 62 | callback: ({ gameObjectA, gameObjectB }) => { 63 | // These fields *can* be undefined depending on the inputs, so use the non-null assertion 64 | // operator when we know more than the type system. 65 | gameObjectA!.play("angry", false); // gameObjectA will always match the given "objectA" 66 | gameObjectB!.play("love", false); // gameObjectB will always match the given "objectB" 67 | }, 68 | }); 69 | 70 | this.matterCollision.addOnCollideActive({ 71 | objectA: emoji1, 72 | objectB: emoji2, 73 | callback: ({ gameObjectA, gameObjectB }) => { 74 | gameObjectA!.play("angry", false); 75 | gameObjectB!.play("love", false); 76 | }, 77 | }); 78 | 79 | // Kill poop emoji on collision with lava. 80 | const unsubscribe = this.matterCollision.addOnCollideStart({ 81 | objectA: emoji3, 82 | callback: ({ gameObjectB }) => { 83 | if (!gameObjectB || !(gameObjectB instanceof Phaser.Tilemaps.Tile)) return; 84 | if (gameObjectB.index === 290) { 85 | emoji3.destroy(); 86 | unsubscribe(); 87 | } 88 | }, 89 | }); 90 | 91 | // Make the emoji draggable 92 | emoji1.setInteractive(); 93 | emoji2.setInteractive(); 94 | emoji3.setInteractive(); 95 | this.input.setDraggable(emoji1); 96 | this.input.setDraggable(emoji2); 97 | this.input.setDraggable(emoji3); 98 | this.input.on( 99 | "drag", 100 | (pointer: Input.Pointer, gameObject: Physics.Matter.Sprite, x: number, y: number) => 101 | gameObject.setPosition(x, y) 102 | ); 103 | this.input.on("dragstart", (pointer: Input.Pointer, gameObject: Physics.Matter.Sprite) => 104 | gameObject.setStatic(true) 105 | ); 106 | this.input.on("dragend", (pointer: Input.Pointer, gameObject: Physics.Matter.Sprite) => 107 | gameObject.setStatic(false) 108 | ); 109 | 110 | Phaser.Input.Events.DRAG; 111 | const text = "Click and drag the emoji.\nArrow keys to move the camera."; 112 | const help = this.add.text(16, 16, text, { 113 | fontSize: "18px", 114 | padding: { x: 10, y: 5 }, 115 | backgroundColor: "#ffffff", 116 | color: "#000000", 117 | }); 118 | help.setScrollFactor(0).setDepth(1000); 119 | 120 | const cursors = this.input.keyboard.createCursorKeys(); 121 | const controlConfig = { 122 | camera: this.cameras.main, 123 | left: cursors.left, 124 | right: cursors.right, 125 | up: cursors.up, 126 | down: cursors.down, 127 | speed: 0.5, 128 | }; 129 | this.controls = new Phaser.Cameras.Controls.FixedKeyControl(controlConfig); 130 | 131 | this.cameras.main.scrollX = 100; 132 | this.cameras.main.scrollY = 100; 133 | } 134 | 135 | update(time: number, delta: number) { 136 | this.controls.update(delta); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /workspaces/typescript-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "strict": true, 5 | "strictPropertyInitialization": false, 6 | "noImplicitAny": true, 7 | "module": "es6", 8 | "target": "es5", 9 | "moduleResolution": "node", 10 | "sourceMap": true, 11 | "allowSyntheticDefaultImports": true, // Necessary for default importing Phaser to pick up types properly 12 | "allowJs": true, 13 | "checkJs": false, 14 | "lib": ["dom", "esnext", "scripthost"], 15 | }, 16 | "include": ["src/**/*"] 17 | } -------------------------------------------------------------------------------- /workspaces/typescript-example/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | 3 | const webpack = require("webpack"); 4 | const path = require("path"); 5 | const root = path.resolve(__dirname); 6 | const HTMLWebpackPlugin = require("html-webpack-plugin"); 7 | const CopyWebpackPlugin = require("copy-webpack-plugin"); 8 | 9 | module.exports = function (env, argv) { 10 | const isDev = argv.mode === "development"; 11 | 12 | return { 13 | context: path.join(root, "src"), 14 | entry: "./index.ts", 15 | output: { 16 | filename: "index.js", 17 | path: path.resolve(__dirname, "dist"), 18 | }, 19 | module: { 20 | rules: [{ test: /\.(ts|tsx)$/, use: "ts-loader", exclude: /node_modules/ }], 21 | }, 22 | resolve: { 23 | extensions: [".tsx", ".ts", ".js"], 24 | }, 25 | plugins: [ 26 | new HTMLWebpackPlugin({ template: "./index.html" }), 27 | new CopyWebpackPlugin({ 28 | patterns: [{ from: "assets", to: "assets" }], 29 | }), 30 | new webpack.DefinePlugin({ 31 | "typeof CANVAS_RENDERER": JSON.stringify(true), 32 | "typeof WEBGL_RENDERER": JSON.stringify(true), 33 | PRODUCTION: !isDev, 34 | }), 35 | ], 36 | devtool: isDev ? "eval-source-map" : "source-map", 37 | }; 38 | }; 39 | --------------------------------------------------------------------------------