├── .gitignore ├── README.md ├── assets └── sprites │ ├── dude.png │ └── platform.png ├── package-lock.json ├── package.json ├── src ├── constants.ts ├── game.ts ├── index.html ├── manifest.json ├── objects │ └── player.ts ├── phaser.d.ts ├── scenes │ ├── boot.ts │ ├── game-over.ts │ ├── game-title.ts │ ├── main.ts │ └── preload.ts ├── service-worker.js └── utils.ts ├── sw-toolbox.js ├── tsconfig.json └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Specifies intentionally untracked files to ignore when using Git 2 | # http://git-scm.com/docs/gitignore 3 | 4 | *~ 5 | *.sw[mnpcod] 6 | *.log 7 | *.tmp 8 | *.tmp.* 9 | log.txt 10 | *.sublime-project 11 | *.sublime-workspace 12 | .vscode/ 13 | npm-debug.log* 14 | 15 | .idea/ 16 | .sourcemaps/ 17 | .sass-cache/ 18 | .tmp/ 19 | .versions/ 20 | node_modules/ 21 | tmp/ 22 | temp/ 23 | hooks/ 24 | www/ 25 | $RECYCLE.BIN/ 26 | 27 | .DS_Store 28 | Thumbs.db 29 | UserInterfaceState.xcuserstate 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Phaser/TypeScript/Webpack/Capacitor Starter 2 | 3 | A simple starter template for using Phaser with TypeScript, Webpack, and Capacitor for native iOS and Android builds. Using this repository will require a working knowledge of Capacitor - you can find documentation [here](https://capacitor.ionicframework.com/docs/) and additional learning resources [here](https://www.joshmorony.com/tag/capacitor/). 4 | 5 | As of this commit, Phaser 3 is not feature complete and Capacitor is still in alpha. I would not recommend using this in a production environment - proceed with caution. 6 | 7 | Inspiration/configuration from: 8 | - https://github.com/digitsensitive/phaser3-typescript 9 | - https://github.com/TooManyCaptains/TooManyCaptains 10 | 11 | ## Install 12 | 13 | ``` 14 | npm install 15 | ``` 16 | 17 | ``` 18 | npx cap init 19 | ``` 20 | 21 | ## Develop 22 | 23 | ``` 24 | npm run dev 25 | ``` 26 | 27 | ## Build 28 | 29 | ``` 30 | npm run build 31 | ``` 32 | 33 | ## Add Native Platforms 34 | 35 | ``` 36 | npx cap add ios 37 | ``` 38 | 39 | ``` 40 | npx cap add android 41 | ``` 42 | 43 | ## Run 44 | 45 | ``` 46 | npm run build 47 | ``` 48 | 49 | ``` 50 | npx cap open ios 51 | ``` 52 | 53 | ``` 54 | npx cap open android 55 | ``` 56 | -------------------------------------------------------------------------------- /assets/sprites/dude.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuamorony/phaser3-typescript-webpack-capacitor/e1520f3d998860938aeddfb8322060cf6e61f5d0/assets/sprites/dude.png -------------------------------------------------------------------------------- /assets/sprites/platform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuamorony/phaser3-typescript-webpack-capacitor/e1520f3d998860938aeddfb8322060cf6e61f5d0/assets/sprites/platform.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phaser3-typescript", 3 | "version": "0.0.1", 4 | "description": "Boilerplate for Phaser 3 in Typescript", 5 | "keywords": [ 6 | "Phaser", 7 | "Phaser 3", 8 | "Phaser3", 9 | "TypeScript", 10 | "Webpack" 11 | ], 12 | "devDependencies": { 13 | "expose-loader": "0.7.5", 14 | "ts-loader": "5.1.1", 15 | "typescript": "3.0.3", 16 | "webpack": "4.19.1", 17 | "webpack-cli": "3.1.0", 18 | "webpack-dev-server": "3.1.8" 19 | }, 20 | "dependencies": { 21 | "@capacitor/cli": "^1.0.0-beta.7", 22 | "@capacitor/core": "^1.0.0-beta.7", 23 | "@capacitor/ios": "^1.0.0-beta.7", 24 | "phaser": "3.13.0" 25 | }, 26 | "scripts": { 27 | "copy": "cp src/index.html www/index.html && cp -fR assets www && cp src/service-worker.js www/service-worker.js && cp src/manifest.json www/manifest.json && cp sw-toolbox.js www/sw-toolbox.js", 28 | "dev": "webpack && npm run copy && webpack-dev-server --mode development", 29 | "prod": "webpack && npm run copy && webpack-dev-server --mode production", 30 | "build": "webpack --mode production && npm run copy && npx cap copy" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | export const WORLD_WIDTH = window.innerWidth; 2 | export const WORLD_HEIGHT = window.innerHeight; -------------------------------------------------------------------------------- /src/game.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import 'phaser'; 4 | import { BootScene } from './scenes/boot'; 5 | import { PreloadScene } from './scenes/preload'; 6 | import { GameTitleScene } from './scenes/game-title'; 7 | import { MainScene } from './scenes/main'; 8 | import { GameOverScene } from './scenes/game-over'; 9 | 10 | import { WORLD_WIDTH, WORLD_HEIGHT } from './constants'; 11 | 12 | import { Plugins } from '@capacitor/core'; 13 | 14 | const config: GameConfig = { 15 | width: WORLD_WIDTH, 16 | height: WORLD_HEIGHT, 17 | type: Phaser.AUTO, 18 | parent: 'game', 19 | backgroundColor: '#93e7ff', 20 | pixelArt: false, 21 | zoom: 1, 22 | physics: { 23 | default: 'arcade', 24 | arcade: { 25 | gravity: { y: 300 } 26 | } 27 | } 28 | }; 29 | 30 | const { StatusBar, SplashScreen } = Plugins; 31 | 32 | export class Game extends Phaser.Game { 33 | 34 | constructor(GameConfig: config) { 35 | 36 | super(config); 37 | 38 | this.scene.add('Boot', BootScene, false); 39 | this.scene.add('Preload', PreloadScene, false); 40 | this.scene.add('GameTitle', GameTitleScene, false); 41 | this.scene.add('Main', MainScene, false); 42 | this.scene.add('GameOver', GameOverScene, false); 43 | 44 | this.scene.start('Boot'); 45 | 46 | StatusBar.hide(); 47 | SplashScreen.hide(); 48 | 49 | } 50 | 51 | } 52 | 53 | new Game(config); -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | My Game 9 | 10 | 18 | 19 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "My Game", 3 | "short_name": "My Game", 4 | "start_url": "index.html", 5 | "display": "standalone", 6 | "icons": [{ 7 | "src": "assets/images/icon.png", 8 | "sizes": "512x512", 9 | "type": "image/png" 10 | }], 11 | "background_color": "#000", 12 | "theme_color": "#000" 13 | } -------------------------------------------------------------------------------- /src/objects/player.ts: -------------------------------------------------------------------------------- 1 | export default class Player { 2 | 3 | private player; 4 | private scene; 5 | private x; 6 | private y; 7 | private controls; 8 | 9 | constructor(x, y, scene){ 10 | 11 | this.scene = scene; 12 | this.x = x; 13 | this.y = y; 14 | this.controls = this.scene.input.activePointer; 15 | 16 | this.addToScene(); 17 | this.addAnimations(); 18 | 19 | } 20 | 21 | get entity() { 22 | return this.player; 23 | } 24 | 25 | update(): void { 26 | 27 | if(this.controls.isDown && this.player.body.touching.down){ 28 | this.player.setVelocityY(-330); 29 | this.player.anims.play('right', true); 30 | } else { 31 | this.player.anims.play('turn'); 32 | } 33 | 34 | } 35 | 36 | addToScene(): void { 37 | 38 | this.player = this.scene.physics.add.sprite(this.x, this.y, 'dude'); 39 | this.player.setBounce(0.2); 40 | 41 | } 42 | 43 | addAnimations(): void { 44 | 45 | this.scene.anims.create({ 46 | key: 'turn', 47 | frames: [ { key: 'dude', frame: 4 } ], 48 | frameRate: 20 49 | }); 50 | 51 | this.scene.anims.create({ 52 | key: 'right', 53 | frames: this.scene.anims.generateFrameNumbers('dude', { start: 5, end: 8 }), 54 | frameRate: 10, 55 | repeat: -1 56 | }); 57 | 58 | } 59 | 60 | 61 | } -------------------------------------------------------------------------------- /src/scenes/boot.ts: -------------------------------------------------------------------------------- 1 | export class BootScene extends Phaser.Scene { 2 | 3 | create(): void { 4 | 5 | this.scene.start('Preload'); 6 | 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /src/scenes/game-over.ts: -------------------------------------------------------------------------------- 1 | export class GameOverScene extends Phaser.Scene { 2 | 3 | preload(): void { 4 | 5 | } 6 | 7 | create(): void { 8 | this.scene.start('Main'); 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /src/scenes/game-title.ts: -------------------------------------------------------------------------------- 1 | export class GameTitleScene extends Phaser.Scene { 2 | 3 | preload(): void { 4 | 5 | } 6 | 7 | create(): void { 8 | this.scene.start('Main'); 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /src/scenes/main.ts: -------------------------------------------------------------------------------- 1 | import Player from '../objects/player'; 2 | import { WORLD_WIDTH, WORLD_HEIGHT } from '../constants'; 3 | 4 | export class MainScene extends Phaser.Scene { 5 | 6 | private player; 7 | private platforms; 8 | 9 | create(): void { 10 | 11 | this.player = new Player(WORLD_WIDTH/2, 100, this); 12 | this.addPlatforms(); 13 | 14 | } 15 | 16 | update(): void { 17 | 18 | this.player.update(); 19 | 20 | } 21 | 22 | addPlatforms(){ 23 | 24 | this.platforms = this.physics.add.staticGroup(); 25 | 26 | this.platforms.create(WORLD_WIDTH / 2, WORLD_HEIGHT, 'ground'); 27 | this.physics.add.collider(this.player.entity, this.platforms, null, null, this); 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/scenes/preload.ts: -------------------------------------------------------------------------------- 1 | export class PreloadScene extends Phaser.Scene { 2 | 3 | preload(): void { 4 | 5 | this.load.crossOrigin = 'anonymous'; 6 | this.load.maxParallelDownloads = Infinity; 7 | 8 | this.load.image('ground', 'assets/sprites/platform.png'); 9 | this.load.spritesheet('dude', 'assets/sprites/dude.png', { frameWidth: 32, frameHeight: 48 }); 10 | 11 | } 12 | 13 | create(): void { 14 | this.scene.start('GameTitle'); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/service-worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Check out https://googlechromelabs.github.io/sw-toolbox/ for 3 | * more info on how to use sw-toolbox to custom configure your service worker. 4 | */ 5 | 6 | 'use strict'; 7 | importScripts('./sw-toolbox.js'); 8 | 9 | self.toolbox.options.cache = { 10 | name: 'phaser-cache' 11 | }; 12 | 13 | // pre-cache our key assets 14 | self.toolbox.precache( 15 | [ 16 | './build/bundle.js', 17 | './assets/sprites/dude.png', 18 | './assets/sprites/platform.png', 19 | 'index.html', 20 | 'manifest.json' 21 | ] 22 | ); 23 | 24 | // dynamically cache any other local assets 25 | self.toolbox.router.any('/*', self.toolbox.fastest); 26 | 27 | // for any other requests go to the network, cache, 28 | // and then only use that cached resource if your user goes offline 29 | self.toolbox.router.default = self.toolbox.networkFirst; 30 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | export function someUtilityFunction(){ 2 | return "something"; 3 | } -------------------------------------------------------------------------------- /sw-toolbox.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.toolbox=e()}}(function(){return function e(t,n,r){function o(c,s){if(!n[c]){if(!t[c]){var a="function"==typeof require&&require;if(!s&&a)return a(c,!0);if(i)return i(c,!0);var u=new Error("Cannot find module '"+c+"'");throw u.code="MODULE_NOT_FOUND",u}var f=n[c]={exports:{}};t[c][0].call(f.exports,function(e){var n=t[c][1][e];return o(n?n:e)},f,f.exports,e,t,n,r)}return n[c].exports}for(var i="function"==typeof require&&require,c=0;ct.value[l]){var r=t.value[p];c.push(r),a.delete(r),t.continue()}},s.oncomplete=function(){r(c)},s.onabort=o}):Promise.resolve([])}function s(e,t){return t?new Promise(function(n,r){var o=[],i=e.transaction(h,"readwrite"),c=i.objectStore(h),s=c.index(l),a=s.count();s.count().onsuccess=function(){var e=a.result;e>t&&(s.openCursor().onsuccess=function(n){var r=n.target.result;if(r){var i=r.value[p];o.push(i),c.delete(i),e-o.length>t&&r.continue()}})},i.oncomplete=function(){n(o)},i.onabort=r}):Promise.resolve([])}function a(e,t,n,r){return c(e,n,r).then(function(n){return s(e,t).then(function(e){return n.concat(e)})})}var u="sw-toolbox-",f=1,h="store",p="url",l="timestamp",d={};t.exports={getDb:o,setTimestampForUrl:i,expireEntries:a}},{}],3:[function(e,t,n){"use strict";function r(e){var t=a.match(e.request);t?e.respondWith(t(e.request)):a.default&&"GET"===e.request.method&&0===e.request.url.indexOf("http")&&e.respondWith(a.default(e.request))}function o(e){s.debug("activate event fired");var t=u.cache.name+"$$$inactive$$$";e.waitUntil(s.renameCache(t,u.cache.name))}function i(e){return e.reduce(function(e,t){return e.concat(t)},[])}function c(e){var t=u.cache.name+"$$$inactive$$$";s.debug("install event fired"),s.debug("creating cache ["+t+"]"),e.waitUntil(s.openCache({cache:{name:t}}).then(function(e){return Promise.all(u.preCacheItems).then(i).then(s.validatePrecacheInput).then(function(t){return s.debug("preCache list: "+(t.join(", ")||"(none)")),e.addAll(t)})}))}e("serviceworker-cache-polyfill");var s=e("./helpers"),a=e("./router"),u=e("./options");t.exports={fetchListener:r,activateListener:o,installListener:c}},{"./helpers":1,"./options":4,"./router":6,"serviceworker-cache-polyfill":16}],4:[function(e,t,n){"use strict";var r;r=self.registration?self.registration.scope:self.scope||new URL("./",self.location).href,t.exports={cache:{name:"$$$toolbox-cache$$$"+r+"$$$",maxAgeSeconds:null,maxEntries:null},debug:!1,networkTimeoutSeconds:null,preCacheItems:[],successResponses:/^0|([123]\d\d)|(40[14567])|410$/}},{}],5:[function(e,t,n){"use strict";var r=new URL("./",self.location),o=r.pathname,i=e("path-to-regexp"),c=function(e,t,n,r){t instanceof RegExp?this.fullUrlRegExp=t:(0!==t.indexOf("/")&&(t=o+t),this.keys=[],this.regexp=i(t,this.keys)),this.method=e,this.options=r,this.handler=n};c.prototype.makeHandler=function(e){var t;if(this.regexp){var n=this.regexp.exec(e);t={},this.keys.forEach(function(e,r){t[e.name]=n[r+1]})}return function(e){return this.handler(e,t,this.options)}.bind(this)},t.exports=c},{"path-to-regexp":15}],6:[function(e,t,n){"use strict";function r(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var o=e("./route"),i=e("./helpers"),c=function(e,t){for(var n=e.entries(),r=n.next(),o=[];!r.done;){var i=new RegExp(r.value[0]);i.test(t)&&o.push(r.value[1]),r=n.next()}return o},s=function(){this.routes=new Map,this.routes.set(RegExp,new Map),this.default=null};["get","post","put","delete","head","any"].forEach(function(e){s.prototype[e]=function(t,n,r){return this.add(e,t,n,r)}}),s.prototype.add=function(e,t,n,c){c=c||{};var s;t instanceof RegExp?s=RegExp:(s=c.origin||self.location.origin,s=s instanceof RegExp?s.source:r(s)),e=e.toLowerCase();var a=new o(e,t,n,c);this.routes.has(s)||this.routes.set(s,new Map);var u=this.routes.get(s);u.has(e)||u.set(e,new Map);var f=u.get(e),h=a.regexp||a.fullUrlRegExp;f.has(h.source)&&i.debug('"'+t+'" resolves to same regex as existing route.'),f.set(h.source,a)},s.prototype.matchMethod=function(e,t){var n=new URL(t),r=n.origin,o=n.pathname;return this._match(e,c(this.routes,r),o)||this._match(e,[this.routes.get(RegExp)],t)},s.prototype._match=function(e,t,n){if(0===t.length)return null;for(var r=0;r0)return s[0].makeHandler(n)}}return null},s.prototype.match=function(e){return this.matchMethod(e.method,e.url)||this.matchMethod("any",e.url)},t.exports=new s},{"./helpers":1,"./route":5}],7:[function(e,t,n){"use strict";function r(e,t,n){return n=n||{},i.debug("Strategy: cache first ["+e.url+"]",n),i.openCache(n).then(function(t){return t.match(e).then(function(t){var r=n.cache||o.cache,c=Date.now();return i.isResponseFresh(t,r.maxAgeSeconds,c)?t:i.fetchAndCache(e,n)})})}var o=e("../options"),i=e("../helpers");t.exports=r},{"../helpers":1,"../options":4}],8:[function(e,t,n){"use strict";function r(e,t,n){return n=n||{},i.debug("Strategy: cache only ["+e.url+"]",n),i.openCache(n).then(function(t){return t.match(e).then(function(e){var t=n.cache||o.cache,r=Date.now();if(i.isResponseFresh(e,t.maxAgeSeconds,r))return e})})}var o=e("../options"),i=e("../helpers");t.exports=r},{"../helpers":1,"../options":4}],9:[function(e,t,n){"use strict";function r(e,t,n){return o.debug("Strategy: fastest ["+e.url+"]",n),new Promise(function(r,c){var s=!1,a=[],u=function(e){a.push(e.toString()),s?c(new Error('Both cache and network failed: "'+a.join('", "')+'"')):s=!0},f=function(e){e instanceof Response?r(e):u("No result returned")};o.fetchAndCache(e.clone(),n).then(f,u),i(e,t,n).then(f,u)})}var o=e("../helpers"),i=e("./cacheOnly");t.exports=r},{"../helpers":1,"./cacheOnly":8}],10:[function(e,t,n){t.exports={networkOnly:e("./networkOnly"),networkFirst:e("./networkFirst"),cacheOnly:e("./cacheOnly"),cacheFirst:e("./cacheFirst"),fastest:e("./fastest")}},{"./cacheFirst":7,"./cacheOnly":8,"./fastest":9,"./networkFirst":11,"./networkOnly":12}],11:[function(e,t,n){"use strict";function r(e,t,n){n=n||{};var r=n.successResponses||o.successResponses,c=n.networkTimeoutSeconds||o.networkTimeoutSeconds;return i.debug("Strategy: network first ["+e.url+"]",n),i.openCache(n).then(function(t){var s,a,u=[];if(c){var f=new Promise(function(r){s=setTimeout(function(){t.match(e).then(function(e){var t=n.cache||o.cache,c=Date.now(),s=t.maxAgeSeconds;i.isResponseFresh(e,s,c)&&r(e)})},1e3*c)});u.push(f)}var h=i.fetchAndCache(e,n).then(function(e){if(s&&clearTimeout(s),r.test(e.status))return e;throw i.debug("Response was an HTTP error: "+e.statusText,n),a=e,new Error("Bad response")}).catch(function(r){return i.debug("Network or response error, fallback to cache ["+e.url+"]",n),t.match(e).then(function(e){if(e)return e;if(a)return a;throw r})});return u.push(h),Promise.race(u)})}var o=e("../options"),i=e("../helpers");t.exports=r},{"../helpers":1,"../options":4}],12:[function(e,t,n){"use strict";function r(e,t,n){return o.debug("Strategy: network only ["+e.url+"]",n),fetch(e)}var o=e("../helpers");t.exports=r},{"../helpers":1}],13:[function(e,t,n){"use strict";var r=e("./options"),o=e("./router"),i=e("./helpers"),c=e("./strategies"),s=e("./listeners");i.debug("Service Worker Toolbox is loading"),self.addEventListener("install",s.installListener),self.addEventListener("activate",s.activateListener),self.addEventListener("fetch",s.fetchListener),t.exports={networkOnly:c.networkOnly,networkFirst:c.networkFirst,cacheOnly:c.cacheOnly,cacheFirst:c.cacheFirst,fastest:c.fastest,router:o,options:r,cache:i.cache,uncache:i.uncache,precache:i.precache}},{"./helpers":1,"./listeners":3,"./options":4,"./router":6,"./strategies":10}],14:[function(e,t,n){t.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},{}],15:[function(e,t,n){function r(e,t){for(var n,r=[],o=0,i=0,c="",s=t&&t.delimiter||"/";null!=(n=x.exec(e));){var f=n[0],h=n[1],p=n.index;if(c+=e.slice(i,p),i=p+f.length,h)c+=h[1];else{var l=e[i],d=n[2],m=n[3],g=n[4],v=n[5],w=n[6],y=n[7];c&&(r.push(c),c="");var b=null!=d&&null!=l&&l!==d,E="+"===w||"*"===w,R="?"===w||"*"===w,k=n[2]||s,$=g||v;r.push({name:m||o++,prefix:d||"",delimiter:k,optional:R,repeat:E,partial:b,asterisk:!!y,pattern:$?u($):y?".*":"[^"+a(k)+"]+?"})}}return i=46||"Chrome"===n&&r>=50)||(Cache.prototype.addAll=function(e){function t(e){this.name="NetworkError",this.code=19,this.message=e}var n=this;return t.prototype=Object.create(Error.prototype),Promise.resolve().then(function(){if(arguments.length<1)throw new TypeError;return e=e.map(function(e){return e instanceof Request?e:String(e)}),Promise.all(e.map(function(e){"string"==typeof e&&(e=new Request(e));var n=new URL(e.url).protocol;if("http:"!==n&&"https:"!==n)throw new t("Invalid scheme");return fetch(e.clone())}))}).then(function(r){if(r.some(function(e){return!e.ok}))throw new t("Incorrect response status");return Promise.all(r.map(function(t,r){return n.put(e[r],t)}))}).then(function(){})},Cache.prototype.add=function(e){return this.addAll([e])})}()},{}]},{},[13])(13)}); 16 | //# sourceMappingURL=sw-toolbox.js.map 17 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var pathToPhaser = path.join(__dirname, '/node_modules/phaser/'); 3 | var phaser = path.join(pathToPhaser, 'dist/phaser.js'); 4 | 5 | module.exports = { 6 | entry: './src/game.ts', 7 | output: { 8 | filename: 'bundle.js', 9 | path: path.resolve(__dirname, 'www/build') 10 | }, 11 | devServer: { 12 | contentBase: path.resolve(__dirname, './www'), 13 | publicPath: '/www/', 14 | host: '127.0.0.1', 15 | port: 8080, 16 | open: true 17 | }, 18 | resolve: { 19 | extensions: ['.ts', '.js'], 20 | alias: { 21 | phaser: phaser 22 | } 23 | }, 24 | module: { 25 | rules: [ 26 | { test: /\.ts$/, loader: 'ts-loader', exclude: '/node_modules/' }, 27 | { test: /phaser\.js$/, loader: 'expose-loader?Phaser' } 28 | ] 29 | } 30 | }; 31 | --------------------------------------------------------------------------------