Add basic gameobject system

This commit is contained in:
schmelczerandras 2020-07-19 13:50:03 +02:00
parent d5be727040
commit efb01476b2
33 changed files with 399 additions and 171 deletions

View file

@ -1,7 +1,38 @@
import { Typed } from '../transport/serializable';
import { Vec2 } from '../math/vec2';
import { IdentityManager } from '../identity/identity-manager';
import { Command } from '../commands/command';
import { CommandReceiver } from '../commands/command-receiver';
export class GameObject extends Typed {
public position = new Vec2();
public boundingBoxSize = new Vec2();
export abstract class GameObject extends Typed implements CommandReceiver {
public readonly id = IdentityManager.generateId();
protected _position = new Vec2();
public get position(): Vec2 {
return this._position;
}
protected _boundingBoxSize = new Vec2();
public get boundingBoxSize(): Vec2 {
return this._boundingBoxSize;
}
private commandExecutors: {
[commandName: string]: (e: Command) => void;
} = {};
protected addCommandExecutor<T extends Command>(
commandType: new () => T,
handler: (command: T) => void
) {
this.commandExecutors[commandType.name] = handler;
}
public sendCommand(command: Command) {
const commandType = command.constructor.name;
if (this.commandExecutors.hasOwnProperty(commandType)) {
this.commandExecutors[commandType](command);
}
}
}

View file

@ -1,8 +1,24 @@
import { GameObject } from './game-object';
import { Camera } from './types/camera';
import { Id } from '../identity/identity';
import { Command } from '../commands/command';
import { CommandReceiver } from '../commands/command-receiver';
export class ObjectContainer {
private objects: Array<GameObject> = [];
export class ObjectContainer implements CommandReceiver {
private objects: Map<Id, GameObject> = new Map();
constructor(public camera: Camera) {}
public addObject(o: GameObject) {
this.objects.set(o.id, o);
}
public removeObject(o: GameObject) {
this.objects.delete(o.id);
}
public sendCommandToSingleObject(id: Id, e: Command) {
this.objects.get(id)?.sendCommand(e);
}
public sendCommand(e: Command) {
this.objects.forEach((o, _) => o.sendCommand(e));
}
}

View file

@ -1,3 +1,23 @@
import { GameObject } from '../game-object';
import { DrawCommand } from '../../commands/types/draw';
import { Vec2 } from '../../math/vec2';
import { MoveToCommand } from '../../commands/types/move-to';
export class Camera extends GameObject {}
export class Camera extends GameObject {
constructor() {
super();
this._boundingBoxSize = new Vec2(1200, 800);
this.addCommandExecutor(DrawCommand, this.draw.bind(this));
this.addCommandExecutor(MoveToCommand, this.moveTo.bind(this));
}
private draw(e: DrawCommand) {
e.drawer.setCameraPosition(this.position);
e.drawer.setViewBoxSize(this.boundingBoxSize);
}
private moveTo(e: MoveToCommand) {
this._position = e.position;
}
}

View file

@ -0,0 +1,53 @@
import { GameObject } from '../game-object';
import { Vec2 } from '../../math/vec2';
import { ObjectContainer } from '../object-container';
import { Camera } from './camera';
import { MoveToCommand } from '../../commands/types/move-to';
import { StepCommand } from '../../commands/types/step';
import { KeyDownCommand } from '../../commands/types/key-down';
import { KeyUpCommand } from '../../commands/types/key-up';
import { SwipeCommand } from '../../commands/types/swipe';
export class Character extends GameObject {
private keysDown: Set<string> = new Set();
private camera = new Camera();
private static speed = 0.5;
constructor(objects: ObjectContainer) {
super();
objects.addObject(this.camera);
this.addCommandExecutor(StepCommand, this.stepHandler.bind(this));
this.addCommandExecutor(KeyDownCommand, (c) => this.keysDown.add(c.key));
this.addCommandExecutor(KeyUpCommand, (c) => this.keysDown.delete(c.key));
this.addCommandExecutor(SwipeCommand, (c) =>
this.setPosition(
this.position.add(c.delta.times(this.camera.boundingBoxSize))
)
);
}
private setPosition(value: Vec2) {
this._position = value;
this.camera.sendCommand(new MoveToCommand(this.position));
}
public stepHandler(c: StepCommand) {
const deltaTime = c.deltaTimeInMiliseconds;
const up = ~~this.keysDown.has('w');
const down = ~~this.keysDown.has('s');
const left = ~~this.keysDown.has('a');
const right = ~~this.keysDown.has('d');
const movementVector = new Vec2(right - left, up - down);
if (movementVector.length > 0) {
this.setPosition(
this.position.add(
movementVector.normalized.scale(Character.speed * deltaTime)
)
);
}
}
}

View file

@ -0,0 +1,22 @@
import { GameObject } from '../game-object';
import { DrawCommand } from '../../commands/types/draw';
export class InfoText extends GameObject {
constructor() {
super();
this.addCommandExecutor(DrawCommand, this.draw.bind(this));
}
private static records: Map<string, string> = new Map();
public static modifyRecord(key: string, value: string) {
InfoText.records.set(key, value);
}
private draw(e: DrawCommand) {
let text = '';
InfoText.records.forEach((v, k) => (text += `${k}\n\t${v}\n`));
e.drawer.drawCornerText(text);
}
}