Add linting
This commit is contained in:
parent
76282a4cf7
commit
40a660b7cb
49 changed files with 237 additions and 334 deletions
|
|
@ -6,8 +6,6 @@ export class CommandBroadcaster {
|
|||
commandGenerators: Array<CommandGenerator>,
|
||||
commandReceivers: Array<CommandReceiver>
|
||||
) {
|
||||
commandReceivers.forEach((r) =>
|
||||
commandGenerators.forEach((g) => g.subscribe(r))
|
||||
);
|
||||
commandReceivers.forEach((r) => commandGenerators.forEach((g) => g.subscribe(r)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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] = [];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { IDrawable } from '../i-drawable';
|
||||
|
||||
export interface ILight extends IDrawable {}
|
||||
export type ILight = IDrawable;
|
||||
|
|
|
|||
|
|
@ -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] = [];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {}
|
||||
|
|
|
|||
|
|
@ -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}`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
export const getWebGl2Context = (
|
||||
canvas: HTMLCanvasElement
|
||||
): WebGL2RenderingContext => {
|
||||
export const getWebGl2Context = (canvas: HTMLCanvasElement): WebGL2RenderingContext => {
|
||||
const gl = canvas.getContext('webgl2');
|
||||
|
||||
if (!gl) {
|
||||
|
|
|
|||
|
|
@ -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<vec2>, 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<number>).x;
|
||||
result[2 * i + 1] = (v[i] as Array<number>).y;
|
||||
}
|
||||
|
||||
gl.uniform2fv(l, result);
|
||||
} else {
|
||||
gl.uniform2fv(l, v as vec2);
|
||||
}
|
||||
converters.set(WebGL2RenderingContext.FLOAT_VEC2, (gl, v: vec2 | Array<vec2>, 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<number>).x;
|
||||
result[2 * i + 1] = (v[i] as Array<number>).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}`);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<WebGLShader> = [];
|
||||
|
||||
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));
|
||||
|
|
|
|||
|
|
@ -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<number>;
|
||||
}> = [];
|
||||
|
||||
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<IDrawableDescriptor>
|
||||
) {
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<FrameBuffer>) {
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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<IDrawable> = [];
|
||||
|
||||
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 = [];
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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: {
|
||||
|
|
|
|||
|
|
@ -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<number> = [];
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
export const getCombinations = (
|
||||
values: Array<Array<number>>
|
||||
): Array<Array<number>> => {
|
||||
export const getCombinations = (values: Array<Array<number>>): Array<Array<number>> => {
|
||||
if (!values.every((a) => a.length > 0)) {
|
||||
return [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Id } from './identity';
|
||||
import { v4 } from 'uuid';
|
||||
import { Id } from './identity';
|
||||
|
||||
export class IdentityManager {
|
||||
public static generateId(): Id {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@ import { GameObject } from './game-object';
|
|||
|
||||
export class Objects implements CommandReceiver {
|
||||
private objects: Map<Id, GameObject> = new Map();
|
||||
|
||||
private objectsGroupedByAbilities: Map<string, Array<GameObject>> = 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) {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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<string> = 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)
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<ImmutableBoundingBox> {
|
||||
public findIntersecting(box: ImmutableBoundingBox): Array<ImmutableBoundingBox> {
|
||||
const maybeResults = this.findMaybeIntersecting(box, this.root, 0);
|
||||
const results = maybeResults.filter((b) => b.intersects(box));
|
||||
return results;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue