Add basic multiplayer
This commit is contained in:
parent
0f0a1eaf67
commit
46a48e7c15
113 changed files with 1362 additions and 754 deletions
1
shared/.eslintignore
Normal file
1
shared/.eslintignore
Normal file
|
|
@ -0,0 +1 @@
|
|||
**/*.js
|
||||
29
shared/.eslintrc.json
Normal file
29
shared/.eslintrc.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"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",
|
||||
"@typescript-eslint/no-non-null-assertion": "off"
|
||||
}
|
||||
}
|
||||
4
shared/.gitignore
vendored
Normal file
4
shared/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
dist
|
||||
node_modules
|
||||
package-lock.json
|
||||
.firebase
|
||||
7
shared/.prettierrc
Normal file
7
shared/.prettierrc
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"trailingComma": "es5",
|
||||
"printWidth": 90,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
16
shared/firebase.json
Normal file
16
shared/firebase.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"hosting": {
|
||||
"public": "dist",
|
||||
"ignore": [
|
||||
"firebase.json",
|
||||
"**/.*",
|
||||
"**/node_modules/**"
|
||||
],
|
||||
"rewrites": [
|
||||
{
|
||||
"source": "**",
|
||||
"destination": "/index.html"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
17
shared/package.json
Normal file
17
shared/package.json
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "shared",
|
||||
"version": "0.0.0",
|
||||
"description": "Shared library between backend and frontend",
|
||||
"main": "src/main.ts",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@types/gl-matrix": "^3.2.0",
|
||||
"@types/uuid": "^8.0.0",
|
||||
"gl-matrix": "^3.3.0",
|
||||
"uuid": "^8.2.0"
|
||||
}
|
||||
}
|
||||
7
shared/src/commands/broadcast-commands.ts
Normal file
7
shared/src/commands/broadcast-commands.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { CommandReceiver } from './command-receiver';
|
||||
import { CommandGenerator } from './command-generator';
|
||||
|
||||
export const broadcastCommands = (
|
||||
commandGenerators: Array<CommandGenerator>,
|
||||
commandReceivers: Array<CommandReceiver>
|
||||
) => commandReceivers.forEach((r) => commandGenerators.forEach((g) => g.subscribe(r)));
|
||||
14
shared/src/commands/command-generator.ts
Normal file
14
shared/src/commands/command-generator.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { CommandReceiver } from './command-receiver';
|
||||
import { Command } from './command';
|
||||
|
||||
export class CommandGenerator {
|
||||
private subscribers: Array<CommandReceiver> = [];
|
||||
|
||||
public subscribe(subscriber: CommandReceiver): void {
|
||||
this.subscribers.push(subscriber);
|
||||
}
|
||||
|
||||
protected sendCommandToSubcribers(command: Command): void {
|
||||
this.subscribers.forEach((s) => s.sendCommand(command));
|
||||
}
|
||||
}
|
||||
25
shared/src/commands/command-receiver.ts
Normal file
25
shared/src/commands/command-receiver.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import { Command } from './command';
|
||||
|
||||
export type CommandExecutors = {
|
||||
[type: string]: (command: Command) => void;
|
||||
};
|
||||
|
||||
export abstract class CommandReceiver {
|
||||
protected commandExecutors: CommandExecutors = {};
|
||||
|
||||
protected defaultCommandExecutor(command: Command) {}
|
||||
|
||||
public reactsToCommand(commandType: string): boolean {
|
||||
return Object.prototype.hasOwnProperty.call(this.commandExecutors, commandType);
|
||||
}
|
||||
|
||||
public sendCommand(command: Command) {
|
||||
const commandType = command.type;
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(this.commandExecutors, commandType)) {
|
||||
this.commandExecutors[commandType](command);
|
||||
} else {
|
||||
this.defaultCommandExecutor(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
7
shared/src/commands/command.ts
Normal file
7
shared/src/commands/command.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { Id } from '../transport/identity';
|
||||
|
||||
export abstract class Command {
|
||||
public get type(): string {
|
||||
return (this as any).constructor.type;
|
||||
}
|
||||
}
|
||||
13
shared/src/commands/types/create-objects.ts
Normal file
13
shared/src/commands/types/create-objects.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { Command } from '../command';
|
||||
|
||||
export class CreateObjectsCommand extends Command {
|
||||
public static readonly type = 'CreateObjectsCommand';
|
||||
|
||||
public constructor(public readonly serializedObjects: string) {
|
||||
super();
|
||||
}
|
||||
|
||||
public toJSON(): any {
|
||||
return [this.type, this.serializedObjects];
|
||||
}
|
||||
}
|
||||
13
shared/src/commands/types/create-player.ts
Normal file
13
shared/src/commands/types/create-player.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { Command } from '../command';
|
||||
|
||||
export class CreatePlayerCommand extends Command {
|
||||
public static readonly type = 'CreatePlayerCommand';
|
||||
|
||||
public constructor(public readonly serializedPlayer: string) {
|
||||
super();
|
||||
}
|
||||
|
||||
public toJSON(): any {
|
||||
return [this.type, this.serializedPlayer];
|
||||
}
|
||||
}
|
||||
14
shared/src/commands/types/delete-objects.ts
Normal file
14
shared/src/commands/types/delete-objects.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { Id } from '../../transport/identity';
|
||||
import { Command } from '../command';
|
||||
|
||||
export class DeleteObjectsCommand extends Command {
|
||||
public static readonly type = 'DeleteObjectsCommand';
|
||||
|
||||
public constructor(public readonly ids: Array<Id>) {
|
||||
super();
|
||||
}
|
||||
|
||||
public toJSON(): any {
|
||||
return [this.type, this.ids];
|
||||
}
|
||||
}
|
||||
14
shared/src/commands/types/move-action.ts
Normal file
14
shared/src/commands/types/move-action.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { Command } from '../command';
|
||||
|
||||
export class MoveActionCommand extends Command {
|
||||
public static readonly type = 'MoveActionCommand';
|
||||
|
||||
public constructor(public readonly delta: vec2) {
|
||||
super();
|
||||
}
|
||||
|
||||
public toJSON(): any {
|
||||
return [this.type, this.delta];
|
||||
}
|
||||
}
|
||||
14
shared/src/commands/types/primary-action.ts
Normal file
14
shared/src/commands/types/primary-action.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { Command } from '../command';
|
||||
|
||||
export class PrimaryActionCommand extends Command {
|
||||
public static readonly type = 'PrimaryActionCommand';
|
||||
|
||||
public constructor(public readonly position: vec2) {
|
||||
super();
|
||||
}
|
||||
|
||||
public toJSON(): any {
|
||||
return [this.type, this.position];
|
||||
}
|
||||
}
|
||||
14
shared/src/commands/types/secondary-action.ts
Normal file
14
shared/src/commands/types/secondary-action.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { Command } from '../command';
|
||||
|
||||
export class SecondaryActionCommand extends Command {
|
||||
public static readonly type = 'SecondaryActionCommand';
|
||||
|
||||
public constructor(public readonly position: vec2) {
|
||||
super();
|
||||
}
|
||||
|
||||
public toJSON(): any {
|
||||
return [this.type, this.position];
|
||||
}
|
||||
}
|
||||
14
shared/src/commands/types/set-view-area-action.ts
Normal file
14
shared/src/commands/types/set-view-area-action.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { Rectangle } from '../../helper/rectangle';
|
||||
import { Command } from '../command';
|
||||
|
||||
export class SetViewAreaActionCommand extends Command {
|
||||
public static readonly type = 'SetViewAreaAction';
|
||||
|
||||
public constructor(public readonly viewArea: Rectangle) {
|
||||
super();
|
||||
}
|
||||
|
||||
public toJSON(): any {
|
||||
return [this.type, this.viewArea];
|
||||
}
|
||||
}
|
||||
14
shared/src/commands/types/ternary-action.ts
Normal file
14
shared/src/commands/types/ternary-action.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { Command } from '../command';
|
||||
|
||||
export class TernaryActionCommand extends Command {
|
||||
public static readonly type = 'TernaryActionCommand';
|
||||
|
||||
public constructor(public readonly position: vec2) {
|
||||
super();
|
||||
}
|
||||
|
||||
public toJSON(): any {
|
||||
return [this.type, this.position];
|
||||
}
|
||||
}
|
||||
13
shared/src/commands/types/update-objects.ts
Normal file
13
shared/src/commands/types/update-objects.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { Command } from '../command';
|
||||
|
||||
export class UpdateObjectsCommand extends Command {
|
||||
public static readonly type = 'UpdateObjectsCommand';
|
||||
|
||||
public constructor(public readonly serializedObjects: string) {
|
||||
super();
|
||||
}
|
||||
|
||||
public toJSON(): any {
|
||||
return [this.type, this.serializedObjects];
|
||||
}
|
||||
}
|
||||
31
shared/src/helper/array.ts
Normal file
31
shared/src/helper/array.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
declare global {
|
||||
interface Array<T> {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
interface Float32Array {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
}
|
||||
|
||||
const setIndexAlias = (name: string, index: number, type: any) => {
|
||||
if (!Object.prototype.hasOwnProperty.call(type.prototype, name)) {
|
||||
Object.defineProperty(type.prototype, name, {
|
||||
get() {
|
||||
return this[index];
|
||||
},
|
||||
set(value) {
|
||||
this[index] = value;
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const applyArrayPlugins = () => {
|
||||
setIndexAlias('x', 0, Array);
|
||||
setIndexAlias('y', 1, Array);
|
||||
setIndexAlias('x', 0, Float32Array);
|
||||
setIndexAlias('y', 1, Float32Array);
|
||||
};
|
||||
5
shared/src/helper/circle.ts
Normal file
5
shared/src/helper/circle.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
|
||||
export class Circle {
|
||||
constructor(public center: vec2, public radius: number) {}
|
||||
}
|
||||
4
shared/src/helper/clamp.ts
Normal file
4
shared/src/helper/clamp.ts
Normal file
|
|
@ -0,0 +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));
|
||||
23
shared/src/helper/delta-time-calculator.ts
Normal file
23
shared/src/helper/delta-time-calculator.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
export class DeltaTimeCalculator {
|
||||
private previousTime: DOMHighResTimeStamp | null = null;
|
||||
|
||||
constructor() {
|
||||
document.addEventListener('visibilitychange', this.handleVisibilityChange.bind(this));
|
||||
}
|
||||
|
||||
public getNextDeltaTime(currentTime: DOMHighResTimeStamp): DOMHighResTimeStamp {
|
||||
if (this.previousTime === null) {
|
||||
this.previousTime = currentTime;
|
||||
}
|
||||
|
||||
const delta = currentTime - this.previousTime;
|
||||
this.previousTime = currentTime;
|
||||
return delta;
|
||||
}
|
||||
|
||||
private handleVisibilityChange() {
|
||||
if (!document.hidden) {
|
||||
this.previousTime = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
shared/src/helper/last.ts
Normal file
3
shared/src/helper/last.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export function last<T>(a: Array<T>): T | null {
|
||||
return a.length > 0 ? a[a.length - 1] : null;
|
||||
}
|
||||
1
shared/src/helper/mix.ts
Normal file
1
shared/src/helper/mix.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export const mix = (from: number, to: number, q: number) => from + (to - from) * q;
|
||||
4
shared/src/helper/pretty-print.ts
Normal file
4
shared/src/helper/pretty-print.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
export const prettyPrint = (o: any): string =>
|
||||
JSON.stringify(o, (_, v) => (v.toFixed ? Number(v.toFixed(3)) : v), ' ')
|
||||
.replace(/("|,|{|^\n)/g, '')
|
||||
.replace(/(\W*}\n?)+/g, '\n\n');
|
||||
18
shared/src/helper/random.ts
Normal file
18
shared/src/helper/random.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// src
|
||||
// https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript
|
||||
// Mulberry32
|
||||
|
||||
export abstract class Random {
|
||||
private static _seed = Math.random();
|
||||
|
||||
public static set seed(value: number) {
|
||||
Random._seed = value;
|
||||
}
|
||||
|
||||
public static getRandom(): number {
|
||||
let t = (Random._seed += 0x6d2b79f5);
|
||||
t = Math.imul(t ^ (t >>> 15), t | 1);
|
||||
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
||||
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
||||
}
|
||||
}
|
||||
5
shared/src/helper/rectangle.ts
Normal file
5
shared/src/helper/rectangle.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
|
||||
export class Rectangle {
|
||||
constructor(public topLeft = vec2.create(), public size = vec2.create()) {}
|
||||
}
|
||||
3
shared/src/helper/rgb.ts
Normal file
3
shared/src/helper/rgb.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import { vec3 } from 'gl-matrix';
|
||||
|
||||
export const rgb = (r: number, g: number, b: number): vec3 => vec3.fromValues(r, g, b);
|
||||
4
shared/src/helper/rgb255.ts
Normal file
4
shared/src/helper/rgb255.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import { vec3 } from 'gl-matrix';
|
||||
|
||||
export const rgb255 = (r: number, g: number, b: number): vec3 =>
|
||||
vec3.fromValues(r / 255, g / 255, b / 255);
|
||||
3
shared/src/helper/rotate-90-deg.ts
Normal file
3
shared/src/helper/rotate-90-deg.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
|
||||
export const rotate90Deg = (vec: vec2): vec2 => vec2.fromValues(-vec.y, vec.x);
|
||||
1
shared/src/helper/to-percent.ts
Normal file
1
shared/src/helper/to-percent.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export const toPercent = (value: number) => `${Math.round(value * 100)}%`;
|
||||
5
shared/src/helper/unique.ts
Normal file
5
shared/src/helper/unique.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
let currentId = 0;
|
||||
|
||||
export const id = (): number => {
|
||||
return currentId++;
|
||||
};
|
||||
3
shared/src/helper/wait.ts
Normal file
3
shared/src/helper/wait.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export const wait = (ms: number): Promise<void> => {
|
||||
return new Promise<void>((resolve, _) => setTimeout(resolve, ms));
|
||||
};
|
||||
29
shared/src/main.ts
Normal file
29
shared/src/main.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
export * from './commands/command';
|
||||
export * from './commands/types/create-objects';
|
||||
export * from './commands/types/create-player';
|
||||
export * from './commands/types/delete-objects';
|
||||
export * from './commands/types/update-objects';
|
||||
export * from './commands/types/ternary-action';
|
||||
export * from './commands/types/move-action';
|
||||
export * from './commands/types/set-view-area-action';
|
||||
export * from './commands/types/primary-action';
|
||||
export * from './commands/types/secondary-action';
|
||||
export * from './commands/command-receiver';
|
||||
export * from './commands/command-generator';
|
||||
export * from './commands/broadcast-commands';
|
||||
export * from './helper/array';
|
||||
export * from './helper/clamp';
|
||||
export * from './helper/circle';
|
||||
export * from './helper/rectangle';
|
||||
export * from './helper/mix';
|
||||
export * from './helper/random';
|
||||
export * from './helper/unique';
|
||||
export * from './helper/rotate-90-deg';
|
||||
export * from './objects/game-object';
|
||||
export * from './objects/deserialize';
|
||||
export * from './objects/types/character-base';
|
||||
export * from './objects/types/lamp-base';
|
||||
export * from './objects/types/tunnel-base';
|
||||
export * from './settings';
|
||||
export * from './transport/transport-events';
|
||||
export * from './transport/identity';
|
||||
26
shared/src/objects/deserialize.ts
Normal file
26
shared/src/objects/deserialize.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { CreatePlayerCommand } from '../commands/types/create-player';
|
||||
import { MoveActionCommand } from '../commands/types/move-action';
|
||||
import { PrimaryActionCommand } from '../commands/types/primary-action';
|
||||
import { SecondaryActionCommand } from '../commands/types/secondary-action';
|
||||
import { SetViewAreaActionCommand } from '../commands/types/set-view-area-action';
|
||||
import { TernaryActionCommand } from '../commands/types/ternary-action';
|
||||
import { UpdateObjectsCommand } from '../commands/types/update-objects';
|
||||
import { Command, CreateObjectsCommand, DeleteObjectsCommand } from '../main';
|
||||
|
||||
export const commandConstructors: {
|
||||
[type: string]: new (...values: Array<any>) => any;
|
||||
} = {
|
||||
[CreateObjectsCommand.type]: CreateObjectsCommand,
|
||||
[DeleteObjectsCommand.type]: DeleteObjectsCommand,
|
||||
[CreatePlayerCommand.type]: CreatePlayerCommand,
|
||||
[MoveActionCommand.type]: MoveActionCommand,
|
||||
[PrimaryActionCommand.type]: PrimaryActionCommand,
|
||||
[SecondaryActionCommand.type]: SecondaryActionCommand,
|
||||
[TernaryActionCommand.type]: TernaryActionCommand,
|
||||
[SetViewAreaActionCommand.type]: SetViewAreaActionCommand,
|
||||
[UpdateObjectsCommand.type]: UpdateObjectsCommand,
|
||||
};
|
||||
|
||||
export const deserializeCommand = ([type, ...values]: [string, Array<any>]): Command => {
|
||||
return new commandConstructors[type](...values);
|
||||
};
|
||||
12
shared/src/objects/game-object.ts
Normal file
12
shared/src/objects/game-object.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { CommandReceiver } from '../commands/command-receiver';
|
||||
import { Id } from '../transport/identity';
|
||||
|
||||
export abstract class GameObject extends CommandReceiver {
|
||||
public get type(): string {
|
||||
return (this as any).constructor.type;
|
||||
}
|
||||
|
||||
constructor(public readonly id: Id) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
17
shared/src/objects/types/character-base.ts
Normal file
17
shared/src/objects/types/character-base.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { Circle } from '../../helper/circle';
|
||||
import { Id } from '../../main';
|
||||
import { GameObject } from '../game-object';
|
||||
|
||||
export abstract class CharacterBase extends GameObject {
|
||||
public static readonly type = 'Character';
|
||||
|
||||
constructor(
|
||||
id: Id,
|
||||
public head: Circle,
|
||||
public leftFoot: Circle,
|
||||
public rightFoot: Circle
|
||||
) {
|
||||
super(id);
|
||||
}
|
||||
}
|
||||
11
shared/src/objects/types/lamp-base.ts
Normal file
11
shared/src/objects/types/lamp-base.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { vec2, vec3 } from 'gl-matrix';
|
||||
import { Id } from '../../main';
|
||||
import { GameObject } from '../game-object';
|
||||
|
||||
export abstract class LampBase extends GameObject {
|
||||
public static readonly type = 'Lamp';
|
||||
|
||||
constructor(id: Id, public center: vec2, public color: vec3, public lightness: number) {
|
||||
super(id);
|
||||
}
|
||||
}
|
||||
17
shared/src/objects/types/tunnel-base.ts
Normal file
17
shared/src/objects/types/tunnel-base.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { GameObject, Id } from '../../main';
|
||||
import { typed } from '../../transport/typed';
|
||||
|
||||
export abstract class TunnelBase extends GameObject {
|
||||
public static readonly type = 'Tunnel';
|
||||
|
||||
constructor(
|
||||
id: Id,
|
||||
public readonly from: vec2,
|
||||
public readonly to: vec2,
|
||||
public readonly fromRadius: number,
|
||||
public readonly toRadius: number
|
||||
) {
|
||||
super(id);
|
||||
}
|
||||
}
|
||||
13
shared/src/settings.ts
Normal file
13
shared/src/settings.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
|
||||
export const settings = {
|
||||
lightCutoffDistance: 600,
|
||||
hitDetectionCirclePointCount: 32,
|
||||
hitDetectionMaxOverlap: 0.01,
|
||||
physicsMaxStep: 5,
|
||||
gravitationalForce: vec2.fromValues(0, -0.015),
|
||||
maxVelocityX: 1.5,
|
||||
maxVelocityY: 8,
|
||||
velocityAttenuation: 0.99,
|
||||
inViewAreaSize: 1920 * 1080 * 3,
|
||||
};
|
||||
8
shared/src/transport/identity-manager.ts
Normal file
8
shared/src/transport/identity-manager.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import { v4 } from 'uuid';
|
||||
import { Id } from './identity';
|
||||
|
||||
export class IdentityManager {
|
||||
public static generateId(): Id {
|
||||
return v4();
|
||||
}
|
||||
}
|
||||
1
shared/src/transport/identity.ts
Normal file
1
shared/src/transport/identity.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export type Id = number;
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
export enum TransportEvents {
|
||||
PlayerJoining = "PlayerJoining",
|
||||
PlayerSendingInfo = "PlayerSendingInfo",
|
||||
PlayerJoining = 'PlayerJoining',
|
||||
PlayerToServer = 'PlayerToServer',
|
||||
ServerToPlayer = 'ServerToPlayer',
|
||||
}
|
||||
|
|
|
|||
11
shared/src/transport/typed.ts
Normal file
11
shared/src/transport/typed.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/**
|
||||
* static type: string must be implemented
|
||||
* @param constructor
|
||||
*/
|
||||
export const typed = <T extends { new (...args: any[]): {} }>(constructor: T) => {
|
||||
return class extends constructor {
|
||||
public get type(): string {
|
||||
return (this as any).constructor.type;
|
||||
}
|
||||
};
|
||||
};
|
||||
15
shared/tsconfig.json
Normal file
15
shared/tsconfig.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/",
|
||||
"sourceMap": true,
|
||||
"noImplicitAny": false,
|
||||
"target": "es6",
|
||||
"downlevelIteration": true,
|
||||
"allowJs": true,
|
||||
"experimentalDecorators": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"moduleResolution": "Node",
|
||||
"module": "es6",
|
||||
"lib": ["es2015", "dom"]
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue