diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json new file mode 100644 index 0000000..c259ab0 --- /dev/null +++ b/frontend/.eslintrc.json @@ -0,0 +1,28 @@ +{ + "root": true, + "env": { + "browser": true, + "es2020": true + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 11, + "sourceType": "module" + }, + "plugins": ["unused-imports", "@typescript-eslint", "prettier"], + "rules": { + "prettier/prettier": "error", + "no-unused-vars": "off", + "unused-imports/no-unused-imports-ts": "error", + "@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }], + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/explicit-module-boundary-types": "off" + } +} diff --git a/frontend/.prettierrc b/frontend/.prettierrc index 53d01de..5aae580 100644 --- a/frontend/.prettierrc +++ b/frontend/.prettierrc @@ -1,6 +1,6 @@ { "trailingComma": "es5", - "printWidth": 120, + "printWidth": 90, "tabWidth": 2, "singleQuote": true, "endOfLine": "lf" diff --git a/frontend/package.json b/frontend/package.json index 6635543..9df77ff 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,6 +6,7 @@ "main": "index.js", "scripts": { "start": "webpack-dev-server --mode development", + "lint": "npx eslint --fix \"src/**/*.ts\" && npx prettier --write \"src/**/*.ts\"", "build": "webpack && find dist -type f -not -name '*.html' | xargs rm" }, "keywords": [], @@ -27,10 +28,16 @@ "devDependencies": { "@types/gl-matrix": "^2.4.5", "@types/uuid": "^8.0.0", + "@typescript-eslint/eslint-plugin": "^3.9.1", + "@typescript-eslint/parser": "^3.9.1", "autoprefixer": "^9.8.5", "clean-webpack-plugin": "^3.0.0", "css-loader": "^3.5.2", "cssnano": "^4.1.10", + "eslint": "^7.2.0", + "eslint-config-prettier": "^6.11.0", + "eslint-plugin-import": "^2.21.2", + "eslint-plugin-prettier": "^3.1.4", "gl-matrix": "^3.3.0", "html-webpack-inline-source-plugin": "0.0.10", "html-webpack-plugin": "^3.2.0", diff --git a/frontend/src/scripts/commands/command-broadcaster.ts b/frontend/src/scripts/commands/command-broadcaster.ts index 8703fcf..256a002 100644 --- a/frontend/src/scripts/commands/command-broadcaster.ts +++ b/frontend/src/scripts/commands/command-broadcaster.ts @@ -6,8 +6,6 @@ export class CommandBroadcaster { commandGenerators: Array, commandReceivers: Array ) { - commandReceivers.forEach((r) => - commandGenerators.forEach((g) => g.subscribe(r)) - ); + commandReceivers.forEach((r) => commandGenerators.forEach((g) => g.subscribe(r))); } } diff --git a/frontend/src/scripts/drawing/drawables/drawable-blob.ts b/frontend/src/scripts/drawing/drawables/drawable-blob.ts index cf9da86..9a63575 100644 --- a/frontend/src/scripts/drawing/drawables/drawable-blob.ts +++ b/frontend/src/scripts/drawing/drawables/drawable-blob.ts @@ -1,8 +1,8 @@ +import { mat2d, vec2 } from 'gl-matrix'; +import { Blob } from '../../shapes/types/blob'; +import { settings } from '../settings'; import { IDrawable } from './i-drawable'; import { IDrawableDescriptor } from './i-drawable-descriptor'; -import { settings } from '../settings'; -import { Blob } from '../../shapes/types/blob'; -import { vec2, mat2d } from 'gl-matrix'; export class DrawableBlob extends Blob implements IDrawable { public static descriptor: IDrawableDescriptor = { @@ -11,32 +11,16 @@ export class DrawableBlob extends Blob implements IDrawable { shaderCombinationSteps: settings.shaderCombinations.blobSteps, }; - public serializeToUniforms( - uniforms: any, - scale: number, - transform: mat2d - ): void { - const uniformName = DrawableBlob.descriptor.uniformName; - if (!uniforms.hasOwnProperty(uniformName)) { + public serializeToUniforms(uniforms: any, scale: number, transform: mat2d): void { + const { uniformName } = DrawableBlob.descriptor; + if (!Object.prototype.hasOwnProperty.call(uniforms, uniformName)) { uniforms[uniformName] = []; } uniforms[uniformName].push({ - headCenter: vec2.transformMat2d( - vec2.create(), - this.head.center, - transform - ), - torsoCenter: vec2.transformMat2d( - vec2.create(), - this.torso.center, - transform - ), - leftFootCenter: vec2.transformMat2d( - vec2.create(), - this.leftFoot.center, - transform - ), + headCenter: vec2.transformMat2d(vec2.create(), this.head.center, transform), + torsoCenter: vec2.transformMat2d(vec2.create(), this.torso.center, transform), + leftFootCenter: vec2.transformMat2d(vec2.create(), this.leftFoot.center, transform), rightFootCenter: vec2.transformMat2d( vec2.create(), this.rightFoot.center, diff --git a/frontend/src/scripts/drawing/drawables/drawable-tunnel.ts b/frontend/src/scripts/drawing/drawables/drawable-tunnel.ts index 40b4072..ff734d7 100644 --- a/frontend/src/scripts/drawing/drawables/drawable-tunnel.ts +++ b/frontend/src/scripts/drawing/drawables/drawable-tunnel.ts @@ -1,8 +1,8 @@ -import { IDrawable } from './i-drawable'; -import { TunnelShape } from '../../shapes/types/tunnel-shape'; -import { IDrawableDescriptor } from './i-drawable-descriptor'; -import { settings } from '../settings'; import { mat2d, vec2 } from 'gl-matrix'; +import TunnelShape from '../../shapes/types/tunnel-shape'; +import { settings } from '../settings'; +import { IDrawable } from './i-drawable'; +import { IDrawableDescriptor } from './i-drawable-descriptor'; export class DrawableTunnel extends TunnelShape implements IDrawable { public static descriptor: IDrawableDescriptor = { @@ -11,23 +11,15 @@ export class DrawableTunnel extends TunnelShape implements IDrawable { shaderCombinationSteps: settings.shaderCombinations.lineSteps, }; - public serializeToUniforms( - uniforms: any, - scale: number, - transform: mat2d - ): void { - const uniformName = DrawableTunnel.descriptor.uniformName; - if (!uniforms.hasOwnProperty(uniformName)) { + public serializeToUniforms(uniforms: any, scale: number, transform: mat2d): void { + const { uniformName } = DrawableTunnel.descriptor; + if (!Object.prototype.hasOwnProperty.call(uniforms, uniformName)) { uniforms[uniformName] = []; } uniforms[uniformName].push({ from: vec2.transformMat2d(vec2.create(), this.from, transform), - toFromDelta: vec2.transformMat2d( - vec2.create(), - this.toFromDelta, - transform - ), + toFromDelta: vec2.transformMat2d(vec2.create(), this.toFromDelta, transform), fromRadius: this.fromRadius * scale, toRadius: this.toRadius * scale, }); diff --git a/frontend/src/scripts/drawing/drawables/lights/circle-light.ts b/frontend/src/scripts/drawing/drawables/lights/circle-light.ts index 4122e1c..3bb9674 100644 --- a/frontend/src/scripts/drawing/drawables/lights/circle-light.ts +++ b/frontend/src/scripts/drawing/drawables/lights/circle-light.ts @@ -1,5 +1,4 @@ -import { vec2, vec3, mat2d } from 'gl-matrix'; -import { GameObject } from '../../../objects/game-object'; +import { mat2d, vec2, vec3 } from 'gl-matrix'; import { settings } from '../../settings'; import { IDrawableDescriptor } from '../i-drawable-descriptor'; import { ILight } from './i-light'; @@ -22,14 +21,10 @@ export class CircleLight implements ILight { return 0; } - public serializeToUniforms( - uniforms: any, - scale: number, - transform: mat2d - ): void { - const uniformName = CircleLight.descriptor.uniformName; + public serializeToUniforms(uniforms: any, scale: number, transform: mat2d): void { + const { uniformName } = CircleLight.descriptor; - if (!uniforms.hasOwnProperty(uniformName)) { + if (!Object.prototype.hasOwnProperty.call(uniforms, uniformName)) { uniforms[uniformName] = []; } diff --git a/frontend/src/scripts/drawing/drawables/lights/i-light.ts b/frontend/src/scripts/drawing/drawables/lights/i-light.ts index 3739bf0..59e4431 100644 --- a/frontend/src/scripts/drawing/drawables/lights/i-light.ts +++ b/frontend/src/scripts/drawing/drawables/lights/i-light.ts @@ -1,4 +1,3 @@ -import { vec2 } from 'gl-matrix'; import { IDrawable } from '../i-drawable'; -export interface ILight extends IDrawable {} +export type ILight = IDrawable; diff --git a/frontend/src/scripts/drawing/drawables/lights/point-light.ts b/frontend/src/scripts/drawing/drawables/lights/point-light.ts index 0417e78..71cb42e 100644 --- a/frontend/src/scripts/drawing/drawables/lights/point-light.ts +++ b/frontend/src/scripts/drawing/drawables/lights/point-light.ts @@ -1,8 +1,7 @@ -import { ILight } from './i-light'; -import { vec2, vec3, mat2d } from 'gl-matrix'; -import { IDrawableDescriptor } from '../i-drawable-descriptor'; +import { mat2d, vec2, vec3 } from 'gl-matrix'; import { settings } from '../../settings'; -import { GameObject } from '../../../objects/game-object'; +import { IDrawableDescriptor } from '../i-drawable-descriptor'; +import { ILight } from './i-light'; export class PointLight implements ILight { public static descriptor: IDrawableDescriptor = { @@ -22,14 +21,10 @@ export class PointLight implements ILight { return vec2.distance(this.center, target) - this.radius; } - public serializeToUniforms( - uniforms: any, - scale: number, - transform: mat2d - ): void { + public serializeToUniforms(uniforms: any, scale: number, transform: mat2d): void { const listName = PointLight.descriptor.uniformName; - if (!uniforms.hasOwnProperty(listName)) { + if (!Object.prototype.hasOwnProperty.call(uniforms, listName)) { uniforms[listName] = []; } diff --git a/frontend/src/scripts/drawing/graphics-library/frame-buffer/default-frame-buffer.ts b/frontend/src/scripts/drawing/graphics-library/frame-buffer/default-frame-buffer.ts index 07290dd..1e697b7 100644 --- a/frontend/src/scripts/drawing/graphics-library/frame-buffer/default-frame-buffer.ts +++ b/frontend/src/scripts/drawing/graphics-library/frame-buffer/default-frame-buffer.ts @@ -11,10 +11,7 @@ export class DefaultFrameBuffer extends FrameBuffer { public setSize() { super.setSize(); - if ( - this.gl.canvas.width !== this.size.x || - this.gl.canvas.height !== this.size.y - ) { + if (this.gl.canvas.width !== this.size.x || this.gl.canvas.height !== this.size.y) { this.gl.canvas.width = this.size.x; this.gl.canvas.height = this.size.y; } diff --git a/frontend/src/scripts/drawing/graphics-library/frame-buffer/frame-buffer.ts b/frontend/src/scripts/drawing/graphics-library/frame-buffer/frame-buffer.ts index aeee6e1..8259ba5 100644 --- a/frontend/src/scripts/drawing/graphics-library/frame-buffer/frame-buffer.ts +++ b/frontend/src/scripts/drawing/graphics-library/frame-buffer/frame-buffer.ts @@ -2,9 +2,11 @@ import { vec2 } from 'gl-matrix'; export abstract class FrameBuffer { public renderScale = 1; + public enableHighDpiRendering = false; protected size: vec2; + protected frameBuffer: WebGLFramebuffer; constructor(protected gl: WebGL2RenderingContext) {} diff --git a/frontend/src/scripts/drawing/graphics-library/helper/enable-extension.ts b/frontend/src/scripts/drawing/graphics-library/helper/enable-extension.ts index 0425e8e..6989983 100644 --- a/frontend/src/scripts/drawing/graphics-library/helper/enable-extension.ts +++ b/frontend/src/scripts/drawing/graphics-library/helper/enable-extension.ts @@ -1,7 +1,4 @@ -export const enableExtension = ( - gl: WebGL2RenderingContext, - name: string -): any => { +export const enableExtension = (gl: WebGL2RenderingContext, name: string): any => { if (gl.getSupportedExtensions().indexOf(name) == -1) { throw new Error(`Unsupported extension ${name}`); } diff --git a/frontend/src/scripts/drawing/graphics-library/helper/get-webgl2-context.ts b/frontend/src/scripts/drawing/graphics-library/helper/get-webgl2-context.ts index 426004c..30abe93 100644 --- a/frontend/src/scripts/drawing/graphics-library/helper/get-webgl2-context.ts +++ b/frontend/src/scripts/drawing/graphics-library/helper/get-webgl2-context.ts @@ -1,6 +1,4 @@ -export const getWebGl2Context = ( - canvas: HTMLCanvasElement -): WebGL2RenderingContext => { +export const getWebGl2Context = (canvas: HTMLCanvasElement): WebGL2RenderingContext => { const gl = canvas.getContext('webgl2'); if (!gl) { diff --git a/frontend/src/scripts/drawing/graphics-library/helper/load-uniform.ts b/frontend/src/scripts/drawing/graphics-library/helper/load-uniform.ts index 9a2a16d..821816c 100644 --- a/frontend/src/scripts/drawing/graphics-library/helper/load-uniform.ts +++ b/frontend/src/scripts/drawing/graphics-library/helper/load-uniform.ts @@ -10,11 +10,7 @@ export const loadUniform = ( ): any => { const converters: Map< GLenum, - ( - gl: WebGL2RenderingContext, - value: any, - location: WebGLUniformLocation - ) => void + (gl: WebGL2RenderingContext, value: any, location: WebGLUniformLocation) => void > = new Map(); { converters.set(WebGL2RenderingContext.FLOAT, (gl, v, l) => { @@ -29,27 +25,24 @@ export const loadUniform = ( } }); - converters.set( - WebGL2RenderingContext.FLOAT_VEC2, - (gl, v: vec2 | Array, l) => { - if (v.length == 0) { - return; - } - - if (v[0] instanceof Array) { - const result = new Float32Array(v.length * 2); - - for (let i = 0; i < v.length; i++) { - result[2 * i] = (v[i] as Array).x; - result[2 * i + 1] = (v[i] as Array).y; - } - - gl.uniform2fv(l, result); - } else { - gl.uniform2fv(l, v as vec2); - } + converters.set(WebGL2RenderingContext.FLOAT_VEC2, (gl, v: vec2 | Array, l) => { + if (v.length == 0) { + return; } - ); + + if (v[0] instanceof Array) { + const result = new Float32Array(v.length * 2); + + for (let i = 0; i < v.length; i++) { + result[2 * i] = (v[i] as Array).x; + result[2 * i + 1] = (v[i] as Array).y; + } + + gl.uniform2fv(l, result); + } else { + gl.uniform2fv(l, v as vec2); + } + }); converters.set( WebGL2RenderingContext.FLOAT_VEC3, @@ -78,9 +71,7 @@ export const loadUniform = ( gl.uniformMatrix3fv(l, true, mat3.fromMat2d(loaderMat3, v)); }); - converters.set(WebGL2RenderingContext.BOOL, (gl, v, l) => - gl.uniform1i(l, v) - ); + converters.set(WebGL2RenderingContext.BOOL, (gl, v, l) => gl.uniform1i(l, v)); if (!converters.has(type)) { throw new Error(`Unimplemented webgl type: ${type}`); diff --git a/frontend/src/scripts/drawing/graphics-library/helper/stopwatch.ts b/frontend/src/scripts/drawing/graphics-library/helper/stopwatch.ts index cae7874..3937fae 100644 --- a/frontend/src/scripts/drawing/graphics-library/helper/stopwatch.ts +++ b/frontend/src/scripts/drawing/graphics-library/helper/stopwatch.ts @@ -5,16 +5,15 @@ import { enableExtension } from './enable-extension'; export class WebGlStopwatch { private timerExtension: any; + private timerQuery: WebGLQuery; + private isReady = true; private resultsInNanoSeconds: number; constructor(private gl: WebGL2RenderingContext) { - this.timerExtension = enableExtension( - gl, - 'EXT_disjoint_timer_query_webgl2' - ); + this.timerExtension = enableExtension(gl, 'EXT_disjoint_timer_query_webgl2'); } public start() { @@ -42,10 +41,7 @@ export class WebGlStopwatch { this.gl.QUERY_RESULT ); - InfoText.modifyRecord( - 'Draw time', - `${this.resultsInMilliSeconds.toFixed(2)} ms` - ); + InfoText.modifyRecord('Draw time', `${this.resultsInMilliSeconds.toFixed(2)} ms`); this.isReady = true; } diff --git a/frontend/src/scripts/drawing/graphics-library/program/fragment-shader-only-program.ts b/frontend/src/scripts/drawing/graphics-library/program/fragment-shader-only-program.ts index 568c760..beba0b9 100644 --- a/frontend/src/scripts/drawing/graphics-library/program/fragment-shader-only-program.ts +++ b/frontend/src/scripts/drawing/graphics-library/program/fragment-shader-only-program.ts @@ -1,4 +1,4 @@ -import { Program } from './program'; +import Program from './program'; export class FragmentShaderOnlyProgram extends Program { private vao: WebGLVertexArrayObject; @@ -39,13 +39,6 @@ export class FragmentShaderOnlyProgram extends Program { this.gl.bindVertexArray(this.vao); this.gl.enableVertexAttribArray(positionAttributeLocation); - this.gl.vertexAttribPointer( - positionAttributeLocation, - 2, - this.gl.FLOAT, - false, - 0, - 0 - ); + this.gl.vertexAttribPointer(positionAttributeLocation, 2, this.gl.FLOAT, false, 0, 0); } } diff --git a/frontend/src/scripts/drawing/graphics-library/program/program.ts b/frontend/src/scripts/drawing/graphics-library/program/program.ts index fd91937..a657b2a 100644 --- a/frontend/src/scripts/drawing/graphics-library/program/program.ts +++ b/frontend/src/scripts/drawing/graphics-library/program/program.ts @@ -3,10 +3,13 @@ import { createShader } from '../helper/create-shader'; import { loadUniform } from '../helper/load-uniform'; import { IProgram } from './i-program'; -export abstract class Program implements IProgram { +export default abstract class Program implements IProgram { protected program: WebGLProgram; + private shaders: Array = []; + private modelTransform = mat2d.identity(mat2d.create()); + private readonly ndcToUv: mat2d; private uniforms: Array<{ @@ -116,10 +119,7 @@ export abstract class Program implements IProgram { this.gl.linkProgram(this.program); - const success = this.gl.getProgramParameter( - this.program, - this.gl.LINK_STATUS - ); + const success = this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS); if (!success) { throw new Error(this.gl.getProgramInfoLog(this.program)); diff --git a/frontend/src/scripts/drawing/graphics-library/program/uniform-array-autoscaling-program.ts b/frontend/src/scripts/drawing/graphics-library/program/uniform-array-autoscaling-program.ts index 5e63510..5fb2772 100644 --- a/frontend/src/scripts/drawing/graphics-library/program/uniform-array-autoscaling-program.ts +++ b/frontend/src/scripts/drawing/graphics-library/program/uniform-array-autoscaling-program.ts @@ -1,18 +1,20 @@ import { vec2 } from 'gl-matrix'; +import { getCombinations } from '../../../helper/get-combinations'; +import { last } from '../../../helper/last'; +import { IDrawableDescriptor } from '../../drawables/i-drawable-descriptor'; import { FragmentShaderOnlyProgram } from './fragment-shader-only-program'; import { IProgram } from './i-program'; -import { last } from '../../../helper/last'; -import { getCombinations } from '../../../helper/get-combinations'; -import { IDrawableDescriptor } from '../../drawables/i-drawable-descriptor'; export class UniformArrayAutoScalingProgram implements IProgram { private programs: Array<{ program: FragmentShaderOnlyProgram; values: Array; }> = []; + private current: FragmentShaderOnlyProgram; private drawingRectangleTopLeft = vec2.fromValues(0, 0); + private drawingRectangleSize = vec2.fromValues(1, 1); constructor( @@ -21,7 +23,7 @@ export class UniformArrayAutoScalingProgram implements IProgram { private options: Array ) { const names = options.map((o) => o.countMacroName); - for (let combination of getCombinations( + for (const combination of getCombinations( options.map((o) => o.shaderCombinationSteps) )) { this.createProgram(names, combination, shaderSources); @@ -29,13 +31,11 @@ export class UniformArrayAutoScalingProgram implements IProgram { } public bindAndSetUniforms(uniforms: { [name: string]: any }): void { - let values = this.options.map((o) => + const values = this.options.map((o) => uniforms[o.uniformName] ? uniforms[o.uniformName].length : 0 ); - const closest = this.programs.find((p) => - p.values.every((v, i) => v >= values[i]) - ); + const closest = this.programs.find((p) => p.values.every((v, i) => v >= values[i])); this.current = closest ? closest.program : last(this.programs).program; @@ -67,11 +67,7 @@ export class UniformArrayAutoScalingProgram implements IProgram { const substitutions = {}; names.forEach((v, i) => (substitutions[v] = combination[i].toString())); - const program = new FragmentShaderOnlyProgram( - this.gl, - shaderSources, - substitutions - ); + const program = new FragmentShaderOnlyProgram(this.gl, shaderSources, substitutions); this.programs.push({ program, diff --git a/frontend/src/scripts/drawing/i-renderer.ts b/frontend/src/scripts/drawing/i-renderer.ts index dd19304..ed666c8 100644 --- a/frontend/src/scripts/drawing/i-renderer.ts +++ b/frontend/src/scripts/drawing/i-renderer.ts @@ -1,7 +1,7 @@ import { vec2 } from 'gl-matrix'; -import { ILight } from './drawables/lights/i-light'; -import { IDrawable } from './drawables/i-drawable'; import { BoundingBoxBase } from '../shapes/bounding-box-base'; +import { IDrawable } from './drawables/i-drawable'; +import { ILight } from './drawables/lights/i-light'; export interface IRenderer { startFrame(deltaTime: DOMHighResTimeStamp): void; diff --git a/frontend/src/scripts/drawing/rendering/fps-autoscaler.ts b/frontend/src/scripts/drawing/rendering/fps-autoscaler.ts index 72fee3f..fdb6067 100644 --- a/frontend/src/scripts/drawing/rendering/fps-autoscaler.ts +++ b/frontend/src/scripts/drawing/rendering/fps-autoscaler.ts @@ -7,6 +7,7 @@ import { toPercent } from '../../helper/to-percent'; export class FpsAutoscaler extends Autoscaler { private timeSinceLastAdjusment = 0; + private exponentialDecayedDeltaTime = 0.0; constructor(private frameBuffers: Array) { @@ -21,8 +22,7 @@ export class FpsAutoscaler extends Autoscaler { public autoscale(lastDeltaTime: DOMHighResTimeStamp) { this.timeSinceLastAdjusment += lastDeltaTime; if ( - this.timeSinceLastAdjusment >= - settings.qualityScaling.adjusmentRateInMilliseconds + this.timeSinceLastAdjusment >= settings.qualityScaling.adjusmentRateInMilliseconds ) { this.timeSinceLastAdjusment = 0; this.exponentialDecayedDeltaTime = exponentialDecay( diff --git a/frontend/src/scripts/drawing/rendering/rendering-pass.ts b/frontend/src/scripts/drawing/rendering/rendering-pass.ts index 22d9908..6c44767 100644 --- a/frontend/src/scripts/drawing/rendering/rendering-pass.ts +++ b/frontend/src/scripts/drawing/rendering/rendering-pass.ts @@ -1,4 +1,4 @@ -import { vec2, mat2d } from 'gl-matrix'; +import { mat2d, vec2 } from 'gl-matrix'; import { InfoText } from '../../objects/types/info-text'; import { IDrawable } from '../drawables/i-drawable'; import { IDrawableDescriptor } from '../drawables/i-drawable-descriptor'; @@ -8,6 +8,7 @@ import { settings } from '../settings'; export class RenderingPass { private drawables: Array = []; + private program: UniformArrayAutoScalingProgram; constructor( @@ -83,17 +84,13 @@ export class RenderingPass { } InfoText.modifyRecord( - 'nearby ' + this.drawableDescriptors[0].countMacroName, + `nearby ${this.drawableDescriptors[0].countMacroName}`, this.drawables.length.toFixed(2) ); InfoText.modifyRecord( - 'drawn ' + this.drawableDescriptors[0].countMacroName, - ( - sumLineCount / - settings.tileMultiplier / - settings.tileMultiplier - ).toFixed(2) + `drawn ${this.drawableDescriptors[0].countMacroName}`, + (sumLineCount / settings.tileMultiplier / settings.tileMultiplier).toFixed(2) ); this.drawables = []; diff --git a/frontend/src/scripts/drawing/rendering/webgl2-renderer.ts b/frontend/src/scripts/drawing/rendering/webgl2-renderer.ts index d036f51..38c6833 100644 --- a/frontend/src/scripts/drawing/rendering/webgl2-renderer.ts +++ b/frontend/src/scripts/drawing/rendering/webgl2-renderer.ts @@ -1,4 +1,8 @@ import { mat2d, vec2 } from 'gl-matrix'; +import { BoundingBoxBase } from '../../shapes/bounding-box-base'; +import { DrawableBlob } from '../drawables/drawable-blob'; +import { DrawableTunnel } from '../drawables/drawable-tunnel'; +import { IDrawable } from '../drawables/i-drawable'; import { CircleLight } from '../drawables/lights/circle-light'; import { ILight } from '../drawables/lights/i-light'; import { PointLight } from '../drawables/lights/point-light'; @@ -14,23 +18,24 @@ import caveVertexShader from '../shaders/passthrough-distance-vs.glsl'; import lightsVertexShader from '../shaders/passthrough-shading-vs.glsl'; import { FpsAutoscaler } from './fps-autoscaler'; import { RenderingPass } from './rendering-pass'; -import { IDrawable } from '../drawables/i-drawable'; -import { DrawableTunnel } from '../drawables/drawable-tunnel'; -import { enableExtension } from '../graphics-library/helper/enable-extension'; -import { DrawableBlob } from '../drawables/drawable-blob'; -import { BoundingBoxBase } from '../../shapes/bounding-box-base'; export class WebGl2Renderer implements IRenderer { private gl: WebGL2RenderingContext; + private stopwatch?: WebGlStopwatch; private viewBoxBottomLeft = vec2.create(); + private viewBoxSize = vec2.create(); + private cursorPosition = vec2.create(); private distanceFieldFrameBuffer: IntermediateFrameBuffer; + private lightingFrameBuffer: DefaultFrameBuffer; + private distancePass: RenderingPass; + private lightingPass: RenderingPass; private autoscaler: FpsAutoscaler; @@ -70,7 +75,9 @@ export class WebGl2Renderer implements IRenderer { try { this.stopwatch = new WebGlStopwatch(this.gl); - } catch {} + } catch { + // no problem + } } public drawShape(shape: IDrawable) { @@ -81,7 +88,7 @@ export class WebGl2Renderer implements IRenderer { this.lightingPass.addDrawable(light); } - public startFrame(deltaTime: DOMHighResTimeStamp): void { + public startFrame(deltaTime: DOMHighResTimeStamp) { this.autoscaler.autoscale(deltaTime); this.stopwatch?.start(); @@ -94,10 +101,7 @@ export class WebGl2Renderer implements IRenderer { this.distancePass.render(this.uniforms); - this.lightingPass.render( - this.uniforms, - this.distanceFieldFrameBuffer.colorTexture - ); + this.lightingPass.render(this.uniforms, this.distanceFieldFrameBuffer.colorTexture); this.stopwatch?.stop(); } @@ -112,11 +116,7 @@ export class WebGl2Renderer implements IRenderer { mat2d.create(), this.viewBoxBottomLeft ); - mat2d.scale( - this.matrices.uvToWorld, - this.matrices.uvToWorld, - this.viewBoxSize - ); + mat2d.scale(this.matrices.uvToWorld, this.matrices.uvToWorld, this.viewBoxSize); this.matrices.distanceScreenToWorld = this.getScreenToWorldTransform( this.distanceFieldFrameBuffer.getSize() @@ -127,17 +127,11 @@ export class WebGl2Renderer implements IRenderer { this.matrices.distanceScreenToWorld, this.distanceFieldFrameBuffer.getSize() ); - mat2d.invert( - this.matrices.worldToDistanceUV, - this.matrices.worldToDistanceUV - ); + mat2d.invert(this.matrices.worldToDistanceUV, this.matrices.worldToDistanceUV); } private getScreenToWorldTransform(screenSize: vec2) { - const transform = mat2d.fromTranslation( - mat2d.create(), - this.viewBoxBottomLeft - ); + const transform = mat2d.fromTranslation(mat2d.create(), this.viewBoxBottomLeft); mat2d.scale( transform, transform, diff --git a/frontend/src/scripts/drawing/settings.ts b/frontend/src/scripts/drawing/settings.ts index 0c1a66e..5ea8610 100644 --- a/frontend/src/scripts/drawing/settings.ts +++ b/frontend/src/scripts/drawing/settings.ts @@ -8,11 +8,11 @@ export const settings = { [0.2, 0.1], [0.6, 0.1], [1, 1], - /*[1.25, 0.75], + /* [1.25, 0.75], [1.5, 1], [1.75, 1.25], [1.75, 1.75], - [2, 2],*/ + [2, 2], */ ], startingTargetIndex: 2, scalingOptions: { diff --git a/frontend/src/scripts/game.ts b/frontend/src/scripts/game.ts index 65f1150..20a26ed 100644 --- a/frontend/src/scripts/game.ts +++ b/frontend/src/scripts/game.ts @@ -1,38 +1,41 @@ import { CommandBroadcaster } from './commands/command-broadcaster'; import { BeforeRenderCommand } from './drawing/commands/before-render'; -import { StepCommand } from './physics/commands/step'; +import { RenderCommand } from './drawing/commands/render'; +import { IRenderer } from './drawing/i-renderer'; import { WebGl2Renderer } from './drawing/rendering/webgl2-renderer'; +import { Random } from './helper/random'; import { timeIt } from './helper/timing'; +import { IGame } from './i-game'; import { KeyboardListener } from './input/keyboard-listener'; import { MouseListener } from './input/mouse-listener'; import { TouchListener } from './input/touch-listener'; +import { GameObject } from './objects/game-object'; import { Objects } from './objects/objects'; -import { InfoText } from './objects/types/info-text'; -import { createDungeon } from './objects/world/create-dungeon'; -import { RenderCommand } from './drawing/commands/render'; -import { Physics } from './physics/physics'; -import { TeleportToCommand } from './physics/commands/teleport-to'; -import { IRenderer } from './drawing/i-renderer'; -import { Random } from './helper/random'; import { Camera } from './objects/types/camera'; import { Character } from './objects/types/character'; -import { IGame } from './i-game'; -import { GameObject } from './objects/game-object'; -import { vec2 } from 'gl-matrix'; -import { BoundingBoxBase } from './shapes/bounding-box-base'; +import { InfoText } from './objects/types/info-text'; +import { createDungeon } from './objects/world/create-dungeon'; import { MoveToCommand } from './physics/commands/move-to'; -import { BoundingBox } from './shapes/bounding-box'; +import { StepCommand } from './physics/commands/step'; +import { TeleportToCommand } from './physics/commands/teleport-to'; +import { Physics } from './physics/physics'; +import { BoundingBoxBase } from './shapes/bounding-box-base'; export class Game implements IGame { public readonly objects = new Objects(); + public readonly physics = new Physics(); + public readonly camera = new Camera(); private previousTime?: DOMHighResTimeStamp = null; + private previousFpsValues: Array = []; private infoText = new InfoText(); + private character: Character; + private renderer: IRenderer; constructor() { @@ -41,10 +44,7 @@ export class Game implements IGame { Random.seed = 42; - document.addEventListener( - 'visibilitychange', - this.handleVisibilityChange.bind(this) - ); + document.addEventListener('visibilitychange', this.handleVisibilityChange.bind(this)); new CommandBroadcaster( [ @@ -82,7 +82,7 @@ export class Game implements IGame { createDungeon(this.objects, this.physics); this.character = new Character(this); - //this.physics.addDynamicBoundingBox(this.character.boundingBox); + // this.physics.addDynamicBoundingBox(this.character.boundingBox); this.addObject(this.character); this.addObject(this.camera); this.character.sendCommand(new TeleportToCommand(start.from)); @@ -115,7 +115,7 @@ export class Game implements IGame { .findIntersecting(this.camera.viewArea) .map((b) => b.shape?.gameObject); - for (let object of shouldBeDrawn) { + for (const object of shouldBeDrawn) { object?.sendCommand(new BeforeRenderCommand(this.renderer)); object?.sendCommand(new RenderCommand(this.renderer)); } diff --git a/frontend/src/scripts/helper/array.ts b/frontend/src/scripts/helper/array.ts index 7523b4f..bcde98b 100644 --- a/frontend/src/scripts/helper/array.ts +++ b/frontend/src/scripts/helper/array.ts @@ -12,37 +12,37 @@ declare global { export const applyArrayPlugins = () => { Object.defineProperty(Array.prototype, 'x', { - get: function () { + get() { return this[0]; }, - set: function (value) { + set(value) { this[0] = value; }, }); Object.defineProperty(Array.prototype, 'y', { - get: function () { + get() { return this[1]; }, - set: function (value) { + set(value) { this[1] = value; }, }); Object.defineProperty(Float32Array.prototype, 'x', { - get: function () { + get() { return this[0]; }, - set: function (value) { + set(value) { this[0] = value; }, }); Object.defineProperty(Float32Array.prototype, 'y', { - get: function () { + get() { return this[1]; }, - set: function (value) { + set(value) { this[1] = value; }, }); diff --git a/frontend/src/scripts/helper/autoscaler.ts b/frontend/src/scripts/helper/autoscaler.ts index e4d7557..f427105 100644 --- a/frontend/src/scripts/helper/autoscaler.ts +++ b/frontend/src/scripts/helper/autoscaler.ts @@ -36,9 +36,7 @@ export class Autoscaler { const previousTarget = this.targets[floor]; const nextTarget = - floor + 1 == this.targets.length - ? previousTarget - : this.targets[floor + 1]; + floor + 1 == this.targets.length ? previousTarget : this.targets[floor + 1]; this.setters.forEach((setter, i) => setter(mix(previousTarget[i], nextTarget[i], fract)) diff --git a/frontend/src/scripts/helper/clamp.ts b/frontend/src/scripts/helper/clamp.ts index d1d639b..45da555 100644 --- a/frontend/src/scripts/helper/clamp.ts +++ b/frontend/src/scripts/helper/clamp.ts @@ -1,5 +1,4 @@ export const clamp = (value: number, min: number, max: number): number => Math.min(max, Math.max(min, value)); -export const clamp01 = (value: number): number => - Math.min(1, Math.max(0, value)); +export const clamp01 = (value: number): number => Math.min(1, Math.max(0, value)); diff --git a/frontend/src/scripts/helper/get-combinations.ts b/frontend/src/scripts/helper/get-combinations.ts index 4d298ab..42c36d6 100644 --- a/frontend/src/scripts/helper/get-combinations.ts +++ b/frontend/src/scripts/helper/get-combinations.ts @@ -1,6 +1,4 @@ -export const getCombinations = ( - values: Array> -): Array> => { +export const getCombinations = (values: Array>): Array> => { if (!values.every((a) => a.length > 0)) { return []; } diff --git a/frontend/src/scripts/helper/mix.ts b/frontend/src/scripts/helper/mix.ts index 6af50f8..16a76ed 100644 --- a/frontend/src/scripts/helper/mix.ts +++ b/frontend/src/scripts/helper/mix.ts @@ -1,2 +1 @@ -export const mix = (from: number, to: number, q: number) => - from + (to - from) * q; +export const mix = (from: number, to: number, q: number) => from + (to - from) * q; diff --git a/frontend/src/scripts/helper/timing.ts b/frontend/src/scripts/helper/timing.ts index 1e3be3a..a8a3148 100644 --- a/frontend/src/scripts/helper/timing.ts +++ b/frontend/src/scripts/helper/timing.ts @@ -18,9 +18,11 @@ export function timeIt(interval = 60) { if (i++ % interval == 0) { previousTimes = previousTimes.sort(); - const text = `Max: ${last(previousTimes).toFixed(2)} ms\n\tMedian: ${previousTimes[ - Math.floor(previousTimes.length / 2) - ].toFixed(2)} ms`; + const text = `Max: ${last(previousTimes).toFixed( + 2 + )} ms\n\tMedian: ${previousTimes[Math.floor(previousTimes.length / 2)].toFixed( + 2 + )} ms`; InfoText.modifyRecord(propertyKey, text); diff --git a/frontend/src/scripts/i-game.ts b/frontend/src/scripts/i-game.ts index 1a32748..0a4bfde 100644 --- a/frontend/src/scripts/i-game.ts +++ b/frontend/src/scripts/i-game.ts @@ -1,5 +1,4 @@ import { GameObject } from './objects/game-object'; -import { vec2 } from 'gl-matrix'; import { BoundingBoxBase } from './shapes/bounding-box-base'; export interface IGame { diff --git a/frontend/src/scripts/identity/identity-manager.ts b/frontend/src/scripts/identity/identity-manager.ts index 3fe5e6a..b743b9c 100644 --- a/frontend/src/scripts/identity/identity-manager.ts +++ b/frontend/src/scripts/identity/identity-manager.ts @@ -1,5 +1,5 @@ -import { Id } from './identity'; import { v4 } from 'uuid'; +import { Id } from './identity'; export class IdentityManager { public static generateId(): Id { diff --git a/frontend/src/scripts/input/commands/cursor-move-command.ts b/frontend/src/scripts/input/commands/cursor-move-command.ts index a5101c2..5116fa6 100644 --- a/frontend/src/scripts/input/commands/cursor-move-command.ts +++ b/frontend/src/scripts/input/commands/cursor-move-command.ts @@ -1,5 +1,5 @@ -import { Command } from '../../commands/command'; import { vec2 } from 'gl-matrix'; +import { Command } from '../../commands/command'; export class CursorMoveCommand extends Command { public constructor(public readonly position?: vec2) { diff --git a/frontend/src/scripts/input/mouse-listener.ts b/frontend/src/scripts/input/mouse-listener.ts index df4cf1a..055ca6e 100644 --- a/frontend/src/scripts/input/mouse-listener.ts +++ b/frontend/src/scripts/input/mouse-listener.ts @@ -1,5 +1,5 @@ -import { CommandGenerator } from '../commands/command-generator'; import { vec2 } from 'gl-matrix'; +import { CommandGenerator } from '../commands/command-generator'; import { clamp01 } from '../helper/clamp'; import { CursorMoveCommand } from './commands/cursor-move-command'; import { PrimaryActionCommand } from './commands/primary-action'; @@ -9,6 +9,7 @@ import { ZoomCommand } from './commands/zoom'; export class MouseListener extends CommandGenerator { private previousPosition = vec2.create(); + private isMouseDown = false; constructor(private target: Element) { @@ -30,9 +31,7 @@ export class MouseListener extends CommandGenerator { if (this.isMouseDown) { this.sendCommand( - new SwipeCommand( - vec2.subtract(vec2.create(), this.previousPosition, position) - ) + new SwipeCommand(vec2.subtract(vec2.create(), this.previousPosition, position)) ); this.previousPosition = position; } diff --git a/frontend/src/scripts/input/touch-listener.ts b/frontend/src/scripts/input/touch-listener.ts index e605cd4..99318f9 100644 --- a/frontend/src/scripts/input/touch-listener.ts +++ b/frontend/src/scripts/input/touch-listener.ts @@ -1,5 +1,5 @@ -import { CommandGenerator } from '../commands/command-generator'; import { vec2 } from 'gl-matrix'; +import { CommandGenerator } from '../commands/command-generator'; import { clamp01 } from '../helper/clamp'; import { PrimaryActionCommand } from './commands/primary-action'; import { SecondaryActionCommand } from './commands/secondary-action'; @@ -31,9 +31,7 @@ export class TouchListener extends CommandGenerator { const position = this.positionFromEvent(event); this.sendCommand( - new SwipeCommand( - vec2.subtract(vec2.create(), position, this.previousPosition) - ) + new SwipeCommand(vec2.subtract(vec2.create(), position, this.previousPosition)) ); this.previousPosition = position; diff --git a/frontend/src/scripts/objects/game-object.ts b/frontend/src/scripts/objects/game-object.ts index 3662f15..9a7f987 100644 --- a/frontend/src/scripts/objects/game-object.ts +++ b/frontend/src/scripts/objects/game-object.ts @@ -1,8 +1,6 @@ import { Command } from '../commands/command'; import { CommandReceiver } from '../commands/command-receiver'; import { IdentityManager } from '../identity/identity-manager'; -import { Objects } from './objects'; -import { Physics } from '../physics/physics'; export abstract class GameObject implements CommandReceiver { public readonly id = IdentityManager.generateId(); @@ -12,13 +10,13 @@ export abstract class GameObject implements CommandReceiver { } = {}; public reactsToCommand(commandType: string): boolean { - return this.commandExecutors.hasOwnProperty(commandType); + return Object.prototype.hasOwnProperty.call(this.commandExecutors, commandType); } public sendCommand(command: Command) { const commandType = command.type; - if (this.commandExecutors.hasOwnProperty(commandType)) { + if (Object.prototype.hasOwnProperty.call(this.commandExecutors, commandType)) { this.commandExecutors[commandType](command); } } diff --git a/frontend/src/scripts/objects/objects.ts b/frontend/src/scripts/objects/objects.ts index cc46933..2c681e2 100644 --- a/frontend/src/scripts/objects/objects.ts +++ b/frontend/src/scripts/objects/objects.ts @@ -5,12 +5,13 @@ import { GameObject } from './game-object'; export class Objects implements CommandReceiver { private objects: Map = new Map(); + private objectsGroupedByAbilities: Map> = new Map(); public addObject(o: GameObject) { this.objects.set(o.id, o); - for (let command of this.objectsGroupedByAbilities.keys()) { + for (const command of this.objectsGroupedByAbilities.keys()) { if (o.reactsToCommand(command)) { this.objectsGroupedByAbilities.get(command).push(o); } @@ -30,9 +31,7 @@ export class Objects implements CommandReceiver { this.createGroupForCommand(e.type); } - this.objectsGroupedByAbilities - .get(e.type) - .forEach((o, _) => o.sendCommand(e)); + this.objectsGroupedByAbilities.get(e.type).forEach((o, _) => o.sendCommand(e)); } private createGroupForCommand(commandType: string) { diff --git a/frontend/src/scripts/objects/types/camera.ts b/frontend/src/scripts/objects/types/camera.ts index 442d827..15c1a72 100644 --- a/frontend/src/scripts/objects/types/camera.ts +++ b/frontend/src/scripts/objects/types/camera.ts @@ -4,13 +4,12 @@ import { CursorMoveCommand } from '../../input/commands/cursor-move-command'; import { ZoomCommand } from '../../input/commands/zoom'; import { MoveToCommand } from '../../physics/commands/move-to'; import { BoundingBox } from '../../shapes/bounding-box'; -import { Physics } from '../../physics/physics'; import { GameObject } from '../game-object'; -import { Lamp } from './lamp'; export class Camera extends GameObject { private inViewAreaSize = 1920 * 1080 * 5; private cursorPosition = vec2.create(); + private _viewArea: BoundingBox; constructor() { diff --git a/frontend/src/scripts/objects/types/character.ts b/frontend/src/scripts/objects/types/character.ts index 4c8d228..236c87f 100644 --- a/frontend/src/scripts/objects/types/character.ts +++ b/frontend/src/scripts/objects/types/character.ts @@ -1,31 +1,25 @@ import { vec2, vec3 } from 'gl-matrix'; +import { RenderCommand } from '../../drawing/commands/render'; +import { DrawableBlob } from '../../drawing/drawables/drawable-blob'; +import { IGame } from '../../i-game'; import { KeyDownCommand } from '../../input/commands/key-down'; import { KeyUpCommand } from '../../input/commands/key-up'; import { SwipeCommand } from '../../input/commands/swipe'; import { MoveToCommand } from '../../physics/commands/move-to'; import { StepCommand } from '../../physics/commands/step'; import { TeleportToCommand } from '../../physics/commands/teleport-to'; -import { Physics } from '../../physics/physics'; -import { GameObject } from '../game-object'; -import { Camera } from './camera'; import { IShape } from '../../shapes/i-shape'; import { Blob } from '../../shapes/types/blob'; -import { RenderCommand } from '../../drawing/commands/render'; -import { DrawableBlob } from '../../drawing/drawables/drawable-blob'; +import { GameObject } from '../game-object'; import { Lamp } from './lamp'; -import { Game } from '../../game'; -import { IGame } from '../../i-game'; export class Character extends GameObject { private keysDown: Set = new Set(); - private light = new Lamp( - vec2.create(), - 40, - vec3.fromValues(0.67, 0.0, 0.33), - 2 - ); + + private light = new Lamp(vec2.create(), 40, vec3.fromValues(0.67, 0.0, 0.33), 2); private shape = new DrawableBlob(vec2.create()); + private static speed = 1.5; constructor(private game: IGame) { @@ -35,15 +29,11 @@ export class Character extends GameObject { this.addCommandExecutor(StepCommand, this.stepHandler.bind(this)); this.addCommandExecutor(RenderCommand, this.draw.bind(this)); - this.addCommandExecutor(TeleportToCommand, (c) => - this.setPosition(c.position) - ); + this.addCommandExecutor(TeleportToCommand, (c) => this.setPosition(c.position)); this.addCommandExecutor(KeyDownCommand, (c) => this.keysDown.add(c.key)); this.addCommandExecutor(KeyUpCommand, (c) => this.keysDown.delete(c.key)); this.addCommandExecutor(SwipeCommand, (c) => { - this.tryMoving( - vec2.multiply(vec2.create(), c.delta, this.game.viewArea.size) - ); + this.tryMoving(vec2.multiply(vec2.create(), c.delta, this.game.viewArea.size)); }); } @@ -90,9 +80,8 @@ export class Character extends GameObject { const intersecting = nextNearShapes .filter( (n) => - currentNearShapes.find( - (c) => c.shape === n.shape && c.distance <= 0 - ) !== undefined + currentNearShapes.find((c) => c.shape === n.shape && c.distance <= 0) !== + undefined ) .sort((e) => Math.abs(e.distance)); @@ -101,23 +90,16 @@ export class Character extends GameObject { } const normal = intersecting[0].shape.normal(this.shape.center); - const maxDistance = intersecting.reduce((p, c) => - p.distance > c.distance ? p : c - ).distance; + const maxDistance = intersecting.reduce((p, c) => (p.distance > c.distance ? p : c)) + .distance; - vec2.add( - delta, - delta, - vec2.scale(vec2.create(), normal, -maxDistance - 2) - ); + vec2.add(delta, delta, vec2.scale(vec2.create(), normal, -maxDistance - 2)); this.tryMoving(delta, false); } } - private getNearShapesTo( - shape: Blob - ): Array<{ shape: IShape; distance: number }> { + private getNearShapesTo(shape: Blob): Array<{ shape: IShape; distance: number }> { return this.game .findIntersecting(shape.boundingBox) .filter((b) => b.shape) diff --git a/frontend/src/scripts/objects/types/info-text.ts b/frontend/src/scripts/objects/types/info-text.ts index 88a88dc..1ab4e2a 100644 --- a/frontend/src/scripts/objects/types/info-text.ts +++ b/frontend/src/scripts/objects/types/info-text.ts @@ -1,5 +1,5 @@ -import { GameObject } from '../game-object'; import { RenderCommand } from '../../drawing/commands/render'; +import { GameObject } from '../game-object'; export class InfoText extends GameObject { constructor() { diff --git a/frontend/src/scripts/objects/types/lamp.ts b/frontend/src/scripts/objects/types/lamp.ts index 1e31d7d..80154d9 100644 --- a/frontend/src/scripts/objects/types/lamp.ts +++ b/frontend/src/scripts/objects/types/lamp.ts @@ -1,8 +1,8 @@ import { vec2, vec3 } from 'gl-matrix'; -import { GameObject } from '../game-object'; -import { CircleLight } from '../../drawing/drawables/lights/circle-light'; import { RenderCommand } from '../../drawing/commands/render'; +import { CircleLight } from '../../drawing/drawables/lights/circle-light'; import { MoveToCommand } from '../../physics/commands/move-to'; +import { GameObject } from '../game-object'; export class Lamp extends GameObject { private light: CircleLight; diff --git a/frontend/src/scripts/objects/types/tunnel.ts b/frontend/src/scripts/objects/types/tunnel.ts index 19927d8..351dc63 100644 --- a/frontend/src/scripts/objects/types/tunnel.ts +++ b/frontend/src/scripts/objects/types/tunnel.ts @@ -1,9 +1,8 @@ import { vec2 } from 'gl-matrix'; -import { GameObject } from '../game-object'; import { RenderCommand } from '../../drawing/commands/render'; -import { Physics } from '../../physics/physics'; -import { TunnelShape } from '../../shapes/types/tunnel-shape'; import { DrawableTunnel } from '../../drawing/drawables/drawable-tunnel'; +import { Physics } from '../../physics/physics'; +import { GameObject } from '../game-object'; export class Tunnel extends GameObject { private shape: DrawableTunnel; diff --git a/frontend/src/scripts/objects/world/create-dungeon.ts b/frontend/src/scripts/objects/world/create-dungeon.ts index 82ad0fd..9b800e2 100644 --- a/frontend/src/scripts/objects/world/create-dungeon.ts +++ b/frontend/src/scripts/objects/world/create-dungeon.ts @@ -30,7 +30,7 @@ export const createDungeon = (objects: Objects, physics: Physics): Tunnel => { objects.addObject(tunnel); - /*if (deltaHeight > 0 && Random.getRandom() > 0.8) { + /* if (deltaHeight > 0 && Random.getRandom() > 0.8) { objects.addObject( new Lamp( currentEnd, @@ -43,7 +43,7 @@ export const createDungeon = (objects: Objects, physics: Physics): Tunnel => { 1 ) ); - }*/ + } */ previousEnd = currentEnd; previousRadius = currentToRadius; diff --git a/frontend/src/scripts/physics/commands/step.ts b/frontend/src/scripts/physics/commands/step.ts index 8df26a5..301597c 100644 --- a/frontend/src/scripts/physics/commands/step.ts +++ b/frontend/src/scripts/physics/commands/step.ts @@ -1,9 +1,7 @@ import { Command } from '../../commands/command'; export class StepCommand extends Command { - public constructor( - public readonly deltaTimeInMiliseconds?: DOMHighResTimeStamp - ) { + public constructor(public readonly deltaTimeInMiliseconds?: DOMHighResTimeStamp) { super(); } diff --git a/frontend/src/scripts/physics/containers/bounding-box-tree.ts b/frontend/src/scripts/physics/containers/bounding-box-tree.ts index 3d5aaeb..3cbebcb 100644 --- a/frontend/src/scripts/physics/containers/bounding-box-tree.ts +++ b/frontend/src/scripts/physics/containers/bounding-box-tree.ts @@ -4,6 +4,7 @@ import { ImmutableBoundingBox } from '../../shapes/immutable-bounding-box'; class Node { public left?: Node = null; + public right?: Node = null; constructor(public rectangle: ImmutableBoundingBox, public parent: Node) {} @@ -63,9 +64,7 @@ export class BoundingBoxTree { } } - public findIntersecting( - box: ImmutableBoundingBox - ): Array { + public findIntersecting(box: ImmutableBoundingBox): Array { const maybeResults = this.findMaybeIntersecting(box, this.root, 0); const results = maybeResults.filter((b) => b.intersects(box)); return results; diff --git a/frontend/src/scripts/physics/physics.ts b/frontend/src/scripts/physics/physics.ts index 8d6556a..07d1797 100644 --- a/frontend/src/scripts/physics/physics.ts +++ b/frontend/src/scripts/physics/physics.ts @@ -5,7 +5,9 @@ import { BoundingBoxBase } from '../shapes/bounding-box-base'; export class Physics { private isTreeInitialized = false; + private staticBoundingBoxesWaitList = []; + private staticBoundingBoxes = new BoundingBoxTree(); private dynamicBoundingBoxes = new BoundingBoxList(); diff --git a/frontend/src/scripts/shapes/i-shape.ts b/frontend/src/scripts/shapes/i-shape.ts index cbd1d6c..ab7fdac 100644 --- a/frontend/src/scripts/shapes/i-shape.ts +++ b/frontend/src/scripts/shapes/i-shape.ts @@ -1,5 +1,5 @@ -import { BoundingBox } from './bounding-box'; import { vec2 } from 'gl-matrix'; +import { BoundingBox } from './bounding-box'; import { GameObject } from '../objects/game-object'; export interface IShape { diff --git a/frontend/src/scripts/shapes/types/blob.ts b/frontend/src/scripts/shapes/types/blob.ts index 9ef4731..b586759 100644 --- a/frontend/src/scripts/shapes/types/blob.ts +++ b/frontend/src/scripts/shapes/types/blob.ts @@ -7,35 +7,28 @@ import { GameObject } from '../../objects/game-object'; export class Blob implements IShape { private static readonly boundingCircleRadius = 19; + private static readonly headOffset = vec2.fromValues(0, 15); + private static readonly torsoOffset = vec2.fromValues(0, 0); + private static readonly leftFootOffset = vec2.fromValues(-5, -10); + private static readonly rightFootOffset = vec2.fromValues(5, -10); public readonly isInverted = false; - protected boundingCircle = new Circle( - vec2.create(), - Blob.boundingCircleRadius - ); - protected head = new Circle(vec2.create(), settings.shaderMacros.headRadius); - protected torso = new Circle( - vec2.create(), - settings.shaderMacros.torsoRadius - ); - protected leftFoot = new Circle( - vec2.create(), - settings.shaderMacros.footRadius - ); - protected rightFoot = new Circle( - vec2.create(), - settings.shaderMacros.footRadius - ); + protected boundingCircle = new Circle(vec2.create(), Blob.boundingCircleRadius); - public constructor( - center: vec2, - public readonly gameObject: GameObject = null - ) { + protected head = new Circle(vec2.create(), settings.shaderMacros.headRadius); + + protected torso = new Circle(vec2.create(), settings.shaderMacros.torsoRadius); + + protected leftFoot = new Circle(vec2.create(), settings.shaderMacros.footRadius); + + protected rightFoot = new Circle(vec2.create(), settings.shaderMacros.footRadius); + + public constructor(center: vec2, public readonly gameObject: GameObject = null) { this.position = center; } diff --git a/frontend/src/scripts/shapes/types/tunnel-shape.ts b/frontend/src/scripts/shapes/types/tunnel-shape.ts index 0fa83e2..d20db34 100644 --- a/frontend/src/scripts/shapes/types/tunnel-shape.ts +++ b/frontend/src/scripts/shapes/types/tunnel-shape.ts @@ -6,7 +6,7 @@ import { IShape } from '../i-shape'; import { rotate90Deg } from '../../helper/rotate-90-deg'; import { GameObject } from '../../objects/game-object'; -export class TunnelShape implements IShape { +export default class TunnelShape implements IShape { public readonly isInverted = true; public readonly toFromDelta: vec2; @@ -22,22 +22,10 @@ export class TunnelShape implements IShape { } public get boundingBox(): BoundingBox { - const xMin = Math.min( - this.from.x - this.fromRadius, - this.to.x - this.toRadius - ); - const yMin = Math.min( - this.from.y - this.fromRadius, - this.to.y - this.toRadius - ); - const xMax = Math.max( - this.from.x + this.fromRadius, - this.to.x + this.toRadius - ); - const yMax = Math.max( - this.from.y + this.fromRadius, - this.to.y + this.toRadius - ); + const xMin = Math.min(this.from.x - this.fromRadius, this.to.x - this.toRadius); + const yMin = Math.min(this.from.y - this.fromRadius, this.to.y - this.toRadius); + const xMax = Math.max(this.from.x + this.fromRadius, this.to.x + this.toRadius); + const yMax = Math.max(this.from.y + this.fromRadius, this.to.y + this.toRadius); return new BoundingBox(this, xMin, xMax, yMin, yMax); } @@ -58,8 +46,7 @@ export class TunnelShape implements IShape { vec2.subtract(diff, target, this.from); } else { const side = Math.sign( - this.toFromDelta.x * targetFromDelta.y - - this.toFromDelta.y * targetFromDelta.x + this.toFromDelta.x * targetFromDelta.y - this.toFromDelta.y * targetFromDelta.x ); const normal = rotate90Deg(this.toFromDelta); @@ -77,9 +64,7 @@ export class TunnelShape implements IShape { vec2.scale(vec2.create(), normal, side * this.toRadius) ); - diff = rotate90Deg( - vec2.subtract(vec2.create(), translatedTo, translatedFrom) - ); + diff = rotate90Deg(vec2.subtract(vec2.create(), translatedTo, translatedFrom)); vec2.scale(diff, diff, side); } @@ -96,10 +81,8 @@ export class TunnelShape implements IShape { ); return ( - vec2.distance( - targetFromDelta, - vec2.scale(vec2.create(), this.toFromDelta, h) - ) - mix(this.fromRadius, this.toRadius, h) + vec2.distance(targetFromDelta, vec2.scale(vec2.create(), this.toFromDelta, h)) - + mix(this.fromRadius, this.toRadius, h) ); }