Refactor frontend to use commands
This commit is contained in:
parent
be26ab422c
commit
503c99cb1f
25 changed files with 8031 additions and 23084 deletions
30679
frontend/package-lock.json
generated
30679
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -6,9 +6,6 @@ import {
|
|||
CharacterBase,
|
||||
ProjectileBase,
|
||||
} from 'shared';
|
||||
import { LampView } from './scripts/objects/lamp-view';
|
||||
import { ProjectileView } from './scripts/objects/projectile-view';
|
||||
import { PlanetView } from './scripts/objects/planet-view';
|
||||
import './main.scss';
|
||||
import '../static/og-image.png';
|
||||
import '../static/favicons/apple-touch-icon.png';
|
||||
|
|
@ -19,7 +16,6 @@ import { LandingPageBackground } from './scripts/landing-page-background';
|
|||
import { JoinFormHandler } from './scripts/join-form-handler';
|
||||
import { handleFullScreen } from './scripts/helper/handle-full-screen';
|
||||
import { Game } from './scripts/game';
|
||||
import { CharacterView } from './scripts/objects/character-view';
|
||||
import { handleInsights } from './scripts/handle-insights';
|
||||
import { getInsightsFromRenderer } from './scripts/get-insights-from-renderer';
|
||||
import { Renderer } from 'sdf-2d';
|
||||
|
|
@ -29,6 +25,10 @@ import { hide } from './scripts/helper/hide';
|
|||
import { show } from './scripts/helper/show';
|
||||
import { SoundHandler, Sounds } from './scripts/sound-handler';
|
||||
import { VibrationHandler } from './scripts/vibration-handler';
|
||||
import { CharacterView } from './scripts/objects/types/character-view';
|
||||
import { LampView } from './scripts/objects/types/lamp-view';
|
||||
import { PlanetView } from './scripts/objects/types/planet-view';
|
||||
import { ProjectileView } from './scripts/objects/types/projectile-view';
|
||||
|
||||
glMatrix.setMatrixArrayType(Array);
|
||||
|
||||
|
|
|
|||
7
frontend/src/scripts/commands/types/before-destroy.ts
Normal file
7
frontend/src/scripts/commands/types/before-destroy.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { Command } from 'shared';
|
||||
|
||||
export class BeforeDestroyCommand extends Command {
|
||||
public constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
13
frontend/src/scripts/commands/types/render.ts
Normal file
13
frontend/src/scripts/commands/types/render.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { Renderer } from 'sdf-2d';
|
||||
import { Command } from 'shared';
|
||||
|
||||
export class RenderCommand extends Command {
|
||||
public constructor(
|
||||
public readonly renderer: Renderer,
|
||||
public readonly overlay: HTMLElement,
|
||||
public readonly shouldChangeLayout: boolean,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
7
frontend/src/scripts/commands/types/step.ts
Normal file
7
frontend/src/scripts/commands/types/step.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { Command } from 'shared';
|
||||
|
||||
export class StepCommand extends Command {
|
||||
public constructor(public readonly deltaTimeInSeconds: number) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
|
@ -33,6 +33,8 @@ import { GameObjectContainer } from './objects/game-object-container';
|
|||
import parser from 'socket.io-msgpack-parser';
|
||||
import { BlobShape } from './shapes/blob-shape';
|
||||
import { PlanetShape } from './shapes/planet-shape';
|
||||
import { RenderCommand } from './commands/types/render';
|
||||
import { StepCommand } from './commands/types/step';
|
||||
|
||||
export class Game extends CommandReceiver {
|
||||
public gameObjects = new GameObjectContainer(this);
|
||||
|
|
@ -107,7 +109,7 @@ export class Game extends CommandReceiver {
|
|||
|
||||
this.socket.on(TransportEvents.ServerToPlayer, (serializedCommands: string) => {
|
||||
const commands: Array<Command> = deserialize(serializedCommands);
|
||||
commands.forEach((c) => this.sendCommand(c));
|
||||
commands.forEach((c) => this.handleCommand(c));
|
||||
});
|
||||
|
||||
this.socketReceiver = new CommandSocket(this.socket);
|
||||
|
|
@ -124,7 +126,7 @@ export class Game extends CommandReceiver {
|
|||
}
|
||||
|
||||
protected defaultCommandExecutor(c: Command) {
|
||||
this.gameObjects.sendCommand(c);
|
||||
this.gameObjects.handleCommand(c);
|
||||
}
|
||||
|
||||
private lastGameState?: UpdateGameState;
|
||||
|
|
@ -248,7 +250,7 @@ export class Game extends CommandReceiver {
|
|||
}
|
||||
|
||||
public aspectRatioChanged(aspectRatio: number) {
|
||||
this.socketReceiver.sendCommand(new SetAspectRatioActionCommand(aspectRatio));
|
||||
this.socketReceiver.handleCommand(new SetAspectRatioActionCommand(aspectRatio));
|
||||
}
|
||||
|
||||
private isActive = true;
|
||||
|
|
@ -284,9 +286,12 @@ export class Game extends CommandReceiver {
|
|||
|
||||
this.renderer = renderer;
|
||||
|
||||
this.gameObjects.handleCommand(new StepCommand(deltaTime));
|
||||
this.gameObjects.handleCommand(
|
||||
new RenderCommand(this.renderer, this.overlay, shouldChangeLayout),
|
||||
);
|
||||
|
||||
this.socketReceiver.sendQueuedCommands();
|
||||
this.gameObjects.stepObjects(deltaTime);
|
||||
this.gameObjects.drawObjects(this.renderer, this.overlay, shouldChangeLayout);
|
||||
|
||||
return this.isActive;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,24 @@
|
|||
import { Renderer } from 'sdf-2d';
|
||||
import {
|
||||
Command,
|
||||
CommandExecutors,
|
||||
CommandReceiver,
|
||||
CreateObjectsCommand,
|
||||
CreatePlayerCommand,
|
||||
DeleteObjectsCommand,
|
||||
GameObject,
|
||||
Id,
|
||||
PropertyUpdatesForObjects,
|
||||
RemoteCallsForObjects,
|
||||
} from 'shared';
|
||||
import { BeforeDestroyCommand } from '../commands/types/before-destroy';
|
||||
import { StepCommand } from '../commands/types/step';
|
||||
import { Game } from '../game';
|
||||
import { Camera } from './camera';
|
||||
import { CharacterView } from './character-view';
|
||||
import { ViewObject } from './view-object';
|
||||
import { Camera } from './types/camera';
|
||||
import { CharacterView } from './types/character-view';
|
||||
|
||||
export class GameObjectContainer extends CommandReceiver {
|
||||
protected objects: Map<Id, ViewObject> = new Map();
|
||||
protected objects: Map<Id, GameObject> = new Map();
|
||||
public player!: CharacterView;
|
||||
public camera!: Camera;
|
||||
|
||||
|
|
@ -35,7 +38,15 @@ export class GameObjectContainer extends CommandReceiver {
|
|||
},
|
||||
|
||||
[CreateObjectsCommand.type]: (c: CreateObjectsCommand) =>
|
||||
c.objects.forEach((o) => this.addObject(o as ViewObject)),
|
||||
c.objects.forEach((o) => this.addObject(o as GameObject)),
|
||||
|
||||
[StepCommand.type]: (c: StepCommand) => {
|
||||
this.objects.forEach((o) => o.handleCommand(c));
|
||||
|
||||
if (this.player) {
|
||||
this.camera.center = this.player.position;
|
||||
}
|
||||
},
|
||||
|
||||
[RemoteCallsForObjects.type]: (c: RemoteCallsForObjects) =>
|
||||
c.callsForObjects.forEach((c) =>
|
||||
|
|
@ -43,7 +54,9 @@ export class GameObjectContainer extends CommandReceiver {
|
|||
),
|
||||
|
||||
[PropertyUpdatesForObjects.type]: (c: PropertyUpdatesForObjects) =>
|
||||
c.updates.forEach((c) => this.objects.get(c.id)?.updateProperties(c.updates)),
|
||||
c.updates.forEach((u) =>
|
||||
u.updates.forEach((au) => this.objects.get(u.id)?.handleCommand(au)),
|
||||
),
|
||||
|
||||
[DeleteObjectsCommand.type]: (c: DeleteObjectsCommand) =>
|
||||
c.ids.forEach((id: Id) => this.deleteObject(id)),
|
||||
|
|
@ -53,29 +66,17 @@ export class GameObjectContainer extends CommandReceiver {
|
|||
super();
|
||||
}
|
||||
|
||||
public stepObjects(deltaTimeInSeconds: number) {
|
||||
this.objects.forEach((o) => o.step(deltaTimeInSeconds));
|
||||
|
||||
if (this.player) {
|
||||
this.camera.center = this.player.position;
|
||||
}
|
||||
protected defaultCommandExecutor(c: Command) {
|
||||
this.objects.forEach((o) => o.handleCommand(c));
|
||||
}
|
||||
|
||||
public drawObjects(
|
||||
renderer: Renderer,
|
||||
overlay: HTMLElement,
|
||||
shouldChangeLayout: boolean,
|
||||
) {
|
||||
this.objects.forEach((o) => o.draw(renderer, overlay, shouldChangeLayout));
|
||||
}
|
||||
|
||||
private addObject(object: ViewObject) {
|
||||
private addObject(object: GameObject) {
|
||||
this.objects.set(object.id, object);
|
||||
}
|
||||
|
||||
private deleteObject(id: Id) {
|
||||
const object = this.objects.get(id);
|
||||
object?.beforeDestroy();
|
||||
object?.handleCommand(new BeforeDestroyCommand());
|
||||
this.objects.delete(id);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
import { vec2, vec3 } from 'gl-matrix';
|
||||
import { CircleLight, Renderer } from 'sdf-2d';
|
||||
import { CommandExecutors, Id, LampBase, UpdateProperty } from 'shared';
|
||||
import { ViewObject } from './view-object';
|
||||
|
||||
export class LampView extends LampBase implements ViewObject {
|
||||
private light: CircleLight;
|
||||
|
||||
constructor(id: Id, center: vec2, color: vec3, lightness: number) {
|
||||
super(id, center, color, lightness);
|
||||
this.light = new CircleLight(center, color, lightness);
|
||||
}
|
||||
|
||||
public updateProperties(update: UpdateProperty[]): void {}
|
||||
|
||||
public step(deltaTimeInSeconds: number): void {}
|
||||
|
||||
public beforeDestroy(): void {}
|
||||
|
||||
public draw(
|
||||
renderer: Renderer,
|
||||
overlay: HTMLElement,
|
||||
shouldChangeLayout: boolean,
|
||||
): void {
|
||||
renderer.addDrawable(this.light);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { CircleLight, Renderer } from 'sdf-2d';
|
||||
import { CharacterTeam, Id, ProjectileBase, settings, UpdateProperty } from 'shared';
|
||||
import { Vec2Extrapolator } from '../helper/vec2-extrapolator';
|
||||
import { ViewObject } from './view-object';
|
||||
|
||||
export class ProjectileView extends ProjectileBase implements ViewObject {
|
||||
private light: CircleLight;
|
||||
|
||||
private centerExtrapolator: Vec2Extrapolator;
|
||||
|
||||
constructor(
|
||||
id: Id,
|
||||
center: vec2,
|
||||
radius: number,
|
||||
team: CharacterTeam,
|
||||
strength: number,
|
||||
) {
|
||||
super(id, center, radius, team, strength);
|
||||
this.light = new CircleLight(
|
||||
center,
|
||||
settings.paletteDim[settings.colorIndices[team]],
|
||||
0,
|
||||
);
|
||||
this.centerExtrapolator = new Vec2Extrapolator(center);
|
||||
}
|
||||
|
||||
public updateProperties(update: UpdateProperty[]): void {
|
||||
update.forEach((u) => {
|
||||
this.centerExtrapolator.addFrame(u.propertyValue, u.rateOfChange);
|
||||
});
|
||||
}
|
||||
|
||||
public step(deltaTimeInSeconds: number): void {
|
||||
super.step(deltaTimeInSeconds);
|
||||
|
||||
this.center = this.centerExtrapolator.getValue(deltaTimeInSeconds);
|
||||
this.light.center = this.center;
|
||||
this.light.intensity = (0.15 * this.strength) / settings.projectileMaxStrength;
|
||||
}
|
||||
|
||||
public beforeDestroy(): void {}
|
||||
|
||||
public draw(
|
||||
renderer: Renderer,
|
||||
overlay: HTMLElement,
|
||||
shouldChangeLayout: boolean,
|
||||
): void {
|
||||
renderer.addDrawable(this.light);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,15 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { Renderer } from 'sdf-2d';
|
||||
import { calculateViewArea, GameObject, mixRgb, settings, UpdateProperty } from 'shared';
|
||||
import {
|
||||
calculateViewArea,
|
||||
CommandExecutors,
|
||||
GameObject,
|
||||
mixRgb,
|
||||
settings,
|
||||
} from 'shared';
|
||||
import { RenderCommand } from '../../commands/types/render';
|
||||
import { Game } from '../../game';
|
||||
|
||||
import { Game } from '../game';
|
||||
import { ViewObject } from './view-object';
|
||||
|
||||
export class Camera extends GameObject implements ViewObject {
|
||||
export class Camera extends GameObject {
|
||||
public center: vec2 = vec2.create();
|
||||
private aspectRatio?: number;
|
||||
|
||||
|
|
@ -13,11 +17,11 @@ export class Camera extends GameObject implements ViewObject {
|
|||
super(null);
|
||||
}
|
||||
|
||||
public updateProperties(update: UpdateProperty[]): void {}
|
||||
public step(deltaTimeInSeconds: number): void {}
|
||||
public beforeDestroy(): void {}
|
||||
protected commandExecutors: CommandExecutors = {
|
||||
[RenderCommand.type]: this.draw.bind(this),
|
||||
};
|
||||
|
||||
public draw(renderer: Renderer) {
|
||||
private draw({ renderer }: RenderCommand) {
|
||||
const canvasAspectRatio = renderer.canvasSize.x / renderer.canvasSize.y;
|
||||
if (canvasAspectRatio !== this.aspectRatio) {
|
||||
this.aspectRatio = canvasAspectRatio;
|
||||
|
|
@ -6,15 +6,18 @@ import {
|
|||
CharacterBase,
|
||||
CharacterTeam,
|
||||
settings,
|
||||
UpdateProperty,
|
||||
CommandExecutors,
|
||||
UpdatePropertyCommand,
|
||||
} from 'shared';
|
||||
import { CircleExtrapolator } from '../helper/circle-extrapolator';
|
||||
import { BlobShape } from '../shapes/blob-shape';
|
||||
import { SoundHandler, Sounds } from '../sound-handler';
|
||||
import { VibrationHandler } from '../vibration-handler';
|
||||
import { ViewObject } from './view-object';
|
||||
import { BeforeDestroyCommand } from '../../commands/types/before-destroy';
|
||||
import { RenderCommand } from '../../commands/types/render';
|
||||
import { StepCommand } from '../../commands/types/step';
|
||||
import { CircleExtrapolator } from '../../helper/circle-extrapolator';
|
||||
import { BlobShape } from '../../shapes/blob-shape';
|
||||
import { SoundHandler, Sounds } from '../../sound-handler';
|
||||
import { VibrationHandler } from '../../vibration-handler';
|
||||
|
||||
export class CharacterView extends CharacterBase implements ViewObject {
|
||||
export class CharacterView extends CharacterBase {
|
||||
private shape: BlobShape;
|
||||
private nameElement: HTMLElement = document.createElement('div');
|
||||
private statsElement: HTMLElement = document.createElement('div');
|
||||
|
|
@ -26,6 +29,13 @@ export class CharacterView extends CharacterBase implements ViewObject {
|
|||
private rightFootExtrapolator: CircleExtrapolator;
|
||||
private headExtrapolator: CircleExtrapolator;
|
||||
|
||||
protected commandExecutors: CommandExecutors = {
|
||||
[RenderCommand.type]: this.draw.bind(this),
|
||||
[StepCommand.type]: this.step.bind(this),
|
||||
[BeforeDestroyCommand.type]: this.beforeDestroy.bind(this),
|
||||
[UpdatePropertyCommand.type]: this.updateProperty.bind(this),
|
||||
};
|
||||
|
||||
constructor(
|
||||
id: Id,
|
||||
name: string,
|
||||
|
|
@ -54,18 +64,20 @@ export class CharacterView extends CharacterBase implements ViewObject {
|
|||
return this.head!.center;
|
||||
}
|
||||
|
||||
public updateProperties(update: Array<UpdateProperty>) {
|
||||
update.forEach((u) => {
|
||||
if (u.propertyKey === 'head') {
|
||||
this.headExtrapolator.addFrame(u.propertyValue, u.rateOfChange);
|
||||
}
|
||||
if (u.propertyKey === 'leftFoot') {
|
||||
this.leftFootExtrapolator.addFrame(u.propertyValue, u.rateOfChange);
|
||||
}
|
||||
if (u.propertyKey === 'rightFoot') {
|
||||
this.rightFootExtrapolator.addFrame(u.propertyValue, u.rateOfChange);
|
||||
}
|
||||
});
|
||||
private updateProperty({
|
||||
propertyKey,
|
||||
propertyValue,
|
||||
rateOfChange,
|
||||
}: UpdatePropertyCommand) {
|
||||
if (propertyKey === 'head') {
|
||||
this.headExtrapolator.addFrame(propertyValue, rateOfChange);
|
||||
}
|
||||
if (propertyKey === 'leftFoot') {
|
||||
this.leftFootExtrapolator.addFrame(propertyValue, rateOfChange);
|
||||
}
|
||||
if (propertyKey === 'rightFoot') {
|
||||
this.rightFootExtrapolator.addFrame(propertyValue, rateOfChange);
|
||||
}
|
||||
}
|
||||
|
||||
public setHealth(health: number) {
|
||||
|
|
@ -87,7 +99,7 @@ export class CharacterView extends CharacterBase implements ViewObject {
|
|||
}
|
||||
}
|
||||
|
||||
public step(deltaTimeInSeconds: number): void {
|
||||
private step({ deltaTimeInSeconds }: StepCommand): void {
|
||||
this.head! = this.headExtrapolator.getValue(deltaTimeInSeconds);
|
||||
this.leftFoot! = this.leftFootExtrapolator.getValue(deltaTimeInSeconds);
|
||||
this.rightFoot! = this.rightFootExtrapolator.getValue(deltaTimeInSeconds);
|
||||
|
|
@ -97,15 +109,11 @@ export class CharacterView extends CharacterBase implements ViewObject {
|
|||
SoundHandler.play(Sounds.shoot, (0.6 * strength) / settings.playerMaxStrength);
|
||||
}
|
||||
|
||||
public beforeDestroy(): void {
|
||||
private beforeDestroy(): void {
|
||||
this.nameElement.parentElement?.removeChild(this.nameElement);
|
||||
}
|
||||
|
||||
public draw(
|
||||
renderer: Renderer,
|
||||
overlay: HTMLElement,
|
||||
shouldChangeLayout: boolean,
|
||||
): void {
|
||||
private draw({ renderer, overlay, shouldChangeLayout }: RenderCommand): void {
|
||||
if (shouldChangeLayout) {
|
||||
if (!this.nameElement.parentElement) {
|
||||
overlay.appendChild(this.nameElement);
|
||||
21
frontend/src/scripts/objects/types/lamp-view.ts
Normal file
21
frontend/src/scripts/objects/types/lamp-view.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import { vec2, vec3 } from 'gl-matrix';
|
||||
import { CircleLight, Renderer } from 'sdf-2d';
|
||||
import { CommandExecutors, Id, LampBase, UpdatePropertyCommand } from 'shared';
|
||||
import { RenderCommand } from '../../commands/types/render';
|
||||
|
||||
export class LampView extends LampBase {
|
||||
private light: CircleLight;
|
||||
|
||||
protected commandExecutors: CommandExecutors = {
|
||||
[RenderCommand.type]: this.draw.bind(this),
|
||||
};
|
||||
|
||||
constructor(id: Id, center: vec2, color: vec3, lightness: number) {
|
||||
super(id, center, color, lightness);
|
||||
this.light = new CircleLight(center, color, lightness);
|
||||
}
|
||||
|
||||
private draw({ renderer }: RenderCommand): void {
|
||||
renderer.addDrawable(this.light);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { Renderer } from 'sdf-2d';
|
||||
import { Id, Random, PlanetBase, UpdateProperty } from 'shared';
|
||||
import { PlanetShape } from '../shapes/planet-shape';
|
||||
import { ViewObject } from './view-object';
|
||||
import { Id, Random, PlanetBase, UpdatePropertyCommand, CommandExecutors } from 'shared';
|
||||
import { BeforeDestroyCommand } from '../../commands/types/before-destroy';
|
||||
import { RenderCommand } from '../../commands/types/render';
|
||||
import { StepCommand } from '../../commands/types/step';
|
||||
import { PlanetShape } from '../../shapes/planet-shape';
|
||||
|
||||
type FallingPoint = {
|
||||
velocity: vec2;
|
||||
|
|
@ -12,10 +13,17 @@ type FallingPoint = {
|
|||
timeToLive: number;
|
||||
};
|
||||
|
||||
export class PlanetView extends PlanetBase implements ViewObject {
|
||||
export class PlanetView extends PlanetBase {
|
||||
private shape: PlanetShape;
|
||||
private ownershipProgress: HTMLElement;
|
||||
|
||||
protected commandExecutors: CommandExecutors = {
|
||||
[RenderCommand.type]: this.draw.bind(this),
|
||||
[StepCommand.type]: this.step.bind(this),
|
||||
[BeforeDestroyCommand.type]: this.beforeDestroy.bind(this),
|
||||
[UpdatePropertyCommand.type]: this.updateProperty.bind(this),
|
||||
};
|
||||
|
||||
constructor(id: Id, vertices: Array<vec2>, ownership: number) {
|
||||
super(id, vertices);
|
||||
this.shape = new PlanetShape(vertices, ownership);
|
||||
|
|
@ -25,7 +33,7 @@ export class PlanetView extends PlanetBase implements ViewObject {
|
|||
this.ownershipProgress.className = 'ownership';
|
||||
}
|
||||
|
||||
public step(deltaTimeInSeconds: number): void {
|
||||
private step(deltaTimeInSeconds: number): void {
|
||||
this.shape.randomOffset += deltaTimeInSeconds / 4;
|
||||
this.shape.colorMixQ = this.ownership;
|
||||
|
||||
|
|
@ -53,24 +61,18 @@ export class PlanetView extends PlanetBase implements ViewObject {
|
|||
this.lastGeneratedPoint = value;
|
||||
}
|
||||
|
||||
public beforeDestroy(): void {
|
||||
private beforeDestroy(): void {
|
||||
this.ownershipProgress.parentElement?.removeChild(this.ownershipProgress);
|
||||
this.generatedPointElements.forEach((p) =>
|
||||
p.element.parentElement?.removeChild(p.element),
|
||||
);
|
||||
}
|
||||
|
||||
public updateProperties(update: UpdateProperty[]): void {
|
||||
update.forEach((u) => {
|
||||
this.ownership = u.propertyValue;
|
||||
});
|
||||
private updateProperty({ propertyValue }: UpdatePropertyCommand): void {
|
||||
this.ownership = propertyValue;
|
||||
}
|
||||
|
||||
public draw(
|
||||
renderer: Renderer,
|
||||
overlay: HTMLElement,
|
||||
shouldChangeLayout: boolean,
|
||||
): void {
|
||||
private draw({ renderer, overlay, shouldChangeLayout }: RenderCommand): void {
|
||||
if (shouldChangeLayout) {
|
||||
if (!this.ownershipProgress.parentElement) {
|
||||
overlay.appendChild(this.ownershipProgress);
|
||||
57
frontend/src/scripts/objects/types/projectile-view.ts
Normal file
57
frontend/src/scripts/objects/types/projectile-view.ts
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { CircleLight, Renderer } from 'sdf-2d';
|
||||
import {
|
||||
CharacterTeam,
|
||||
CommandExecutors,
|
||||
Id,
|
||||
ProjectileBase,
|
||||
settings,
|
||||
UpdatePropertyCommand,
|
||||
} from 'shared';
|
||||
import { RenderCommand } from '../../commands/types/render';
|
||||
import { StepCommand } from '../../commands/types/step';
|
||||
import { Vec2Extrapolator } from '../../helper/vec2-extrapolator';
|
||||
|
||||
export class ProjectileView extends ProjectileBase {
|
||||
private light: CircleLight;
|
||||
|
||||
private centerExtrapolator: Vec2Extrapolator;
|
||||
|
||||
protected commandExecutors: CommandExecutors = {
|
||||
[RenderCommand.type]: this.draw.bind(this),
|
||||
[StepCommand.type]: this.handleStep.bind(this),
|
||||
[UpdatePropertyCommand.type]: this.updateProperty.bind(this),
|
||||
};
|
||||
|
||||
constructor(
|
||||
id: Id,
|
||||
center: vec2,
|
||||
radius: number,
|
||||
team: CharacterTeam,
|
||||
strength: number,
|
||||
) {
|
||||
super(id, center, radius, team, strength);
|
||||
this.light = new CircleLight(
|
||||
center,
|
||||
settings.paletteDim[settings.colorIndices[team]],
|
||||
0,
|
||||
);
|
||||
this.centerExtrapolator = new Vec2Extrapolator(center);
|
||||
}
|
||||
|
||||
private updateProperty({ propertyValue, rateOfChange }: UpdatePropertyCommand): void {
|
||||
this.centerExtrapolator.addFrame(propertyValue, rateOfChange);
|
||||
}
|
||||
|
||||
private handleStep({ deltaTimeInSeconds }: StepCommand): void {
|
||||
this.step(deltaTimeInSeconds);
|
||||
|
||||
this.center = this.centerExtrapolator.getValue(deltaTimeInSeconds);
|
||||
this.light.center = this.center;
|
||||
this.light.intensity = (0.15 * this.strength) / settings.projectileMaxStrength;
|
||||
}
|
||||
|
||||
private draw({ renderer }: RenderCommand): void {
|
||||
renderer.addDrawable(this.light);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
import { Renderer } from 'sdf-2d';
|
||||
import { GameObject, UpdateProperty } from 'shared';
|
||||
|
||||
export interface ViewObject extends GameObject {
|
||||
step(deltaTimeInMilliseconds: number): void;
|
||||
draw(renderer: Renderer, overlay: HTMLElement, shouldChangeLayout: boolean): void;
|
||||
updateProperties(update: Array<UpdateProperty>): void;
|
||||
beforeDestroy(): void;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue