neural-driving/index.ts

153 lines
2.9 KiB
TypeScript

type Vec2 = [number, number];
type Rad = number;
interface Graphics {
clear(): void;
drawCar(pos: Vec2, angle: Rad): void;
}
class CanvasGraphics implements Graphics {
private canvas = document.querySelector<HTMLCanvasElement>("#canvas")!;
private ctx = this.canvas.getContext("2d")!;
private alpha = 1;
private trans: Vec2 = [100, 350];
public setup() {
this.canvas.width = 500;
this.canvas.height = 500;
}
public clear() {
this.setFill(100, 170, 255);
this.fillRect([0, 0], [this.canvas.width, this.canvas.height]);
// Draw ground
this.setFill(50, 155, 50);
this.fillRect([0, 350], [this.canvas.width, 150]);
}
public drawCar(pos: Vec2, angle: Rad) {
const [x, y] = pos;
this.ctx.save();
this.ctx.translate(...this.trans);
this.ctx.save();
this.ctx.translate(60 + x, 0 + y);
this.ctx.rotate(angle);
// Draw car body
this.setFill(200, 0, 0);
this.fillRect([-20, -40], [80, 21]);
this.fillRect([-20, -20], [100, 20]);
// Draw rear wheel
this.setFill(0, 0, 0);
this.fillCircle([0, 0], 10);
// Draw front wheel
this.fillCircle([60, 0], 10);
this.ctx.restore();
this.ctx.restore();
}
private setFill(red: number, green: number, blue: number): void {
this.ctx.fillStyle = `rgba(${red}, ${green}, ${blue}, ${this.alpha})`;
}
private fillRect(pos: Vec2, size: Vec2): void {
const [x, y] = pos;
const [width, height] = size;
this.ctx.fillRect(x, y, width, height);
}
private fillCircle(pos: Vec2, radius: number) {
const [x, y] = pos;
this.ctx.beginPath();
this.ctx.arc(x, y, radius, 0, Math.PI * 2);
this.ctx.fill();
}
}
interface Entity {
render(graphics: Graphics): void;
update(delta: number): void;
}
class Car implements Entity {
private pos: Vec2 = [0, 0];
private angle: Rad = 0;
private speeder = 1.0;
public render(graphics: Graphics): void {
graphics.drawCar(this.pos, this.angle);
}
public update(delta: number): void {
if (this.angle > Math.PI / -2) {
this.angle += this.speeder * -0.005 * Math.PI;
this.pos[0] += this.speeder * delta * 100;
}
}
public setSpeeder(speeder: number): void {
this.speeder = speeder;
}
public getAngle(): number {
return this.angle;
}
}
class Matrix {
private entities: Entity[] = []
private graphics = new CanvasGraphics();
public setup() {
this.graphics.setup();
}
public start() {
const looped = (before: number) => {
const now = Date.now();
const delta = (now - before) / 1000;
for (const entity of this.entities) {
entity.update(delta);
}
this.graphics.clear();
for (const entity of this.entities) {
entity.render(this.graphics);
}
requestAnimationFrame(() => looped(now));
}
looped(Date.now());
}
public addEntity(entity: Entity) {
this.entities.push(entity);
}
}
function main() {
const matricen = new Matrix();
matricen.setup();
const car = new Car();
matricen.addEntity(car);
matricen.start();
}
main();