Skip to content

Commit

Permalink
feat: Use pixijs to render objects
Browse files Browse the repository at this point in the history
  • Loading branch information
NriotHrreion committed Sep 17, 2024
1 parent c484a83 commit a3c656a
Show file tree
Hide file tree
Showing 10 changed files with 236 additions and 147 deletions.
67 changes: 66 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"dependencies": {
"jsx-dom": "^8.1.5",
"jsx-dom-cjs": "^8.1.5",
"lucide": "^0.433.0"
"lucide": "^0.433.0",
"pixi.js": "^8.4.0"
}
}
2 changes: 1 addition & 1 deletion src/common/utils/linkedNodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class LinkedNodes<E> {
private _last: Node<E> = Node.Undefined;
private _size: number = 0;

private constructor() { }
protected constructor() { }

public static empty<E = any>(): LinkedNodes<E> {
return new LinkedNodes<E>();
Expand Down
62 changes: 60 additions & 2 deletions src/simulator/object.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,65 @@
import type { Renderable } from "./render/render";

import * as PIXI from "pixi.js";

import { Disposable } from "@/common/lifecycle";

export class CanvasObject extends Disposable {
public constructor() {
import { colors } from "./render/colors";
import { Vector, VectorCollection } from "./vector";

interface ICanvasObject extends Renderable {
mass: number
velocity: Vector

applyForce(force: Vector): void
clearForces(): void
}

export class CanvasObject extends Disposable implements ICanvasObject {
private _forces: VectorCollection = new VectorCollection();

public constructor(
protected _obj: PIXI.ContainerChild,
public mass: number,
public velocity: Vector
) {
super();
}

public applyForce(force: Vector) {
this._forces.push(force);
}

public clearForces() {
this._forces.clear();
}

public update(delta: number, app: PIXI.Application) {
const sumForce = this._forces.getSum();
const accelerate = Vector.multiplyScalar(sumForce, 1 / this.mass);

this.velocity = Vector.add(this.velocity, accelerate);
this._obj.x += this.velocity.x * delta;
this._obj.y -= this.velocity.y * delta;

app.stage.addChild(this._obj);
}
}

export class Ball extends CanvasObject {
public constructor() {
super(
new PIXI.Graphics()
.arc(100, 100, 15, 0, 2 * Math.PI)
.fill(colors["black"]),
1,
new Vector(0, 0)
);

this.applyForce(new Vector(0, -2));
}

public update(delta: number, app: PIXI.Application) {
super.update(delta, app);
}
}
8 changes: 4 additions & 4 deletions src/simulator/render/colors.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export type Color = string;
export type Color = number;

export const colors = {
"transparent": "",
"black": "#222",
"skyBlue": "#7dd3fc",
"transparent": NaN,
"black": 0x222222,
"skyBlue": 0x7dd3fc,
} as Record<string, Color>;
58 changes: 34 additions & 24 deletions src/simulator/render/render.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,44 @@
import type { Canvas } from "@/ui/canvas/canvas";

import * as PIXI from "pixi.js";

import { Disposable, type IDisposable } from "@/common/lifecycle";
import { LinkedNodes } from "@/common/utils/linkedNodes";
import { Ball, type CanvasObject } from "@/simulator/object";

import { colors } from "./colors";

interface IRender extends IDisposable {
export interface Renderable {
update(delta: number, app: PIXI.Application): void
}

interface IRender extends Renderable, IDisposable {
refresh(): void
update(delta: number): void
}

export class Render extends Disposable implements IRender {
private _ctx: CanvasRenderingContext2D;
private _timer: number;
private _app: PIXI.Application;
private _objects: LinkedNodes<CanvasObject> = LinkedNodes.empty();

public constructor(private _canvas: Canvas) {
super();

this._ctx = this._canvas.ctx;
this._initTimer();
}

private _initTimer() {
let start: number;
this._register(this._canvas.onLoad((app: PIXI.Application) => {
this._app = app;

const render = (current: number) => {
if(!start) start = current;

this.update(current - start);
start = current;
this._init();
this._initTimer();
}));
}

this._timer = window.requestAnimationFrame(render);
};
private _init() {
this._objects.push(new Ball());
}

this._timer = window.requestAnimationFrame(render);
private _initTimer() {
this._app.ticker.add((ticker) => {
this.update(ticker.deltaTime);
});
}

/** @todo */
Expand All @@ -41,16 +47,20 @@ export class Render extends Disposable implements IRender {
}

public update(delta: number) {
this._canvas.clear();

// To solve the blurring issue of canvas
this._ctx.translate(.5, .5);
// console.log(delta);
this._app.stage.removeChildren();

// Fake ground
const ground = new PIXI.Graphics().rect(0, this._app.canvas.height - 50, this._app.screen.width, 50).fill(colors["black"]);
this._app.stage.addChild(ground);

this._canvas.drawFilledRect(0, this._canvas.height - 50, this._canvas.width, 50, colors["black"]);
for(const object of this._objects) {
object.update(delta, this._app);
}
}

public override dispose() {
window.cancelAnimationFrame(this._timer);
this._app.ticker.stop();

super.dispose();
}
Expand Down
40 changes: 22 additions & 18 deletions src/simulator/vector.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { LinkedNodes } from "@/common/utils/linkedNodes"

interface IVector {
x: number
y: number

add(vector: IVector): void
sub(vector: IVector): void
multiplyScalar(scalar: number): void
multiply(vector: IVector): number
get length(): number
}
Expand All @@ -14,21 +13,6 @@ export class Vector implements IVector {

public constructor(public x: number, public y: number) { }

public add(vector: Vector) {
this.x += vector.x;
this.y += vector.y;
}

public sub(vector: Vector) {
this.x -= vector.x;
this.y -= vector.y;
}

public multiplyScalar(scalar: number) {
this.x *= scalar;
this.y *= scalar;
}

public multiply(vector: Vector): number {
return Vector.multiply(this, vector);
}
Expand All @@ -49,7 +33,27 @@ export class Vector implements IVector {
return vector1.x * vector2.x + vector1.y * vector2.y;
}

public static multiplyScalar(vector: Vector, scalar: number): Vector {
return new Vector(vector.x * scalar, vector.y * scalar);
}

public static createUnitVector(angle: number): Vector {
return new Vector(Math.cos(angle), Math.sin(angle));
}
}

export class VectorCollection extends LinkedNodes<Vector> {
public constructor() {
super();
}

public getSum(): Vector {
let sum = Vector.Zero;

for(const vector of this) {
sum = Vector.add(sum, vector);
}

return sum;
}
}
Loading

0 comments on commit a3c656a

Please sign in to comment.