diff --git a/README.md b/README.md
index b4b1b2b..0ef7251 100644
--- a/README.md
+++ b/README.md
@@ -19,3 +19,7 @@ A good-looking 2D adventure.
- lightweight object storage
- 502 error page for ingress
- vs code glsl formatter
+- docker engine dashboard?
+- local dev env
+- vs code config
+- prettier script
diff --git a/frontend/.vscode/settings.json b/frontend/.vscode/settings.json
new file mode 100644
index 0000000..c178efe
--- /dev/null
+++ b/frontend/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+ "typescript.tsdk": "node_modules\\typescript\\lib",
+ "editor.tabSize": 2,
+ "editor.formatOnSave": true
+}
diff --git a/frontend/package.json b/frontend/package.json
index 7399b98..5a4e037 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -48,6 +48,7 @@
"ts-loader": "^8.0.1",
"twgl.js": "^4.15.2",
"typescript": "^3.8.3",
+ "uuid": "^8.2.0",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
diff --git a/frontend/src/index.html b/frontend/src/index.html
index d96135b..1774dc2 100644
--- a/frontend/src/index.html
+++ b/frontend/src/index.html
@@ -1,20 +1,23 @@
-
-
+
+
-
-
+
+
-
-
+
+
- Test
-
-
-
-
-
-
-
+ Test
+
+
+
+
+
+
+
diff --git a/frontend/src/index.ts b/frontend/src/index.ts
index 0d23ac2..aadeadf 100644
--- a/frontend/src/index.ts
+++ b/frontend/src/index.ts
@@ -1,4 +1,4 @@
-import './styling/main.scss';
-import { main } from './scripting/main';
+import './styles/main.scss';
+import { main } from './scripts/main';
main();
diff --git a/frontend/src/scripting/helper/keyboard-listener.ts b/frontend/src/scripting/helper/keyboard-listener.ts
deleted file mode 100644
index 6c946ee..0000000
--- a/frontend/src/scripting/helper/keyboard-listener.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-export class KeyboardListener {
- private keysDown: Set = new Set();
-
- constructor() {
- document.addEventListener('keydown', (event) => {
- this.keysDown.add(event.key);
- });
-
- document.addEventListener('keyup', (event) => {
- this.keysDown.delete(event.key);
- });
- }
-
- isKeyDown(key: string): boolean {
- return (
- this.keysDown.has(key) ||
- this.keysDown.has(key.toLowerCase()) ||
- this.keysDown.has(key.toUpperCase())
- );
- }
-}
diff --git a/frontend/src/scripting/main.ts b/frontend/src/scripting/main.ts
deleted file mode 100644
index 70cb939..0000000
--- a/frontend/src/scripting/main.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { Renderer } from './drawing/renderer';
-import { KeyboardListener } from './helper/keyboard-listener';
-
-import passthroughVertexShader from '../shaders/passthrough.vert';
-import distanceFragmentShader from '../shaders/dist.frag';
-
-export const main = async () => {
- try {
- const canvas: HTMLCanvasElement = document.querySelector('canvas#main');
-
- const renderer = new Renderer(canvas, [
- passthroughVertexShader,
- distanceFragmentShader,
- ]);
-
- renderer.start();
- } catch (e) {
- console.error(e);
- }
-};
diff --git a/frontend/src/scripting/shared/vec2.ts b/frontend/src/scripting/shared/vec2.ts
deleted file mode 100644
index 48ea69a..0000000
--- a/frontend/src/scripting/shared/vec2.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export interface Vec2 {
- x: number;
- y: number;
-}
diff --git a/frontend/src/scripting/shared/world-map.ts b/frontend/src/scripting/shared/world-map.ts
deleted file mode 100644
index 9deccb4..0000000
--- a/frontend/src/scripting/shared/world-map.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Line } from './line';
-
-export class WorldMap {
- private lines: Array = [];
-
- constructor() {
- const delta = 0.01;
- for (let i = delta; i < 30; i += delta) {
- const linePoints = {
- a: { x: i - delta, y: Math.sin(i - delta) },
- b: { x: i, y: Math.sin(i) },
- };
- /*Vec2 tangent = lines[i].b - lines[i].a;
- lines[i].normal = vec2(-lines[i].normal.x * tangent.y, lines[i].normal.x * tangent.x);
- linePoints.normal = */
- }
- }
-}
diff --git a/frontend/src/scripts/commands/command-broadcaster.ts b/frontend/src/scripts/commands/command-broadcaster.ts
new file mode 100644
index 0000000..8703fcf
--- /dev/null
+++ b/frontend/src/scripts/commands/command-broadcaster.ts
@@ -0,0 +1,13 @@
+import { CommandReceiver } from './command-receiver';
+import { CommandGenerator } from './command-generator';
+
+export class CommandBroadcaster {
+ constructor(
+ commandGenerators: Array,
+ commandReceivers: Array
+ ) {
+ commandReceivers.forEach((r) =>
+ commandGenerators.forEach((g) => g.subscribe(r))
+ );
+ }
+}
diff --git a/frontend/src/scripts/commands/command-generator.ts b/frontend/src/scripts/commands/command-generator.ts
new file mode 100644
index 0000000..01fb65b
--- /dev/null
+++ b/frontend/src/scripts/commands/command-generator.ts
@@ -0,0 +1,14 @@
+import { CommandReceiver } from './command-receiver';
+import { Command } from './command';
+
+export class CommandGenerator {
+ private subscribers: Array = [];
+
+ public subscribe(subscriber: CommandReceiver): void {
+ this.subscribers.push(subscriber);
+ }
+
+ protected sendCommand(command: Command): void {
+ this.subscribers.forEach((s) => s.sendCommand(command));
+ }
+}
diff --git a/frontend/src/scripts/commands/command-receiver.ts b/frontend/src/scripts/commands/command-receiver.ts
new file mode 100644
index 0000000..bf6e119
--- /dev/null
+++ b/frontend/src/scripts/commands/command-receiver.ts
@@ -0,0 +1,5 @@
+import { Command } from './command';
+
+export interface CommandReceiver {
+ sendCommand(command: Command): void;
+}
diff --git a/frontend/src/scripts/commands/command.ts b/frontend/src/scripts/commands/command.ts
new file mode 100644
index 0000000..f53a31a
--- /dev/null
+++ b/frontend/src/scripts/commands/command.ts
@@ -0,0 +1,3 @@
+import { Typed } from '../transport/serializable';
+
+export abstract class Command extends Typed {}
diff --git a/frontend/src/scripts/commands/types/key-down.ts b/frontend/src/scripts/commands/types/key-down.ts
new file mode 100644
index 0000000..6adcc0b
--- /dev/null
+++ b/frontend/src/scripts/commands/types/key-down.ts
@@ -0,0 +1,7 @@
+import { Command } from '../command';
+
+export class KeyDownCommand extends Command {
+ public constructor(public readonly key: string) {
+ super();
+ }
+}
diff --git a/frontend/src/scripts/commands/types/key-up.ts b/frontend/src/scripts/commands/types/key-up.ts
new file mode 100644
index 0000000..b70f7f7
--- /dev/null
+++ b/frontend/src/scripts/commands/types/key-up.ts
@@ -0,0 +1,7 @@
+import { Command } from '../command';
+
+export class KeyUpCommand extends Command {
+ public constructor(public readonly key: string) {
+ super();
+ }
+}
diff --git a/frontend/src/scripts/commands/types/primary-action.ts b/frontend/src/scripts/commands/types/primary-action.ts
new file mode 100644
index 0000000..6a9d443
--- /dev/null
+++ b/frontend/src/scripts/commands/types/primary-action.ts
@@ -0,0 +1,8 @@
+import { Command } from '../command';
+import { Vec2 } from '../../math/vec2';
+
+export class PrimaryActionCommand extends Command {
+ public constructor(public readonly position: Vec2) {
+ super();
+ }
+}
diff --git a/frontend/src/scripts/commands/types/secondary-action.ts b/frontend/src/scripts/commands/types/secondary-action.ts
new file mode 100644
index 0000000..369701c
--- /dev/null
+++ b/frontend/src/scripts/commands/types/secondary-action.ts
@@ -0,0 +1,8 @@
+import { Command } from '../command';
+import { Vec2 } from '../../math/vec2';
+
+export class SecondaryActionCommand extends Command {
+ public constructor(public readonly position: Vec2) {
+ super();
+ }
+}
diff --git a/frontend/src/scripts/commands/types/swipe.ts b/frontend/src/scripts/commands/types/swipe.ts
new file mode 100644
index 0000000..929129e
--- /dev/null
+++ b/frontend/src/scripts/commands/types/swipe.ts
@@ -0,0 +1,8 @@
+import { Command } from '../command';
+import { Vec2 } from '../../math/vec2';
+
+export class SwipeCommand extends Command {
+ public constructor(public readonly delta: Vec2) {
+ super();
+ }
+}
diff --git a/frontend/src/scripting/drawing/pipeline.ts b/frontend/src/scripts/drawing/pipeline.ts
similarity index 100%
rename from frontend/src/scripting/drawing/pipeline.ts
rename to frontend/src/scripts/drawing/pipeline.ts
diff --git a/frontend/src/scripting/drawing/renderer.ts b/frontend/src/scripts/drawing/renderer.ts
similarity index 62%
rename from frontend/src/scripting/drawing/renderer.ts
rename to frontend/src/scripts/drawing/renderer.ts
index b507900..11b27f7 100644
--- a/frontend/src/scripting/drawing/renderer.ts
+++ b/frontend/src/scripts/drawing/renderer.ts
@@ -1,17 +1,20 @@
-import * as twgl from 'twgl.js';
+const twgl = require('twgl.js');
+
import { TimeIt } from '../helper/timing';
-import { KeyboardListener } from '../helper/keyboard-listener';
-import { Vec2 } from '../shared/vec2';
+import { Vec2 } from '../math/vec2';
+import { ObjectContainer } from '../objects/object-container';
export class Renderer {
private gl: WebGL2RenderingContext;
private programInfo: any;
private bufferInfo: any;
private vao: any;
- private cameraPosition: Vec2 = { x: 0, y: 0 };
- private keys: KeyboardListener = new KeyboardListener();
- constructor(private canvas: HTMLCanvasElement, shaderSources: Array) {
+ constructor(
+ private canvas: HTMLCanvasElement,
+ private objects: ObjectContainer,
+ shaderSources: Array
+ ) {
twgl.setDefaults({ attribPrefix: 'a_' });
this.gl = this.canvas.getContext('webgl2');
@@ -39,13 +42,7 @@ export class Renderer {
);
}
- start() {
- requestAnimationFrame(this.timedRender);
- }
-
- private timedRender = TimeIt(this.render.bind(this), 240);
-
- private render(time: number) {
+ public render(time: number) {
const gl = this.gl;
twgl.resizeCanvasToDisplaySize(this.canvas);
@@ -53,24 +50,8 @@ export class Renderer {
gl.clear(gl.COLOR_BUFFER_BIT);
- if (this.keys.isKeyDown('w')) {
- this.cameraPosition.y += 10;
- }
-
- if (this.keys.isKeyDown('s')) {
- this.cameraPosition.y -= 10;
- }
-
- if (this.keys.isKeyDown('a')) {
- this.cameraPosition.x -= 10;
- }
-
- if (this.keys.isKeyDown('d')) {
- this.cameraPosition.x += 10;
- }
-
const uniforms = {
- cameraPosition: [this.cameraPosition.x, this.cameraPosition.y],
+ cameraPosition: this.objects.camera.position.list,
viewBoxSize: [this.gl.canvas.width, this.gl.canvas.height],
resolution: [this.gl.canvas.width, this.gl.canvas.height],
};
@@ -81,7 +62,5 @@ export class Renderer {
twgl.setUniforms(this.programInfo, uniforms);
twgl.drawBufferInfo(this.gl, this.bufferInfo);
-
- requestAnimationFrame(this.timedRender);
}
}
diff --git a/frontend/src/scripts/game-logic/game-logic.ts b/frontend/src/scripts/game-logic/game-logic.ts
new file mode 100644
index 0000000..60cc378
--- /dev/null
+++ b/frontend/src/scripts/game-logic/game-logic.ts
@@ -0,0 +1,54 @@
+import { Command } from '../commands/command';
+import { CommandReceiver } from '../commands/command-receiver';
+import { ObjectContainer } from '../objects/object-container';
+import { KeyDownCommand } from '../commands/types/key-down';
+import { KeyUpCommand } from '../commands/types/key-up';
+import { SwipeCommand } from '../commands/types/swipe';
+
+export class GameLogic implements CommandReceiver {
+ private commandBuffer: Array = [];
+ private keysDown: Set = new Set();
+
+ constructor(private objects: ObjectContainer) {}
+
+ public step(time: DOMHighResTimeStamp) {
+ while (this.commandBuffer.length > 0) {
+ const command = this.commandBuffer.pop();
+ console.log(command);
+
+ if (command instanceof KeyDownCommand) {
+ this.keysDown.add(command.key);
+ }
+
+ if (command instanceof KeyUpCommand) {
+ this.keysDown.delete(command.key);
+ }
+
+ if (command instanceof SwipeCommand) {
+ this.objects.camera.position = this.objects.camera.position.subtract(
+ command.delta.scale(200)
+ );
+ }
+ }
+
+ if (this.keysDown.has('w')) {
+ this.objects.camera.position.y += 10;
+ }
+
+ if (this.keysDown.has('s')) {
+ this.objects.camera.position.y -= 10;
+ }
+
+ if (this.keysDown.has('a')) {
+ this.objects.camera.position.x -= 10;
+ }
+
+ if (this.keysDown.has('d')) {
+ this.objects.camera.position.x += 10;
+ }
+ }
+
+ public sendCommand(command: Command) {
+ this.commandBuffer.push(command);
+ }
+}
diff --git a/frontend/src/scripting/helper/timing.ts b/frontend/src/scripts/helper/timing.ts
similarity index 100%
rename from frontend/src/scripting/helper/timing.ts
rename to frontend/src/scripts/helper/timing.ts
diff --git a/frontend/src/scripts/identity/identity-manager.ts b/frontend/src/scripts/identity/identity-manager.ts
new file mode 100644
index 0000000..49b5ad8
--- /dev/null
+++ b/frontend/src/scripts/identity/identity-manager.ts
@@ -0,0 +1,4 @@
+export class IdentityManager {
+ public static sourceId: string;
+ public static targetId: string;
+}
diff --git a/frontend/src/scripts/input/keyboard-listener.ts b/frontend/src/scripts/input/keyboard-listener.ts
new file mode 100644
index 0000000..a94ed88
--- /dev/null
+++ b/frontend/src/scripts/input/keyboard-listener.ts
@@ -0,0 +1,19 @@
+import { CommandGenerator } from '../commands/command-generator';
+import { KeyDownCommand } from '../commands/types/key-down';
+import { KeyUpCommand } from '../commands/types/key-up';
+
+export class KeyboardListener extends CommandGenerator {
+ constructor(target: Element = document.body) {
+ super();
+
+ target.addEventListener('keydown', (event: KeyboardEvent) => {
+ const key = event.key.toLowerCase();
+ this.sendCommand(new KeyDownCommand(key));
+ });
+
+ target.addEventListener('keyup', (event: KeyboardEvent) => {
+ const key = event.key.toLowerCase();
+ this.sendCommand(new KeyUpCommand(key));
+ });
+ }
+}
diff --git a/frontend/src/scripts/input/mouse-listener.ts b/frontend/src/scripts/input/mouse-listener.ts
new file mode 100644
index 0000000..e14ff81
--- /dev/null
+++ b/frontend/src/scripts/input/mouse-listener.ts
@@ -0,0 +1,56 @@
+import { CommandGenerator } from '../commands/command-generator';
+import { PrimaryActionCommand } from '../commands/types/primary-action';
+import { SecondaryActionCommand } from '../commands/types/secondary-action';
+import { Vec2 } from '../math/vec2';
+import { SwipeCommand } from '../commands/types/swipe';
+
+export class MouseListener extends CommandGenerator {
+ private previousPosition: Vec2 = null;
+ private isMouseDown = false;
+
+ constructor(private target: Element = document.body) {
+ super();
+
+ target.addEventListener('mousedown', (event: MouseEvent) => {
+ const position = this.positionFromEvent(event);
+
+ this.previousPosition = position;
+ this.isMouseDown = true;
+
+ if (event.button == 0) {
+ this.sendCommand(new PrimaryActionCommand(position));
+ }
+ });
+
+ target.addEventListener('mousemove', (event: MouseEvent) => {
+ if (this.isMouseDown) {
+ const position = this.positionFromEvent(event);
+ this.sendCommand(
+ new SwipeCommand(this.previousPosition.subtract(position))
+ );
+ this.previousPosition = position;
+ }
+ });
+
+ target.addEventListener('mouseup', (event: MouseEvent) => {
+ this.isMouseDown = false;
+ });
+
+ target.addEventListener('mouseleave', (event: MouseEvent) => {
+ this.isMouseDown = false;
+ });
+
+ target.addEventListener('contextmenu', (event: MouseEvent) => {
+ event.preventDefault();
+ const position = this.positionFromEvent(event);
+ this.sendCommand(new SecondaryActionCommand(position));
+ });
+ }
+
+ private positionFromEvent(event: MouseEvent): Vec2 {
+ return new Vec2(
+ -event.clientX / this.target.clientWidth,
+ event.clientY / this.target.clientHeight
+ );
+ }
+}
diff --git a/frontend/src/scripts/input/touch-listener.ts b/frontend/src/scripts/input/touch-listener.ts
new file mode 100644
index 0000000..b441a7c
--- /dev/null
+++ b/frontend/src/scripts/input/touch-listener.ts
@@ -0,0 +1,42 @@
+import { CommandGenerator } from '../commands/command-generator';
+import { PrimaryActionCommand } from '../commands/types/primary-action';
+import { SecondaryActionCommand } from '../commands/types/secondary-action';
+import { Vec2 } from '../math/vec2';
+import { SwipeCommand } from '../commands/types/swipe';
+
+export class TouchListener extends CommandGenerator {
+ private previousPosition: Vec2 = null;
+
+ constructor(private target: Element = document.body) {
+ super();
+
+ target.addEventListener('touchstart', (event: TouchEvent) => {
+ const touchCount = event.touches.length;
+ const position = this.positionFromEvent(event);
+ this.previousPosition = position;
+
+ if (touchCount == 1) {
+ this.sendCommand(new PrimaryActionCommand(position));
+ } else {
+ this.sendCommand(new SecondaryActionCommand(position));
+ }
+ });
+
+ target.addEventListener('touchmove', (event: TouchEvent) => {
+ const position = this.positionFromEvent(event);
+
+ this.sendCommand(
+ new SwipeCommand(position.subtract(this.previousPosition))
+ );
+
+ this.previousPosition = position;
+ });
+ }
+
+ private positionFromEvent(event: TouchEvent): Vec2 {
+ return new Vec2(
+ event.touches[0].clientX / this.target.clientWidth,
+ -event.touches[0].clientY / this.target.clientHeight
+ );
+ }
+}
diff --git a/frontend/src/scripts/main.ts b/frontend/src/scripts/main.ts
new file mode 100644
index 0000000..5458188
--- /dev/null
+++ b/frontend/src/scripts/main.ts
@@ -0,0 +1,48 @@
+import { Renderer } from './drawing/renderer';
+
+import passthroughVertexShader from '../shaders/passthrough.vert';
+import distanceFragmentShader from '../shaders/dist.frag';
+import { KeyboardListener } from './input/keyboard-listener';
+import { MouseListener } from './input/mouse-listener';
+import { TouchListener } from './input/touch-listener';
+import { CommandBroadcaster } from './commands/command-broadcaster';
+import { GameLogic } from './game-logic/game-logic';
+import { GameObject } from './objects/game-object';
+import { ObjectContainer } from './objects/object-container';
+import { Camera } from './objects/types/camera';
+
+const startGameLoop = (gameLogic: GameLogic, renderer: Renderer) => {
+ const loop = (time: DOMHighResTimeStamp) => {
+ gameLogic.step(time);
+ renderer.render(time);
+ requestAnimationFrame(loop);
+ };
+ requestAnimationFrame(loop);
+};
+
+export const main = async () => {
+ try {
+ const canvas: HTMLCanvasElement = document.querySelector('canvas#main');
+
+ const objects = new ObjectContainer(new Camera());
+
+ const gameLogic = new GameLogic(objects);
+ new CommandBroadcaster(
+ [
+ new KeyboardListener(document.body),
+ new MouseListener(canvas),
+ new TouchListener(canvas),
+ ],
+ [gameLogic]
+ );
+
+ const renderer = new Renderer(canvas, objects, [
+ passthroughVertexShader,
+ distanceFragmentShader,
+ ]);
+
+ startGameLoop(gameLogic, renderer);
+ } catch (e) {
+ console.error(e);
+ }
+};
diff --git a/frontend/src/scripting/shared/line.ts b/frontend/src/scripts/math/line.ts
similarity index 100%
rename from frontend/src/scripting/shared/line.ts
rename to frontend/src/scripts/math/line.ts
diff --git a/frontend/src/scripts/math/vec2.ts b/frontend/src/scripts/math/vec2.ts
new file mode 100644
index 0000000..f47bd39
--- /dev/null
+++ b/frontend/src/scripts/math/vec2.ts
@@ -0,0 +1,27 @@
+import { Typed } from '../transport/serializable';
+
+export class Vec2 extends Typed {
+ public constructor(public x: number = 0.0, public y: number = null) {
+ super();
+
+ if (this.y === null) {
+ this.y = this.x;
+ }
+ }
+
+ public scale(scalar: number): Vec2 {
+ return new Vec2(this.x * scalar, this.y * scalar);
+ }
+
+ public add(other: Vec2): Vec2 {
+ return new Vec2(this.x + other.x, this.y + other.y);
+ }
+
+ public subtract(other: Vec2): Vec2 {
+ return new Vec2(this.x - other.x, this.y - other.y);
+ }
+
+ public get list(): [number, number] {
+ return [this.x, this.y];
+ }
+}
diff --git a/frontend/src/scripts/objects/game-object.ts b/frontend/src/scripts/objects/game-object.ts
new file mode 100644
index 0000000..512e39f
--- /dev/null
+++ b/frontend/src/scripts/objects/game-object.ts
@@ -0,0 +1,7 @@
+import { Typed } from '../transport/serializable';
+import { Vec2 } from '../math/vec2';
+
+export class GameObject extends Typed {
+ public position = new Vec2();
+ public boundingBoxSize = new Vec2();
+}
diff --git a/frontend/src/scripts/objects/object-container.ts b/frontend/src/scripts/objects/object-container.ts
new file mode 100644
index 0000000..31a3bc9
--- /dev/null
+++ b/frontend/src/scripts/objects/object-container.ts
@@ -0,0 +1,8 @@
+import { GameObject } from './game-object';
+import { Camera } from './types/camera';
+
+export class ObjectContainer {
+ private objects: Array = [];
+
+ constructor(public camera: Camera) {}
+}
diff --git a/frontend/src/scripts/objects/types/camera.ts b/frontend/src/scripts/objects/types/camera.ts
new file mode 100644
index 0000000..bf612b2
--- /dev/null
+++ b/frontend/src/scripts/objects/types/camera.ts
@@ -0,0 +1,3 @@
+import { GameObject } from '../game-object';
+
+export class Camera extends GameObject {}
diff --git a/frontend/src/scripts/transport/serializable.ts b/frontend/src/scripts/transport/serializable.ts
new file mode 100644
index 0000000..b1e03d8
--- /dev/null
+++ b/frontend/src/scripts/transport/serializable.ts
@@ -0,0 +1,9 @@
+export class Typed {
+ public get type(): string {
+ return this.constructor.name;
+ }
+
+ public toJSON() {
+ return { type: this.type, ...this };
+ }
+}
diff --git a/frontend/src/shaders/dist.frag b/frontend/src/shaders/dist.frag
index 930ac7f..efc382b 100644
--- a/frontend/src/shaders/dist.frag
+++ b/frontend/src/shaders/dist.frag
@@ -41,6 +41,24 @@ float terrain(float x) {
return result;
}
+vec2 random2(vec2 st){
+ st = vec2( dot(st,vec2(127.1,311.7)),
+ dot(st,vec2(269.5,183.3)) );
+ return -1.0 + 2.0*fract(sin(st)*43758.5453123);
+}
+
+float noise(vec2 st) {
+ vec2 i = floor(st);
+ vec2 f = fract(st);
+
+ vec2 u = f*f*(3.0-2.0*f);
+
+ return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
+ dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
+ mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
+ dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
+}
+
float lineDistance(in vec2 position, in Line line, out float h) {
vec2 pa = position - line.a, ba = line.b - line.a;
h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
@@ -50,6 +68,7 @@ float lineDistance(in vec2 position, in Line line, out float h) {
return length(delta) * side + terrain(length(ba * h));
}
+
Line endDummyLineFromLine(Line line) {
return Line(line.b, line.b + rotate90deg(line.normal), line.normal, false);
}
diff --git a/frontend/src/styling/main.scss b/frontend/src/styles/main.scss
similarity index 100%
rename from frontend/src/styling/main.scss
rename to frontend/src/styles/main.scss
diff --git a/frontend/webpack.config.js b/frontend/webpack.config.js
index 2a159be..1724428 100644
--- a/frontend/webpack.config.js
+++ b/frontend/webpack.config.js
@@ -7,6 +7,7 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');
const Sharp = require('responsive-loader/sharp');
const Sass = require('sass');
+const tsNameof = require('ts-nameof');
const isProduction = process.env.NODE_ENV === 'production';
@@ -73,7 +74,7 @@ module.exports = {
{
test: /\.(frag|vert)$/i,
use: {
- loader: 'raw-loader'
+ loader: 'raw-loader',
},
},
{
@@ -120,7 +121,12 @@ module.exports = {
},
{
test: /\.ts$/,
- use: 'ts-loader',
+ use: {
+ loader: 'ts-loader',
+ options: {
+ getCustomTransformers: () => ({ before: [tsNameof] }),
+ },
+ },
exclude: /node_modules/,
},
],