Fix physics

This commit is contained in:
schmelczerandras 2020-10-12 20:49:17 +02:00
parent 37954e2ef1
commit f9f6825776
51 changed files with 832 additions and 541 deletions

View file

@ -1,29 +1,38 @@
import { vec2 } from 'gl-matrix';
import { calculateViewArea, CommandExecutors, GameObject } from 'shared';
import { RenderCommand } from '../commands/types/render';
import { Game } from '../game';
import { Renderer } from 'sdf-2d';
import { calculateViewArea, GameObject, mixRgb, settings } from 'shared';
export class Camera extends GameObject {
import { Game } from '../game';
import { ViewObject } from './view-object';
export class Camera extends GameObject implements ViewObject {
public center: vec2 = vec2.create();
private aspectRatio?: number;
protected commandExecutors: CommandExecutors = {
[RenderCommand.type]: this.draw.bind(this),
};
constructor(private game: Game) {
super(null);
}
private draw(c: RenderCommand) {
const canvasAspectRatio = c.renderer.canvasSize.x / c.renderer.canvasSize.y;
public step(deltaTimeInMilliseconds: number): void {}
public draw(renderer: Renderer) {
const canvasAspectRatio = renderer.canvasSize.x / renderer.canvasSize.y;
if (canvasAspectRatio !== this.aspectRatio) {
this.aspectRatio = canvasAspectRatio;
this.game.aspectRatioChanged(canvasAspectRatio);
}
const viewArea = calculateViewArea(this.center, canvasAspectRatio);
c.renderer.setViewArea(viewArea.topLeft, viewArea.size);
renderer.setViewArea(viewArea.topLeft, viewArea.size);
renderer.setRuntimeSettings({
backgroundColor: mixRgb(
settings.backgroundGradient[0],
settings.backgroundGradient[1],
(this.center.x - settings.worldLeftEdge) /
(Math.abs(settings.worldLeftEdge) + Math.abs(settings.worldRightEdge)),
),
});
}
}

View file

@ -1,19 +1,32 @@
import { vec2 } from 'gl-matrix';
import { CharacterBase, CommandExecutors } from 'shared';
import { RenderCommand } from '../commands/types/render';
import { Renderer } from 'sdf-2d';
import { CharacterBase, Circle, Id } from 'shared';
import { BlobShape } from '../shapes/blob-shape';
import { ViewObject } from './view-object';
export class CharacterView extends CharacterBase {
private shape = new BlobShape();
export class CharacterView extends CharacterBase implements ViewObject {
private shape: BlobShape;
protected commandExecutors: CommandExecutors = {
[RenderCommand.type]: (c: RenderCommand) => {
this.shape.setCircles([this.head, this.leftFoot, this.rightFoot]);
c.renderer.addDrawable(this.shape);
},
};
constructor(
id: Id,
colorIndex: number,
head?: Circle,
leftFoot?: Circle,
rightFoot?: Circle,
) {
super(id, colorIndex, head, leftFoot, rightFoot);
this.shape = new BlobShape(colorIndex);
}
public get position(): vec2 {
return this.head.center;
return this.head!.center;
}
public step(deltaTimeInMilliseconds: number): void {}
public draw(renderer: Renderer): void {
this.shape.setCircles([this.head!, this.leftFoot!, this.rightFoot!]);
renderer.addDrawable(this.shape);
}
}

View file

@ -1,23 +1,22 @@
import { Renderer } from 'sdf-2d';
import {
Command,
CommandExecutors,
CommandReceiver,
CreateObjectsCommand,
CreatePlayerCommand,
DeleteObjectsCommand,
GameObject,
Id,
StepCommand,
UpdateObjectsCommand,
} from 'shared';
import { Game } from '../game';
import { Camera } from './camera';
import { CharacterView } from './character-view';
import { ViewObject } from './view-object';
export class GameObjectContainer extends CommandReceiver {
protected objects: Map<Id, GameObject> = new Map();
public player: CharacterView;
public camera: Camera;
protected objects: Map<Id, ViewObject> = new Map();
public player!: CharacterView;
public camera!: Camera;
protected commandExecutors: CommandExecutors = {
[CreatePlayerCommand.type]: (c: CreatePlayerCommand) => {
@ -27,14 +26,8 @@ export class GameObjectContainer extends CommandReceiver {
this.addObject(this.camera);
},
[StepCommand.type]: (_: StepCommand) => {
if (this.player) {
this.camera.center = this.player.position;
}
},
[CreateObjectsCommand.type]: (c: CreateObjectsCommand) =>
c.objects.forEach((o) => this.addObject(o)),
c.objects.forEach((o) => this.addObject(o as ViewObject)),
[DeleteObjectsCommand.type]: (c: DeleteObjectsCommand) =>
c.ids.forEach((id: Id) => this.objects.delete(id)),
@ -42,7 +35,7 @@ export class GameObjectContainer extends CommandReceiver {
[UpdateObjectsCommand.type]: (c: UpdateObjectsCommand) => {
c.objects.forEach((o) => {
this.objects.delete(o.id);
this.addObject(o);
this.addObject(o as ViewObject);
if (o.id === this.player.id) {
this.player = o as CharacterView;
}
@ -54,15 +47,19 @@ export class GameObjectContainer extends CommandReceiver {
super();
}
protected defaultCommandExecutor(c: Command) {
this.objects.forEach((o) => o.sendCommand(c));
public stepObjects(delta: number) {
if (this.player) {
this.camera.center = this.player.position;
}
this.objects.forEach((o) => o.step(delta));
}
public sendCommandToSingleObject(id: Id, e: Command) {
this.objects.get(id)!.sendCommand(e);
public drawObjects(renderer: Renderer) {
this.objects.forEach((o) => o.draw(renderer));
}
private addObject(object: GameObject) {
private addObject(object: ViewObject) {
this.objects.set(object.id, object);
}
}

View file

@ -1,17 +1,24 @@
import { vec2, vec3 } from 'gl-matrix';
import { CircleLight } from 'sdf-2d';
import { CircleLight, Renderer } from 'sdf-2d';
import { CommandExecutors, Id, LampBase } from 'shared';
import { RenderCommand } from '../commands/types/render';
import { ViewObject } from './view-object';
export class LampView extends LampBase {
export class LampView extends LampBase implements ViewObject {
private light: CircleLight;
protected commandExecutors: CommandExecutors = {
[RenderCommand.type]: (c: RenderCommand) => c.renderer.addDrawable(this.light),
} as any;
};
constructor(id: Id, center: vec2, color: vec3, lightness: number) {
super(id, center, color, lightness);
this.light = new CircleLight(center, color, lightness);
}
public step(deltaTimeInMilliseconds: number): void {}
public draw(renderer: Renderer): void {
renderer.addDrawable(this.light);
}
}

View file

@ -0,0 +1,19 @@
import { vec2 } from 'gl-matrix';
import { Circle, Renderer } from 'sdf-2d';
import { Id, ProjectileBase } from 'shared';
import { ViewObject } from './view-object';
export class ProjectileView extends ProjectileBase implements ViewObject {
private circle: Circle;
constructor(id: Id, center: vec2, radius: number) {
super(id, center, radius);
this.circle = new Circle(center, radius);
}
public step(deltaTimeInMilliseconds: number): void {}
public draw(renderer: Renderer): void {
renderer.addDrawable(this.circle);
}
}

View file

@ -0,0 +1,25 @@
import { vec2 } from 'gl-matrix';
import { Drawable, Renderer } from 'sdf-2d';
import { CommandExecutors, Id, StoneBase } from 'shared';
import { RenderCommand } from '../commands/types/render';
import { Polygon } from '../shapes/polygon';
import { ViewObject } from './view-object';
export class StoneView extends StoneBase implements ViewObject {
private shape: Drawable;
protected commandExecutors: CommandExecutors = {
[RenderCommand.type]: (c: RenderCommand) => c.renderer.addDrawable(this.shape),
};
constructor(id: Id, vertices: Array<vec2>) {
super(id, vertices);
this.shape = new Polygon(vertices);
}
public step(deltaTimeInMilliseconds: number): void {}
public draw(renderer: Renderer): void {
renderer.addDrawable(this.shape);
}
}

View file

@ -1,17 +0,0 @@
import { vec2 } from 'gl-matrix';
import { InvertedTunnel } from 'sdf-2d';
import { CommandExecutors, Id, TunnelBase } from 'shared';
import { RenderCommand } from '../commands/types/render';
export class TunnelView extends TunnelBase {
private shape: InvertedTunnel;
protected commandExecutors: CommandExecutors = {
[RenderCommand.type]: (c: RenderCommand) => c.renderer.addDrawable(this.shape),
} as any;
constructor(id: Id, from: vec2, to: vec2, fromRadius: number, toRadius: number) {
super(id, from, to, fromRadius, toRadius);
this.shape = new InvertedTunnel(from, to, fromRadius, toRadius);
}
}

View file

@ -0,0 +1,7 @@
import { Renderer } from 'sdf-2d';
import { GameObject } from 'shared';
export interface ViewObject extends GameObject {
step(deltaTimeInMilliseconds: number): void;
draw(renderer: Renderer): void;
}