Add projectile damage
This commit is contained in:
parent
f9f6825776
commit
555be9d602
14 changed files with 111 additions and 40 deletions
11
backend/Dockerfile
Normal file
11
backend/Dockerfile
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
FROM node:14.13.0-alpine3.10
|
||||||
|
|
||||||
|
COPY package.json .
|
||||||
|
|
||||||
|
RUN npm install --production
|
||||||
|
|
||||||
|
COPY dist/main.js main.js
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
CMD [ "node", "main.js" ]
|
||||||
|
|
@ -95,7 +95,7 @@ const handlePhysics = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
objects.stepObjects(delta);
|
objects.stepObjects(delta);
|
||||||
players.forEach((p) => p.sendObjects());
|
players.forEach((p) => p.step(delta));
|
||||||
|
|
||||||
const physicsDelta = deltaTimeCalculator.getDeltaTimeInMilliseconds();
|
const physicsDelta = deltaTimeCalculator.getDeltaTimeInMilliseconds();
|
||||||
deltas.push(physicsDelta);
|
deltas.push(physicsDelta);
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ export const createDungeon = (objectContainer: PhysicalContainer) => {
|
||||||
Random.getRandomInRange(0.5, 1),
|
Random.getRandomInRange(0.5, 1),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Random.getRandomInRange(0.75, 1.5),
|
Random.getRandomInRange(0.25, 1),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,24 +7,26 @@ import {
|
||||||
serializesTo,
|
serializesTo,
|
||||||
clamp,
|
clamp,
|
||||||
last,
|
last,
|
||||||
|
GameObject,
|
||||||
} from 'shared';
|
} from 'shared';
|
||||||
import { DynamicPhysical } from '../physics/conatiners/dynamic-physical';
|
import { DynamicPhysical } from '../physics/conatiners/dynamic-physical';
|
||||||
import { ImmutableBoundingBox } from '../physics/bounding-boxes/immutable-bounding-box';
|
|
||||||
import { CirclePhysical } from './circle-physical';
|
import { CirclePhysical } from './circle-physical';
|
||||||
|
|
||||||
import { PhysicalContainer } from '../physics/containers/physical-container';
|
import { PhysicalContainer } from '../physics/containers/physical-container';
|
||||||
import { Spring } from './spring';
|
import { Spring } from './spring';
|
||||||
|
import { BoundingBoxBase } from '../physics/bounding-boxes/bounding-box-base';
|
||||||
|
import { ProjectilePhysical } from './projectile-physical';
|
||||||
|
|
||||||
@serializesTo(CharacterBase)
|
@serializesTo(CharacterBase)
|
||||||
export class CharacterPhysical extends CharacterBase implements DynamicPhysical {
|
export class CharacterPhysical extends CharacterBase implements DynamicPhysical {
|
||||||
public readonly canCollide = true;
|
public readonly canCollide = true;
|
||||||
public readonly canMove = true;
|
public readonly canMove = true;
|
||||||
|
private isDestroyed = false;
|
||||||
private jumpEnergyLeft = settings.defaultJumpEnergy;
|
private jumpEnergyLeft = settings.defaultJumpEnergy;
|
||||||
|
|
||||||
public head: CirclePhysical;
|
public head: CirclePhysical;
|
||||||
public leftFoot: CirclePhysical;
|
public leftFoot: CirclePhysical;
|
||||||
public rightFoot: CirclePhysical;
|
public rightFoot: CirclePhysical;
|
||||||
|
public bound: CirclePhysical;
|
||||||
|
|
||||||
private movementActions: Array<MoveActionCommand> = [];
|
private movementActions: Array<MoveActionCommand> = [];
|
||||||
private lastMovementAction: MoveActionCommand = new MoveActionCommand(vec2.create());
|
private lastMovementAction: MoveActionCommand = new MoveActionCommand(vec2.create());
|
||||||
|
|
@ -34,6 +36,8 @@ export class CharacterPhysical extends CharacterBase implements DynamicPhysical
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly headOffset = vec2.fromValues(0, 40);
|
private static readonly headOffset = vec2.fromValues(0, 40);
|
||||||
|
private static readonly headRadius = 50;
|
||||||
|
private static readonly feetRadius = 20;
|
||||||
private static readonly leftFootOffset = vec2.fromValues(-20, -35);
|
private static readonly leftFootOffset = vec2.fromValues(-20, -35);
|
||||||
private static readonly rightFootOffset = vec2.fromValues(20, -35);
|
private static readonly rightFootOffset = vec2.fromValues(20, -35);
|
||||||
|
|
||||||
|
|
@ -44,35 +48,44 @@ export class CharacterPhysical extends CharacterBase implements DynamicPhysical
|
||||||
super(id(), colorIndex);
|
super(id(), colorIndex);
|
||||||
this.head = new CirclePhysical(
|
this.head = new CirclePhysical(
|
||||||
vec2.clone(CharacterPhysical.headOffset),
|
vec2.clone(CharacterPhysical.headOffset),
|
||||||
50,
|
CharacterPhysical.headRadius,
|
||||||
this,
|
this,
|
||||||
container,
|
container,
|
||||||
);
|
);
|
||||||
this.leftFoot = new CirclePhysical(
|
this.leftFoot = new CirclePhysical(
|
||||||
vec2.clone(CharacterPhysical.leftFootOffset),
|
vec2.clone(CharacterPhysical.leftFootOffset),
|
||||||
20,
|
CharacterPhysical.feetRadius,
|
||||||
this,
|
this,
|
||||||
container,
|
container,
|
||||||
);
|
);
|
||||||
this.rightFoot = new CirclePhysical(
|
this.rightFoot = new CirclePhysical(
|
||||||
vec2.clone(CharacterPhysical.rightFootOffset),
|
vec2.clone(CharacterPhysical.rightFootOffset),
|
||||||
20,
|
CharacterPhysical.feetRadius,
|
||||||
this,
|
this,
|
||||||
container,
|
container,
|
||||||
);
|
);
|
||||||
container.addObject(this.head);
|
container.addObject(this.head);
|
||||||
container.addObject(this.leftFoot);
|
container.addObject(this.leftFoot);
|
||||||
container.addObject(this.rightFoot);
|
container.addObject(this.rightFoot);
|
||||||
|
|
||||||
|
this.bound = new CirclePhysical(
|
||||||
|
vec2.create(),
|
||||||
|
(CharacterPhysical.headRadius + CharacterPhysical.feetRadius * 2) * 2,
|
||||||
|
this,
|
||||||
|
container,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _boundingBox?: ImmutableBoundingBox;
|
public onCollision(other: GameObject) {
|
||||||
|
if (other instanceof ProjectilePhysical) {
|
||||||
public get boundingBox(): ImmutableBoundingBox {
|
other.destroy();
|
||||||
if (!this._boundingBox) {
|
this.destroy();
|
||||||
this._boundingBox = (this.head as CirclePhysical).boundingBox;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._boundingBox;
|
public get boundingBox(): BoundingBoxBase {
|
||||||
|
this.bound.center = this.head.center;
|
||||||
|
return this.bound.boundingBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get gameObject(): this {
|
public get gameObject(): this {
|
||||||
|
|
@ -209,8 +222,12 @@ export class CharacterPhysical extends CharacterBase implements DynamicPhysical
|
||||||
}
|
}
|
||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
|
if (!this.isDestroyed) {
|
||||||
|
this.isDestroyed = true;
|
||||||
|
this.container.removeObject(this);
|
||||||
this.container.removeObject(this.head);
|
this.container.removeObject(this.head);
|
||||||
this.container.removeObject(this.leftFoot);
|
this.container.removeObject(this.leftFoot);
|
||||||
this.container.removeObject(this.rightFoot);
|
this.container.removeObject(this.rightFoot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { BoundingBox } from '../physics/bounding-boxes/bounding-box';
|
||||||
import { BoundingBoxBase } from '../physics/bounding-boxes/bounding-box-base';
|
import { BoundingBoxBase } from '../physics/bounding-boxes/bounding-box-base';
|
||||||
import { moveCircle } from '../physics/move-circle';
|
import { moveCircle } from '../physics/move-circle';
|
||||||
import { PhysicalContainer } from '../physics/containers/physical-container';
|
import { PhysicalContainer } from '../physics/containers/physical-container';
|
||||||
import { DynamicPhysical } from '../physics/conatiners/dynamic-physical';
|
import { DynamicPhysical } from '../physics/containers/dynamic-physical';
|
||||||
|
|
||||||
@serializesTo(Circle)
|
@serializesTo(Circle)
|
||||||
export class CirclePhysical implements Circle, DynamicPhysical {
|
export class CirclePhysical implements Circle, DynamicPhysical {
|
||||||
|
|
@ -25,7 +25,7 @@ export class CirclePhysical implements Circle, DynamicPhysical {
|
||||||
constructor(
|
constructor(
|
||||||
private _center: vec2,
|
private _center: vec2,
|
||||||
private _radius: number,
|
private _radius: number,
|
||||||
public owner: GameObject,
|
public owner: DynamicPhysical,
|
||||||
private readonly container: PhysicalContainer,
|
private readonly container: PhysicalContainer,
|
||||||
private restitution = 0,
|
private restitution = 0,
|
||||||
) {
|
) {
|
||||||
|
|
@ -46,6 +46,10 @@ export class CirclePhysical implements Circle, DynamicPhysical {
|
||||||
this.recalculateBoundingBox();
|
this.recalculateBoundingBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public onCollision(other: GameObject) {
|
||||||
|
this.owner.onCollision(other);
|
||||||
|
}
|
||||||
|
|
||||||
public get gameObject(): GameObject {
|
public get gameObject(): GameObject {
|
||||||
return this.owner;
|
return this.owner;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,5 @@
|
||||||
import { vec2 } from 'gl-matrix';
|
import { vec2 } from 'gl-matrix';
|
||||||
import {
|
import { id, settings, serializesTo, ProjectileBase, GameObject } from 'shared';
|
||||||
id,
|
|
||||||
settings,
|
|
||||||
serializesTo,
|
|
||||||
ProjectileBase,
|
|
||||||
GameObject,
|
|
||||||
rotate90Deg,
|
|
||||||
} from 'shared';
|
|
||||||
import { ImmutableBoundingBox } from '../physics/bounding-boxes/immutable-bounding-box';
|
import { ImmutableBoundingBox } from '../physics/bounding-boxes/immutable-bounding-box';
|
||||||
import { CirclePhysical } from './circle-physical';
|
import { CirclePhysical } from './circle-physical';
|
||||||
import { DynamicPhysical } from '../physics/conatiners/dynamic-physical';
|
import { DynamicPhysical } from '../physics/conatiners/dynamic-physical';
|
||||||
|
|
@ -16,6 +9,8 @@ import { PhysicalContainer } from '../physics/containers/physical-container';
|
||||||
export class ProjectilePhysical extends ProjectileBase implements DynamicPhysical {
|
export class ProjectilePhysical extends ProjectileBase implements DynamicPhysical {
|
||||||
public readonly canCollide = true;
|
public readonly canCollide = true;
|
||||||
public readonly canMove = true;
|
public readonly canMove = true;
|
||||||
|
private isDestroyed = false;
|
||||||
|
private bounceCount = 0;
|
||||||
|
|
||||||
public object: CirclePhysical;
|
public object: CirclePhysical;
|
||||||
|
|
||||||
|
|
@ -47,9 +42,17 @@ export class ProjectilePhysical extends ProjectileBase implements DynamicPhysica
|
||||||
return this.object.distance(target);
|
return this.object.distance(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onCollision(normal: vec2, other: GameObject) {
|
public destroy() {
|
||||||
const tangent = rotate90Deg(normal);
|
if (!this.isDestroyed) {
|
||||||
vec2.scale(this.velocity, tangent, vec2.dot(tangent, this.velocity));
|
this.isDestroyed = true;
|
||||||
|
this.container.removeObject(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public onCollision(other: GameObject) {
|
||||||
|
if (this.bounceCount++ === settings.projectileMaxBounceCount) {
|
||||||
|
this.destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public step(deltaTimeInMiliseconds: number) {
|
public step(deltaTimeInMiliseconds: number) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
|
import { GameObject } from 'shared';
|
||||||
import { Physical } from '../physical';
|
import { Physical } from '../physical';
|
||||||
|
|
||||||
export interface DynamicPhysical extends Physical {
|
export interface DynamicPhysical extends Physical {
|
||||||
|
readonly canMove: true;
|
||||||
step(deltaTimeInMilliseconds: number): void;
|
step(deltaTimeInMilliseconds: number): void;
|
||||||
|
onCollision(other: GameObject): void;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,6 @@ import { Physical } from '../physical';
|
||||||
import { ImmutableBoundingBox } from '../bounding-boxes/immutable-bounding-box';
|
import { ImmutableBoundingBox } from '../bounding-boxes/immutable-bounding-box';
|
||||||
|
|
||||||
export interface StaticPhysical extends Physical {
|
export interface StaticPhysical extends Physical {
|
||||||
|
readonly canMove: false;
|
||||||
readonly boundingBox: ImmutableBoundingBox;
|
readonly boundingBox: ImmutableBoundingBox;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { vec2 } from 'gl-matrix';
|
import { vec2 } from 'gl-matrix';
|
||||||
import { Circle, rotate90Deg } from 'shared';
|
import { Circle, rotate90Deg } from 'shared';
|
||||||
import { CirclePhysical } from '../objects/circle-physical';
|
import { CirclePhysical } from '../objects/circle-physical';
|
||||||
|
import { DynamicPhysical } from './containers/dynamic-physical';
|
||||||
import { Physical } from './physical';
|
import { Physical } from './physical';
|
||||||
|
|
||||||
export const moveCircle = (
|
export const moveCircle = (
|
||||||
|
|
@ -37,6 +38,15 @@ export const moveCircle = (
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const intersecting = possibleIntersectors
|
||||||
|
.filter((i) => i.canCollide && i.canMove)
|
||||||
|
.find((i) => i.distance(nextCircle.center) < circle.radius);
|
||||||
|
|
||||||
|
(intersecting?.gameObject as DynamicPhysical)?.onCollision(circle.gameObject);
|
||||||
|
((circle.gameObject as unknown) as DynamicPhysical).onCollision(
|
||||||
|
intersecting?.gameObject,
|
||||||
|
);
|
||||||
|
|
||||||
const dx =
|
const dx =
|
||||||
getSdfAtPoint(vec2.add(vec2.create(), nextCircle.center, vec2.fromValues(1, 0))) -
|
getSdfAtPoint(vec2.add(vec2.create(), nextCircle.center, vec2.fromValues(1, 0))) -
|
||||||
sdfAtCenter;
|
sdfAtCenter;
|
||||||
|
|
@ -44,9 +54,7 @@ export const moveCircle = (
|
||||||
getSdfAtPoint(vec2.add(vec2.create(), nextCircle.center, vec2.fromValues(0, 1))) -
|
getSdfAtPoint(vec2.add(vec2.create(), nextCircle.center, vec2.fromValues(0, 1))) -
|
||||||
sdfAtCenter;
|
sdfAtCenter;
|
||||||
const normal = vec2.fromValues(dx, dy);
|
const normal = vec2.fromValues(dx, dy);
|
||||||
|
|
||||||
vec2.normalize(normal, normal);
|
vec2.normalize(normal, normal);
|
||||||
|
|
||||||
const rotatedNormal = rotate90Deg(normal);
|
const rotatedNormal = rotate90Deg(normal);
|
||||||
return {
|
return {
|
||||||
realDelta: delta,
|
realDelta: delta,
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ export class Player extends CommandReceiver {
|
||||||
private aspectRatio: number = 16 / 9;
|
private aspectRatio: number = 16 / 9;
|
||||||
private isActive = true;
|
private isActive = true;
|
||||||
|
|
||||||
|
private timeSinceLastProjectile = 0;
|
||||||
|
|
||||||
private objectsPreviouslyInViewArea: Array<Physical> = [];
|
private objectsPreviouslyInViewArea: Array<Physical> = [];
|
||||||
private objectsInViewArea: Array<Physical> = [];
|
private objectsInViewArea: Array<Physical> = [];
|
||||||
|
|
||||||
|
|
@ -51,6 +53,10 @@ export class Player extends CommandReceiver {
|
||||||
[MoveActionCommand.type]: (c: MoveActionCommand) =>
|
[MoveActionCommand.type]: (c: MoveActionCommand) =>
|
||||||
this.character.handleMovementAction(c),
|
this.character.handleMovementAction(c),
|
||||||
[SecondaryActionCommand.type]: (c: SecondaryActionCommand) => {
|
[SecondaryActionCommand.type]: (c: SecondaryActionCommand) => {
|
||||||
|
if (this.timeSinceLastProjectile < settings.projectileCreationInterval) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const start = vec2.clone(this.character.center);
|
const start = vec2.clone(this.character.center);
|
||||||
const direction = vec2.subtract(vec2.create(), c.position, start);
|
const direction = vec2.subtract(vec2.create(), c.position, start);
|
||||||
vec2.normalize(direction, direction);
|
vec2.normalize(direction, direction);
|
||||||
|
|
@ -63,6 +69,8 @@ export class Player extends CommandReceiver {
|
||||||
vec2.add(velocity, velocity, this.character.velocity);
|
vec2.add(velocity, velocity, this.character.velocity);
|
||||||
const projectile = new ProjectilePhysical(start, 20, velocity, this.objects);
|
const projectile = new ProjectilePhysical(start, 20, velocity, this.objects);
|
||||||
this.objects.addObject(projectile);
|
this.objects.addObject(projectile);
|
||||||
|
|
||||||
|
this.timeSinceLastProjectile = 0;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -92,6 +100,10 @@ export class Player extends CommandReceiver {
|
||||||
this.sendObjects();
|
this.sendObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public step(deltaTimeInMilliseconds: number) {
|
||||||
|
this.sendObjects();
|
||||||
|
this.timeSinceLastProjectile += deltaTimeInMilliseconds;
|
||||||
|
}
|
||||||
public sendObjects() {
|
public sendObjects() {
|
||||||
const viewArea = calculateViewArea(this.character.center, this.aspectRatio, 1.5);
|
const viewArea = calculateViewArea(this.character.center, this.aspectRatio, 1.5);
|
||||||
const bb = new BoundingBox();
|
const bb = new BoundingBox();
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ export class TouchListener extends CommandGenerator {
|
||||||
target.addEventListener('touchmove', (event: TouchEvent) => {
|
target.addEventListener('touchmove', (event: TouchEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const position = this.positionFromEvent(event);
|
const position = this.positionFromEvent(event, true);
|
||||||
const movement = vec2.subtract(vec2.create(), position, this.previousPosition);
|
const movement = vec2.subtract(vec2.create(), position, this.previousPosition);
|
||||||
|
|
||||||
if (vec2.squaredLength(movement) > 0) {
|
if (vec2.squaredLength(movement) > 0) {
|
||||||
|
|
@ -50,11 +50,18 @@ export class TouchListener extends CommandGenerator {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private positionFromEvent(event: TouchEvent): vec2 {
|
private positionFromEvent(event: TouchEvent, invert = false): vec2 {
|
||||||
const touches = Array.prototype.slice.call(event.touches);
|
const touches = Array.prototype.slice.call(event.touches);
|
||||||
const center = touches.reduce(
|
const center = touches.reduce(
|
||||||
(center: vec2, touch: Touch) =>
|
(center: vec2, touch: Touch) =>
|
||||||
vec2.add(center, center, vec2.fromValues(-touch.clientX, -touch.clientY)),
|
vec2.add(
|
||||||
|
center,
|
||||||
|
center,
|
||||||
|
vec2.fromValues(
|
||||||
|
touch.clientX * (invert ? -1 : 1),
|
||||||
|
touch.clientY * (invert ? -1 : 1),
|
||||||
|
),
|
||||||
|
),
|
||||||
vec2.create(),
|
vec2.create(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ export class Game {
|
||||||
{
|
{
|
||||||
shadowTraceCount: 16,
|
shadowTraceCount: 16,
|
||||||
paletteSize: 10,
|
paletteSize: 10,
|
||||||
enableStopwatch: true,
|
//enableStopwatch: true,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -112,7 +112,7 @@ export class Game {
|
||||||
colorPalette: [
|
colorPalette: [
|
||||||
rgb(1, 1, 1),
|
rgb(1, 1, 1),
|
||||||
rgb(0.4, 0.4, 0.4),
|
rgb(0.4, 0.4, 0.4),
|
||||||
rgb(0.3, 1, 1),
|
rgb(1, 1, 1),
|
||||||
...settings.playerColors,
|
...settings.playerColors,
|
||||||
],
|
],
|
||||||
enableHighDpiRendering: false,
|
enableHighDpiRendering: false,
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,22 @@
|
||||||
import { vec2 } from 'gl-matrix';
|
import { vec2 } from 'gl-matrix';
|
||||||
import { Circle, Renderer } from 'sdf-2d';
|
import { Circle, CircleLight, Renderer } from 'sdf-2d';
|
||||||
import { Id, ProjectileBase } from 'shared';
|
import { Id, ProjectileBase, rgb } from 'shared';
|
||||||
import { ViewObject } from './view-object';
|
import { ViewObject } from './view-object';
|
||||||
|
|
||||||
export class ProjectileView extends ProjectileBase implements ViewObject {
|
export class ProjectileView extends ProjectileBase implements ViewObject {
|
||||||
private circle: Circle;
|
private circle: Circle;
|
||||||
|
private light: CircleLight;
|
||||||
|
|
||||||
constructor(id: Id, center: vec2, radius: number) {
|
constructor(id: Id, center: vec2, radius: number) {
|
||||||
super(id, center, radius);
|
super(id, center, radius);
|
||||||
this.circle = new Circle(center, radius);
|
this.circle = new Circle(center, radius / 2);
|
||||||
|
this.light = new CircleLight(center, rgb(1, 0.5, 0), 0.35);
|
||||||
}
|
}
|
||||||
|
|
||||||
public step(deltaTimeInMilliseconds: number): void {}
|
public step(deltaTimeInMilliseconds: number): void {}
|
||||||
|
|
||||||
public draw(renderer: Renderer): void {
|
public draw(renderer: Renderer): void {
|
||||||
renderer.addDrawable(this.circle);
|
renderer.addDrawable(this.circle);
|
||||||
|
renderer.addDrawable(this.light);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,9 @@ export const settings = {
|
||||||
maxVelocityY: 3650,
|
maxVelocityY: 3650,
|
||||||
polygonEdgeCount: 8,
|
polygonEdgeCount: 8,
|
||||||
projectileSpeed: 2000,
|
projectileSpeed: 2000,
|
||||||
|
projectileMaxBounceCount: 1,
|
||||||
projectileStartOffset: 150,
|
projectileStartOffset: 150,
|
||||||
|
projectileCreationInterval: 500,
|
||||||
playerColorIndexOffset: 3,
|
playerColorIndexOffset: 3,
|
||||||
worldLeftEdge: -5000,
|
worldLeftEdge: -5000,
|
||||||
worldRightEdge: 5000,
|
worldRightEdge: 5000,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue