├── .gitignore ├── src ├── images │ └── logo.png ├── css │ └── style.css ├── index.html └── scripts │ ├── types.d.ts │ ├── fps-meter.ts │ └── app.ts ├── tests └── module-test.js ├── .vscode └── launch.json ├── package.json ├── LICENCE ├── webpack.config.js ├── README.md └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.map 2 | *.log 3 | debug/ 4 | dist/ 5 | node_modules/ 6 | -------------------------------------------------------------------------------- /src/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahiko00/PixiProject/HEAD/src/images/logo.png -------------------------------------------------------------------------------- /tests/module-test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | const add = (a, b) => a + b; // Just as an example. Better to "require" 5 | 6 | describe('Tests', () => { 7 | it('should add correctly', () => { 8 | assert.equal(add(1, 1), 2); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /src/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #ffffff; 3 | font-family: "Century Gothic", helvetica, arial, sans-serif; 4 | font-size: 1.4em; 5 | line-height: 1.5; 6 | } 7 | 8 | .fps { 9 | position: fixed; 10 | left: 0px; 11 | bottom: 0px; 12 | color: #0000ff; 13 | z-index: 10; 14 | font-family: monospace; 15 | } 16 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Pixi.js Project Boiler Plate 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/scripts/types.d.ts: -------------------------------------------------------------------------------- 1 | // types.d.ts 2 | 3 | interface Point { 4 | x: double; 5 | y: double; 6 | } // Point 7 | 8 | interface Interval { 9 | min: double; 10 | max: double; 11 | } // Interval 12 | 13 | type int = number; 14 | type double = number; 15 | type Vec2i = [int, int]; 16 | type Vec2f = [double, double]; 17 | type Vec3i = [int, int, int]; 18 | type Vec3f = [double, double, double]; 19 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Utilisez IntelliSense pour découvrir les attributs de débogage Node.js possibles. 3 | // Pointez pour afficher la description des attributs existants. 4 | // Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "chrome", 9 | "request": "launch", 10 | "name": "Launch Chrome", 11 | "url": "http://localhost:8080/", 12 | "webRoot": "${workspaceRoot}" 13 | }, 14 | { 15 | "type": "node", 16 | "request": "launch", 17 | "name": "Lancer le programme", 18 | "program": "${file}" 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /src/scripts/fps-meter.ts: -------------------------------------------------------------------------------- 1 | export class FpsMeter { 2 | private nbFrames: number; 3 | private elapsedTime: number; 4 | private previousTime: number; 5 | 6 | constructor(public render: () => void, private refreshDelay = 500) { 7 | this.nbFrames = 0; 8 | this.elapsedTime = 0; 9 | this.previousTime = performance.now(); 10 | } 11 | 12 | updateTime() { 13 | this.elapsedTime = performance.now() - this.previousTime; 14 | } 15 | 16 | tick() { 17 | this.nbFrames++; 18 | if (this.elapsedTime > this.refreshDelay) { 19 | this.render(); 20 | this.reset(); 21 | } 22 | } 23 | 24 | reset() { 25 | this.nbFrames = 0; 26 | this.elapsedTime = 0; 27 | this.previousTime = performance.now(); 28 | } 29 | 30 | getFrameRate() { 31 | return 1000.0 * this.nbFrames / this.elapsedTime; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pixi-project", 3 | "version": "0.2.0", 4 | "description": "Pixi.js project boiler plate using TypeScript, Webpack and Mocha", 5 | "scripts": { 6 | "build": "cross-env NODE_ENV=production webpack", 7 | "serve": "webpack-dev-server --hot", 8 | "test": "mocha tests" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/yahiko00/PixiProject.git" 13 | }, 14 | "author": "Yahiko ", 15 | "license": "MIT", 16 | "devDependencies": { 17 | "clean-webpack-plugin": "^3.0.0", 18 | "copy-webpack-plugin": "^5.1.1", 19 | "cross-env": "^7.0.2", 20 | "mocha": "^7.1.1", 21 | "mocha-loader": "^5.0.0", 22 | "ts-loader": "^6.2.2", 23 | "typescript": "^3.8.3", 24 | "webpack": "^4.42.1", 25 | "webpack-cli": "^3.3.11", 26 | "webpack-dev-server": "^3.10.3" 27 | }, 28 | "dependencies": { 29 | "pixi.js": "^5.2.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) ''[year(s)]'', ''[copyright holder]'' 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const CopyPlugin = require('copy-webpack-plugin'); 3 | const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 4 | const isDev = process.env.NODE_ENV !== 'production'; 5 | 6 | const config = { 7 | mode: isDev ? 'development' : 'production', 8 | entry: './src/scripts/app.ts', 9 | output: { 10 | path: path.resolve(__dirname, 'dist'), 11 | filename: 'bundle.js', 12 | }, 13 | resolve: { 14 | extensions: ['.tsx', '.ts', '.js'] 15 | }, 16 | module: { 17 | rules: [ 18 | { 19 | test: /\.tsx?$/, 20 | loader: 'ts-loader', 21 | exclude: /node_modules/, 22 | }, 23 | ] 24 | }, 25 | plugins: [ 26 | new CleanWebpackPlugin(), 27 | new CopyPlugin([ 28 | { from: 'src/index.html' }, 29 | { from: 'src/css/style.css', to: 'css/' }, 30 | { from: 'src/images/logo.png', to: 'images/' }, 31 | ]), 32 | ], 33 | devServer: { 34 | contentBase: path.join(__dirname, 'dist'), 35 | compress: true, 36 | port: 8080, 37 | hot: true 38 | }, 39 | optimization: { 40 | minimize: !isDev 41 | } 42 | }; 43 | 44 | module.exports = config; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pixi.js Project # 2 | 3 | A generic frontend **Pixi.js** project boiler plate in **TypeScript** using **Webpack**. 4 | 5 | Main features: 6 | 7 | * Source Map support 8 | * Incremental Build 9 | * Unit tests 10 | * Browser Hot Reload 11 | 12 | 13 | Main dependencies: 14 | 15 | * **Application Server**: [Node](https://nodejs.org/en/) 16 | * **Compiler**: [TypeScript](https://github.com/Microsoft/TypeScript) 17 | * **Bundler**: [Webpack](https://github.com/webpack/webpack) 18 | * **Unit Test Runner**: [Mocha](https://github.com/mochajs/mocha) 19 | * **Pixi.js**: [Pixi.js](http://www.pixijs.com/) 20 | 21 | 22 | ## Installation ## 23 | 24 | Node, TypeScript and TSLint should be installed globally. 25 | 26 | $> git clone https://github.com/yahiko00/PixiProject.git 27 | $> cd 28 | $> git init 29 | $> npm install 30 | 31 | 32 | ## Build ## 33 | 34 | Commands should be run under a **bash** shell. 35 | 36 | The following command builds and run the project in development mode with Hot Reload. 37 | 38 | $> npm run serve 39 | 40 | The following command builds the project in production mode. 41 | 42 | $> npm run build 43 | 44 | 45 | For more predefined commands, see `package.json`, item `scripts`. 46 | 47 | ## Contributors ## 48 | 49 | yahiko 50 | 51 | 52 | ## Licence ## 53 | 54 | MIT 55 | -------------------------------------------------------------------------------- /src/scripts/app.ts: -------------------------------------------------------------------------------- 1 | // app.ts 2 | 3 | import * as PIXI from 'pixi.js' 4 | import { FpsMeter } from './fps-meter'; 5 | 6 | interface EngineParams { 7 | containerId: string, 8 | canvasW: number, 9 | canvasH: number, 10 | fpsMax: number 11 | } 12 | 13 | class Engine { 14 | public container: HTMLElement; 15 | public loader: PIXI.Loader; 16 | public renderer: PIXI.Renderer; 17 | public stage: PIXI.Container; 18 | public graphics: PIXI.Graphics; 19 | public fpsMax: number; 20 | 21 | constructor(params: EngineParams) { 22 | this.loader = PIXI.Loader.shared; 23 | this.renderer = PIXI.autoDetectRenderer({ 24 | width: params.canvasW, 25 | height: params.canvasH, 26 | antialias: true 27 | }); 28 | this.stage = new PIXI.Container(); 29 | this.graphics = new PIXI.Graphics(); 30 | this.fpsMax = params.fpsMax; 31 | 32 | this.container = params.containerId ? document.getElementById(params.containerId) || document.body : document.body; 33 | this.container.appendChild(this.renderer.view); 34 | } // constructor 35 | } // Engine 36 | 37 | const engine = new Engine({ 38 | containerId: 'game', 39 | canvasW: 800, 40 | canvasH: 450, 41 | fpsMax: 60 42 | }); 43 | 44 | let fpsMeter: FpsMeter; 45 | const sprite = PIXI.Sprite.from('images/logo.png'); 46 | 47 | // ============== 48 | // === STATES === 49 | // ============== 50 | 51 | window.onload = load; 52 | 53 | function load() { 54 | create(); 55 | } // load 56 | 57 | function create() { 58 | /* ***************************** */ 59 | /* Create your Game Objects here */ 60 | /* ***************************** */ 61 | 62 | /* Sprite */ 63 | sprite.anchor.set(0.5); 64 | sprite.x = engine.renderer.width / 2; 65 | sprite.y = engine.renderer.height / 2; 66 | engine.stage.addChild(sprite); 67 | 68 | /* FPS */ 69 | const fpsMeterItem = document.createElement('div'); 70 | fpsMeterItem.classList.add('fps'); 71 | engine.container.appendChild(fpsMeterItem); 72 | 73 | fpsMeter = new FpsMeter(() => { 74 | fpsMeterItem.innerHTML = 'FPS: ' + fpsMeter.getFrameRate().toFixed(2).toString(); 75 | }); 76 | 77 | setInterval(update, 1000.0 / engine.fpsMax); 78 | render(); 79 | } // create 80 | 81 | function update() { 82 | fpsMeter.updateTime(); 83 | 84 | /* ***************************** */ 85 | /* Update your Game Objects here */ 86 | /* ***************************** */ 87 | 88 | } // update 89 | 90 | function render() { 91 | requestAnimationFrame(render); 92 | 93 | /* ***************************** */ 94 | /* Render your Game Objects here */ 95 | /* ***************************** */ 96 | 97 | /* Sprite */ 98 | sprite.rotation += 0.01; 99 | 100 | engine.renderer.render(engine.stage); 101 | fpsMeter.tick(); 102 | } // render 103 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ "./src/**/*.ts" ], 3 | "compilerOptions": { 4 | /* Basic Options */ 5 | "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ 6 | "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 7 | // "lib": [], /* Specify library files to be included in the compilation: */ 8 | // "allowJs": true, /* Allow javascript files to be compiled. */ 9 | // "checkJs": true, /* Report errors in .js files. */ 10 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 11 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 12 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 13 | // "outFile": "./", /* Concatenate and emit output to single file. */ 14 | // "outDir": "./dist/", /* Redirect output structure to the directory. */ 15 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 16 | "removeComments": true, /* Do not emit comments to output. */ 17 | // "noEmit": true, /* Do not emit outputs. */ 18 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 19 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 20 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 21 | 22 | /* Strict Type-Checking Options */ 23 | "strict": true, /* Enable all strict type-checking options. */ 24 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 25 | // "strictNullChecks": true, /* Enable strict null checks. */ 26 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 27 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 28 | 29 | /* Additional Checks */ 30 | "noUnusedLocals": true, /* Report errors on unused locals. */ 31 | "noUnusedParameters": true, /* Report errors on unused parameters. */ 32 | "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 33 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */ 34 | 35 | /* Module Resolution Options */ 36 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 37 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 38 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 39 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 40 | // "typeRoots": [], /* List of folders to include type definitions from. */ 41 | // "types": [], /* Type declaration files to be included in compilation. */ 42 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 43 | 44 | /* Source Map Options */ 45 | // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 46 | // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ 47 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 48 | // "inlineSources": true /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 49 | 50 | /* Experimental Options */ 51 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 52 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 53 | } 54 | } 55 | --------------------------------------------------------------------------------