├── .eslintignore
├── assets
├── fonts
│ ├── font.png
│ └── font.xml
├── sounds
│ ├── button.m4a
│ ├── button.mp3
│ └── button.ogg
└── sprites
│ └── mushroom.png
├── babel.config.js
├── .editorconfig
├── src
├── config.ts
├── prefabs
│ └── mushroom.ts
├── helpers
│ └── sound.ts
├── app.ts
└── states
│ ├── preload.ts
│ ├── game.ts
│ └── boot.ts
├── .gitignore
├── tsconfig.json
├── .eslintrc.json
├── index.html
├── package.json
├── webpack.dev.config.js
├── README.md
└── webpack.prod.config.js
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | assets
4 | webpack.*
5 | babel.*
6 |
--------------------------------------------------------------------------------
/assets/fonts/font.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/numbofathma/phaser-typescript-webpack/HEAD/assets/fonts/font.png
--------------------------------------------------------------------------------
/assets/sounds/button.m4a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/numbofathma/phaser-typescript-webpack/HEAD/assets/sounds/button.m4a
--------------------------------------------------------------------------------
/assets/sounds/button.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/numbofathma/phaser-typescript-webpack/HEAD/assets/sounds/button.mp3
--------------------------------------------------------------------------------
/assets/sounds/button.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/numbofathma/phaser-typescript-webpack/HEAD/assets/sounds/button.ogg
--------------------------------------------------------------------------------
/assets/sprites/mushroom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/numbofathma/phaser-typescript-webpack/HEAD/assets/sprites/mushroom.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ["@babel/preset-typescript"],
3 | plugins: [
4 | ["@babel/plugin-proposal-class-properties"],
5 | ["@babel/plugin-transform-typescript"],
6 | ],
7 | };
8 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | charset = utf-8
6 | trim_trailing_whitespace = true
7 | insert_final_newline = true
8 | indent_style = spaces
9 | indent_size = 2
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/src/config.ts:
--------------------------------------------------------------------------------
1 | import Phaser from 'phaser-ce';
2 |
3 | export class Config {
4 | static gameWidth: number = 800;
5 |
6 | static gameHeight: number = 480;
7 |
8 | static enableDebug = false;
9 |
10 | static renderer = Phaser.CANVAS;
11 | }
12 |
--------------------------------------------------------------------------------
/src/prefabs/mushroom.ts:
--------------------------------------------------------------------------------
1 | import Phaser from 'phaser-ce';
2 |
3 | export class Mushroom extends Phaser.Sprite {
4 | constructor(game: Phaser.Game, x: number, y: number) {
5 | super(game, x, y, 'mushroom');
6 |
7 | this.anchor.setTo(0.5);
8 | this.game.physics.arcade.enableBody(this);
9 | this.checkWorldBounds = true;
10 | this.body.collideWorldBounds = true;
11 | }
12 |
13 | update() {
14 | this.angle += 1;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_STORE
2 | .next
3 | node_modules
4 | scripts/flow/*/.flowconfig
5 | *~
6 | *.pyc
7 | .grunt
8 | _SpecRunner.html
9 | __benchmarks__
10 | build/
11 | remote-repo/
12 | coverage/
13 | .module-cache
14 | fixtures/dom/public/react-dom.js
15 | fixtures/dom/public/react.js
16 | test/the-files-to-test.generated.js
17 | *.log*
18 | chrome-user-data
19 | *.sublime-project
20 | *.sublime-workspace
21 | .idea
22 | *.iml
23 | .vscode
24 | *.swp
25 | *.swo
26 | /dist
--------------------------------------------------------------------------------
/src/helpers/sound.ts:
--------------------------------------------------------------------------------
1 | import { Howl } from 'howler';
2 |
3 | const createHowler: any = (
4 | src: string[],
5 | preload: boolean = false,
6 | ) => {
7 | const sound: any = new Howl({
8 | src,
9 | preload,
10 | volume: 1,
11 | onload: () => {
12 | sound.loaded = true;
13 | },
14 | });
15 |
16 | return sound;
17 | };
18 |
19 | export const Sound: any = createHowler([
20 | 'assets/sounds/button.m4a',
21 | 'assets/sounds/button.mp3',
22 | 'assets/sounds/button.ogg',
23 | ]);
24 |
--------------------------------------------------------------------------------
/src/app.ts:
--------------------------------------------------------------------------------
1 | import Phaser from 'phaser-ce';
2 |
3 | import { Config } from './config';
4 |
5 | import { Boot } from './states/boot';
6 | import { Preload } from './states/preload';
7 | import { Game } from './states/game';
8 |
9 | class Template extends Phaser.Game {
10 | constructor() {
11 | const config = {
12 | width: Config.gameWidth,
13 | height: Config.gameHeight,
14 | renderer: Config.renderer,
15 | parent: 'content',
16 | state: null,
17 | enableDebug: Config.enableDebug,
18 | };
19 |
20 | super(config);
21 |
22 | this.state.add('Boot', Boot, false);
23 | this.state.add('Preload', Preload, false);
24 | this.state.add('Game', Game, false);
25 |
26 | this.state.start('Boot');
27 | }
28 | }
29 |
30 | window.onload = () => new Template();
31 |
--------------------------------------------------------------------------------
/src/states/preload.ts:
--------------------------------------------------------------------------------
1 | import Phaser from 'phaser-ce';
2 | import { Sound } from '../helpers/sound';
3 |
4 | export class Preload extends Phaser.State {
5 | private ready: boolean;
6 |
7 | public preload(): void {
8 | // Load awesome fonts
9 | this.game.load.bitmapFont('font', 'assets/fonts/font.png', 'assets/fonts/font.xml');
10 |
11 | // Load sprite
12 | this.game.load.image('mushroom', 'assets/sprites/mushroom.png');
13 |
14 | // Initialize Howler
15 | Sound.load();
16 |
17 | this.load.onLoadComplete.addOnce(this.onLoadComplete, this);
18 | }
19 |
20 | public update(): void {
21 | if ((this.ready === true) && (Sound.loaded === true)) {
22 | this.game.state.start('Game');
23 | }
24 | }
25 |
26 | private onLoadComplete(): void {
27 | this.ready = true;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "strict": true,
4 | "allowSyntheticDefaultImports": true,
5 | "declaration": false,
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "strictPropertyInitialization": false,
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "noEmit": false,
13 | "esModuleInterop": true,
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "lib": [
17 | "dom",
18 | "es2015",
19 | "es2016",
20 | "esnext"
21 | ],
22 | "module": "esnext",
23 | "moduleResolution": "node",
24 | "sourceMap": false,
25 | "target": "es5",
26 | "typeRoots": [
27 | "node_modules/@types",
28 | "node_modules/phaser-ce/typescript/phaser.d.ts",
29 | "node_modules/phaser-ce/typescript/pixi.d.ts",
30 | "node_modules/phaser-ce/typescript/p2.d.ts"
31 | ],
32 | "outDir": "dist"
33 | },
34 | "include": [
35 | "src/**/*.ts"
36 | ],
37 | "exclude": [
38 | "node_modules",
39 | "src/**/*.spec.ts",
40 | "src/**/__tests__/*.ts"
41 | ],
42 | "compileOnSave": false,
43 | "atom": {
44 | "rewriteTsconfig": false
45 | }
46 | }
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true
5 | },
6 | "extends": [
7 | "airbnb-base"
8 | ],
9 | "globals": {
10 | "Atomics": "readonly",
11 | "SharedArrayBuffer": "readonly"
12 | },
13 | "parser": "@typescript-eslint/parser",
14 | "parserOptions": {
15 | "project": "./tsconfig.json",
16 | "ecmaVersion": 2023,
17 | "sourceType": "module"
18 | },
19 | "plugins": [
20 | "@typescript-eslint"
21 | ],
22 | "settings": {
23 | "import/resolver": {
24 | "node": {
25 | "extensions": [
26 | ".ts",
27 | ".js"
28 | ]
29 | }
30 | }
31 | },
32 | "rules": {
33 | "@typescript-eslint/explicit-function-return-type": "off",
34 | "@typescript-eslint/no-unused-vars": "error",
35 | "no-continue": "off",
36 | "no-plusplus": "off",
37 | "no-bitwise": "off",
38 | "class-methods-use-this": "warn",
39 | "import/extensions": [
40 | "error",
41 | "ignorePackages",
42 | {
43 | "js": "never",
44 | "jsx": "never",
45 | "ts": "never",
46 | "tsx": "never"
47 | }
48 | ],
49 | "import/prefer-default-export": "off",
50 | "max-len": [
51 | "warn",
52 | {
53 | "code": 160,
54 | "ignoreStrings": true,
55 | "ignoreTemplateLiterals": true,
56 | "ignoreComments": true
57 | }
58 | ],
59 | "no-nested-ternary": "off"
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Template
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/src/states/game.ts:
--------------------------------------------------------------------------------
1 | import Phaser from 'phaser-ce';
2 | import { Sound } from '../helpers/sound';
3 | import { Mushroom } from '../prefabs/mushroom';
4 |
5 | export class Game extends Phaser.State {
6 | private mushroom: Mushroom;
7 |
8 | private cursors: Phaser.CursorKeys;
9 |
10 | private text: Phaser.BitmapText;
11 |
12 | private spaceKey: Phaser.Key;
13 |
14 | public create(): void {
15 | this.game.physics.startSystem(Phaser.Physics.ARCADE);
16 |
17 | this.text = this.game.add.bitmapText(this.game.world.centerX, this.game.world.centerY + 100, 'font', 'Press Arrows / Space', 15);
18 | this.text.x -= ~~(this.text.width * 0.5);
19 |
20 | this.mushroom = new Mushroom(this.state.getCurrentState().game, this.game.world.centerX, this.game.world.centerY);
21 | this.game.add.existing(this.mushroom);
22 |
23 | this.cursors = this.game.input.keyboard.createCursorKeys();
24 |
25 | this.spaceKey = this.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
26 | this.spaceKey.onDown.add(() => {
27 | Sound.play();
28 | this.mushroom.x = this.game.world.centerX;
29 | this.mushroom.y = this.game.world.centerY;
30 | }, this);
31 | }
32 |
33 | public update(): void {
34 | this.game.input.update();
35 |
36 | if (this.cursors.down.isDown) {
37 | this.mushroom.position.y++;
38 | }
39 | if (this.cursors.up.isDown) {
40 | this.mushroom.position.y--;
41 | }
42 | if (this.cursors.left.isDown) {
43 | this.mushroom.position.x--;
44 | }
45 | if (this.cursors.right.isDown) {
46 | this.mushroom.position.x++;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "phaser-typescript-webpack",
3 | "version": "1.1.2",
4 | "description": "A good place to get started with Phaser and TypeScript development",
5 | "scripts": {
6 | "start": "webpack serve --config webpack.dev.config.js --mode development --progress",
7 | "build": "npm run check && npm run transpile",
8 | "transpile": "rimraf ./dist && webpack --config webpack.prod.config.js --mode production --progress",
9 | "tsc": "tsc --noemit --project tsconfig.json",
10 | "lint": "eslint --ext .js,.ts src --color",
11 | "lint:fix": "eslint --fix --ext .js,.ts src --color",
12 | "check": "npm run lint && npm run tsc"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "https://github.com/numbofathma/phaser-typescript-webpack.git"
17 | },
18 | "engines": {
19 | "node": ">= 7.0.0"
20 | },
21 | "author": "Costin Mirica (https://www.costinmirica.com/)",
22 | "license": "MIT",
23 | "homepage": "https://github.com/numbofathma/phaser-typescript-webpack",
24 | "devDependencies": {
25 | "@babel/cli": "^7.23.9",
26 | "@babel/core": "^7.24.0",
27 | "@babel/plugin-proposal-class-properties": "^7.18.6",
28 | "@babel/plugin-proposal-object-rest-spread": "^7.20.7",
29 | "@babel/plugin-transform-typescript": "^7.23.6",
30 | "@babel/polyfill": "^7.12.1",
31 | "@babel/preset-env": "^7.24.0",
32 | "@babel/preset-typescript": "^7.23.3",
33 | "@types/howler": "^2.2.11",
34 | "@typescript-eslint/eslint-plugin": "^7.2.0",
35 | "@typescript-eslint/parser": "^7.2.0",
36 | "babel-loader": "^9.1.3",
37 | "copy-webpack-plugin": "^12.0.2",
38 | "eslint": "^8.57.0",
39 | "eslint-config-airbnb-base": "^15.0.0",
40 | "eslint-import-resolver-webpack": "^0.13.8",
41 | "eslint-webpack-plugin": "^4.1.0",
42 | "expose-loader": "^5.0.0",
43 | "html-webpack-plugin": "^5.6.0",
44 | "javascript-obfuscator": "^4.1.0",
45 | "rimraf": "^5.0.5",
46 | "typescript": "^5.4.2",
47 | "webpack": "^5.90.3",
48 | "webpack-cli": "^5.1.4",
49 | "webpack-dev-server": "^5.0.3",
50 | "webpack-obfuscator": "^3.5.1"
51 | },
52 | "dependencies": {
53 | "howler": "^2.2.4",
54 | "phaser-ce": "^2.20.0"
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/webpack.dev.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const HtmlWebpackPlugin = require('html-webpack-plugin');
4 | const ESLintPlugin = require('eslint-webpack-plugin');
5 |
6 | const phaserModule = path.join(__dirname, '/node_modules/phaser-ce/');
7 | const phaser = path.join(phaserModule, 'build/custom/phaser-arcade-physics.js');
8 | const pixi = path.join(phaserModule, 'build/custom/pixi.js');
9 | const p2 = path.join(phaserModule, 'build/custom/p2.js');
10 |
11 | module.exports = {
12 | devServer: {
13 | static: {
14 | directory: path.resolve(__dirname, 'assets'),
15 | publicPath: '/assets',
16 | },
17 | hot: true,
18 | open: true,
19 | compress: true,
20 | port: 8000,
21 | },
22 | entry: {
23 | app: [
24 | path.resolve(pixi),
25 | path.resolve(p2),
26 | path.resolve(__dirname, 'src/app.ts'),
27 | ]
28 | },
29 | output: {
30 | filename: '[name].bundle.js',
31 | path: path.resolve('./dist'),
32 | publicPath: '/'
33 | },
34 | plugins: [
35 | new ESLintPlugin({
36 | files: ['./src/**/*.ts']
37 | }),
38 | new HtmlWebpackPlugin({
39 | template: './index.html',
40 | inject: 'body'
41 | })
42 | ],
43 | module: {
44 | rules: [
45 | {
46 | test: /\.(j|t)s$/,
47 | exclude: /(node_modules|bower_components)/,
48 | use: {
49 | loader: 'babel-loader'
50 | }
51 | },
52 | {
53 | test: /pixi\.js/,
54 | use: {
55 | loader: 'expose-loader',
56 | options: {
57 | exposes: ['PIXI', pixi]
58 | }
59 | }
60 | },
61 | {
62 | test: /p2\.js$/,
63 | use: {
64 | loader: 'expose-loader',
65 | options: {
66 | exposes: ['p2', p2]
67 | }
68 | }
69 | },
70 | {
71 | test: /phaser-arcade-physics\.js/,
72 | use: {
73 | loader: 'expose-loader',
74 | options: {
75 | exposes: ['Phaser', phaser]
76 | }
77 | }
78 | },
79 | ]
80 | },
81 | resolve: {
82 | extensions: ['.js', '.ts'],
83 | alias: {
84 | 'phaser-ce': phaser,
85 | 'pixi': pixi,
86 | 'p2': p2,
87 | }
88 | }
89 | };
90 |
--------------------------------------------------------------------------------
/src/states/boot.ts:
--------------------------------------------------------------------------------
1 | import Phaser from 'phaser-ce';
2 |
3 | export class Boot extends Phaser.State {
4 | public create(): void {
5 | // set up input max pointers
6 | this.input.maxPointers = 1;
7 | this.game.stage.backgroundColor = '000000';
8 | // set up stage disable visibility change
9 | // this.stage.disableVisibilityChange = true;
10 | // Set up the scaling method used by the ScaleManager
11 | // Valid values for scaleMode are:
12 | // * EXACT_FIT
13 | // * NO_SCALE
14 | // * SHOW_ALL
15 | // * RESIZE
16 | // See http://docs.phaser.io/Phaser.ScaleManager.html for full document
17 | this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
18 | // If you wish to align your game in the middle of the page then you can
19 | // set this value to true. It will place a re-calculated margin-left
20 | // pixel value onto the canvas element which is updated on orientation /
21 | // resizing events. It doesn't care about any other DOM element that may
22 | // be on the page, it literally just sets the margin.
23 | this.scale.pageAlignHorizontally = true;
24 | this.scale.pageAlignVertically = true;
25 | // this.game.scale.compatibility.forceMinimumDocumentHeight = true;
26 | // this.scale.compatibility.forceMinimumDocumentHeight = true;
27 | // Force the orientation in landscape or portrait.
28 | // * Set first to true to force landscape.
29 | // * Set second to true to force portrait.
30 | // this.scale.forceOrientation(false, true);
31 | // this.game.scale.compatibility.forceMinimumDocumentHeight = true;
32 | // Sets the callback that will be called when the window resize event
33 | // occurs, or if set the parent container changes dimensions. Use this
34 | // to handle responsive game layout options. Note that the callback will
35 | // only be called if the ScaleManager.scaleMode is set to RESIZE.
36 | // this.scale.setResizeCallback(this.gameResized, this);
37 | // Set screen size automatically based on the scaleMode. This is only
38 | // needed if ScaleMode is not set to RESIZE.
39 | // this.scale.updateLayout(true);
40 | // Re-calculate scale mode and update screen size. This only applies if
41 | // ScaleMode is not set to RESIZE.
42 | this.scale.refresh();
43 |
44 | this.game.state.start('Preload');
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Phaser.io CE 2.20.0, Howler.js 2.2.4, TypeScript 5.4.2 and Webpack 5.90, play nice together.
2 | #### A boilerplate project to create games with Phaser.io, Howler.js, TypeScript and Webpack.
3 |
4 | ## Features
5 | - Uses the latest Phaser CE
6 | - Uses Howler (an awesome audio library) - can be easily removed if one does not use it
7 | - TypeScript linter that checks TypeScript code for readability, maintainability, and functionality errors
8 | - Webpack 5 ready
9 | - Built-in commands to easily deploy code your code (minify, uglify, comments removal, etc)
10 | - Other awesome stuff!
11 |
12 | # Setup
13 | To use this boilerplate you’ll need to install a few things before you have a working copy of the project.
14 |
15 | ## 1. Clone this repo:
16 |
17 | Navigate into your workspace directory.
18 |
19 | Run:
20 |
21 | ```git clone https://github.com/numbofathma/phaser-typescript-webpack.git```
22 |
23 | ## 2. Install node.js and npm:
24 |
25 | https://nodejs.org/en/
26 |
27 |
28 | ## 3. Install dependencies:
29 |
30 | Navigate to the cloned repo’s directory.
31 |
32 | Run:
33 |
34 | ```npm install```
35 |
36 | ## 4. Run the development server:
37 |
38 | Run:
39 |
40 | ```npm run start```
41 |
42 | This will run a server so you can run the game in a browser.
43 |
44 | Open your browser and enter localhost:8000 into the address bar.
45 |
46 | As you change your code, Webpack will watch for changes and the browser will refresh.
47 |
48 |
49 | ## 5. Build for deployment:
50 |
51 | Run:
52 |
53 | ```npm run build```
54 |
55 | This will optimize and minimize the compiled bundle. Your code will be minified and uglyfied for reverse engineering protection.
56 | The vendor library will only be minified because uglify will add extra MBs to your game.
57 |
58 |
59 | ## 6. Extra features
60 | I've also added a command that auto-fixes your code according to the rules in the .eslintrc.json file.
61 |
62 | Run:
63 |
64 | ``` npm run lint:fix```
65 |
66 | ...and also a commad to check your TypeScript types.
67 |
68 | Run:
69 |
70 | ``` npm run check```
71 |
72 | ## Credits
73 | Big thanks to this great repos:
74 |
75 | https://github.com/lean/phaser-es6-webpack/tree/typescript
76 | https://github.com/eduardonunesp/phaser-typescript-webpack-boilerplate
77 | https://github.com/heathkit/phaser-typescript-webpack-starter/tree/master/src/sprites
78 |
79 | Special thanks to:
80 | dimorphic
81 |
82 |
83 | Made with <3 in Romania
84 |
--------------------------------------------------------------------------------
/webpack.prod.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const HtmlWebpackPlugin = require('html-webpack-plugin');
4 | const CopyWebpackPlugin = require('copy-webpack-plugin');
5 | const JavaScriptObfuscator = require('webpack-obfuscator');
6 | const TerserPlugin = require('terser-webpack-plugin');
7 |
8 | const phaserModule = path.join(__dirname, '/node_modules/phaser-ce/');
9 | const phaser = path.join(phaserModule, 'build/custom/phaser-arcade-physics.js');
10 | const pixi = path.join(phaserModule, 'build/custom/pixi.js');
11 | const p2 = path.join(phaserModule, 'build/custom/p2.js');
12 |
13 | module.exports = {
14 | entry: {
15 | app: [
16 | path.resolve(pixi),
17 | path.resolve(p2),
18 | path.resolve(__dirname, 'src/app.ts'),
19 | ]
20 | },
21 | output: {
22 | filename: '[name].bundle.js',
23 | path: path.resolve('./dist'),
24 | publicPath: '/'
25 | },
26 | mode: 'production',
27 | devtool: false,
28 | plugins: [
29 | new CopyWebpackPlugin({
30 | patterns: [
31 | { from: './assets', to: './assets' },
32 | ],
33 | options: {
34 | concurrency: 100,
35 | },
36 | }),
37 | new JavaScriptObfuscator({
38 | rotateUnicodeArray: true
39 | }, ['vendor.bundle.js']),
40 | new HtmlWebpackPlugin({
41 | template: './index.html',
42 | inject: 'body',
43 | })
44 | ],
45 | performance: {
46 | hints: false,
47 | maxEntrypointSize: 512000,
48 | maxAssetSize: 512000
49 | },
50 | optimization: {
51 | splitChunks: {
52 | minSize: 10000,
53 | maxSize: 250000,
54 | cacheGroups: {
55 | vendor: {
56 | test: /node_modules/,
57 | chunks: 'initial',
58 | name: 'vendor',
59 | priority: 10,
60 | enforce: true
61 | }
62 | }
63 | },
64 | minimizer: [
65 | new TerserPlugin({
66 | parallel: true,
67 | terserOptions: {
68 | // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
69 | },
70 | }),
71 | ],
72 | },
73 | module: {
74 | rules: [
75 | {
76 | test: /\.(j|t)s$/,
77 | exclude: /(node_modules|bower_components)/,
78 | use: {
79 | loader: 'babel-loader'
80 | }
81 | },
82 | {
83 | test: /pixi\.js/,
84 | use: {
85 | loader: 'expose-loader',
86 | options: {
87 | exposes: ['PIXI', pixi]
88 | }
89 | }
90 | },
91 | {
92 | test: /p2\.js$/,
93 | use: {
94 | loader: 'expose-loader',
95 | options: {
96 | exposes: ['p2', p2]
97 | }
98 | }
99 | },
100 | {
101 | test: /phaser-arcade-physics\.js/,
102 | use: {
103 | loader: 'expose-loader',
104 | options: {
105 | exposes: ['Phaser', phaser]
106 | }
107 | }
108 | },
109 | ]
110 | },
111 | resolve: {
112 | extensions: ['.js', '.ts'],
113 | alias: {
114 | 'phaser-ce': phaser,
115 | 'pixi': pixi,
116 | 'p2': p2,
117 | }
118 | }
119 | };
120 |
--------------------------------------------------------------------------------
/assets/fonts/font.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
--------------------------------------------------------------------------------