@gg-web-engine/matter 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,13 @@
1
+ <p align="center">
2
+ <img src="../../documentation/assets/logo.png" style="height: 400px; width:400px;" alt=''/>
3
+ </p>
4
+
5
+ ## [Matter.js](https://github.com/liabru/matter-js) integration for [gg-web-engine](https://github.com/AndyGura/gg-web-engine), providing 2D physics simulation
6
+
7
+ ### Installation:
8
+ 1) make sure **@gg-web-engine/core** installed
9
+ 1) `npm install --save @gg-web-engine/matter`
10
+ 1) Add to your `tsconfig.json` in the record `compilerOptions.paths`:
11
+ ```json lines
12
+ "matter-js": ["./node_modules/@gg-web-engine/matter/node_modules/matter-js"]
13
+ ```
@@ -0,0 +1,13 @@
1
+ import { BodyShape2DDescriptor, IGg2dBodyFactory, Point2, Shape2DDescriptor } from '@gg-web-engine/core';
2
+ import { Gg2dBody } from './gg-2d-body';
3
+ export declare class Gg2dBodyFactory implements IGg2dBodyFactory<Gg2dBody, any> {
4
+ createRigidBody(descriptor: BodyShape2DDescriptor, transform?: {
5
+ position?: Point2;
6
+ rotation?: number;
7
+ }): Gg2dBody;
8
+ createTrigger(descriptor: Shape2DDescriptor, transform?: {
9
+ position?: Point2;
10
+ rotation?: number;
11
+ }): any;
12
+ private transformOptions;
13
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Gg2dBodyFactory = void 0;
4
+ const gg_2d_body_1 = require("./gg-2d-body");
5
+ const matter_js_1 = require("matter-js");
6
+ class Gg2dBodyFactory {
7
+ createRigidBody(descriptor, transform) {
8
+ var _a, _b;
9
+ let nativeBody = null;
10
+ switch (descriptor.shape.shape) {
11
+ case 'SQUARE':
12
+ nativeBody = matter_js_1.Bodies.rectangle(0, 0, descriptor.shape.dimensions.x, descriptor.shape.dimensions.y, this.transformOptions(descriptor.body));
13
+ break;
14
+ case 'CIRCLE':
15
+ nativeBody = matter_js_1.Bodies.circle(0, 0, descriptor.shape.radius, this.transformOptions(descriptor.body));
16
+ break;
17
+ }
18
+ if (!nativeBody) {
19
+ throw new Error(`Shape "${descriptor.shape}" not implemented for Matter.js`);
20
+ }
21
+ nativeBody.position = matter_js_1.Vector.create(((_a = transform === null || transform === void 0 ? void 0 : transform.position) === null || _a === void 0 ? void 0 : _a.x) || 0, ((_b = transform === null || transform === void 0 ? void 0 : transform.position) === null || _b === void 0 ? void 0 : _b.y) || 0);
22
+ nativeBody.angle = (transform === null || transform === void 0 ? void 0 : transform.rotation) || 0;
23
+ return new gg_2d_body_1.Gg2dBody(nativeBody);
24
+ }
25
+ createTrigger(descriptor, transform) {
26
+ throw new Error('Triggers not implemented for Matter.js');
27
+ }
28
+ transformOptions(options) {
29
+ const res = {
30
+ isStatic: options.dynamic !== undefined ? !options.dynamic : !options.mass,
31
+ mass: options.mass,
32
+ restitution: options.restitution,
33
+ friction: options.friction,
34
+ };
35
+ for (const key in res) {
36
+ if (res[key] === undefined) {
37
+ delete res[key];
38
+ }
39
+ }
40
+ return res;
41
+ }
42
+ }
43
+ exports.Gg2dBodyFactory = Gg2dBodyFactory;
@@ -0,0 +1,19 @@
1
+ import { IGg2dBody, Point2, Gg2dEntity } from '@gg-web-engine/core';
2
+ import { Gg2dPhysicsWorld } from './gg-2d-physics-world';
3
+ import { Body } from 'matter-js';
4
+ export declare class Gg2dBody implements IGg2dBody {
5
+ nativeBody: Body;
6
+ get position(): Point2;
7
+ set position(value: Point2);
8
+ get rotation(): number;
9
+ set rotation(value: number);
10
+ get scale(): Point2;
11
+ name: string;
12
+ entity: Gg2dEntity | null;
13
+ constructor(nativeBody: Body);
14
+ clone(): Gg2dBody;
15
+ addToWorld(world: Gg2dPhysicsWorld): void;
16
+ removeFromWorld(world: Gg2dPhysicsWorld): void;
17
+ dispose(): void;
18
+ resetMotion(): void;
19
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Gg2dBody = void 0;
4
+ const matter_js_1 = require("matter-js");
5
+ class Gg2dBody {
6
+ constructor(nativeBody) {
7
+ this.nativeBody = nativeBody;
8
+ this.name = '';
9
+ this.entity = null;
10
+ }
11
+ get position() {
12
+ return this.nativeBody.position;
13
+ }
14
+ set position(value) {
15
+ matter_js_1.Body.translate(this.nativeBody, matter_js_1.Vector.create(value.x, value.y));
16
+ }
17
+ get rotation() {
18
+ return this.nativeBody.angle;
19
+ }
20
+ set rotation(value) {
21
+ this.nativeBody.angle = value;
22
+ }
23
+ get scale() {
24
+ // hmm, is it even possible to be different?
25
+ return { x: 1, y: 1 };
26
+ }
27
+ clone() {
28
+ // TODO
29
+ throw new Error('Gg2dBody.clone() not implemented for Matter.js');
30
+ }
31
+ addToWorld(world) {
32
+ matter_js_1.Composite.add(world.matterWorld, this.nativeBody);
33
+ }
34
+ removeFromWorld(world) {
35
+ matter_js_1.Composite.remove(world.matterWorld, this.nativeBody);
36
+ }
37
+ dispose() { }
38
+ resetMotion() {
39
+ matter_js_1.Body.setVelocity(this.nativeBody, { x: 0, y: 0 });
40
+ matter_js_1.Body.setAngularVelocity(this.nativeBody, 0);
41
+ }
42
+ }
43
+ exports.Gg2dBody = Gg2dBody;
@@ -0,0 +1,20 @@
1
+ import { IGg2dPhysicsWorld, GgDebugPhysicsDrawer, Point2, Gg2dWorld } from '@gg-web-engine/core';
2
+ import { World } from 'matter-js';
3
+ import { Gg2dBodyFactory } from './gg-2d-body-factory';
4
+ export declare class Gg2dPhysicsWorld implements IGg2dPhysicsWorld {
5
+ private matterEngine;
6
+ get matterWorld(): World | null;
7
+ readonly factory: Gg2dBodyFactory;
8
+ private _gravity;
9
+ get gravity(): Point2;
10
+ set gravity(value: Point2);
11
+ private _timeScale;
12
+ get timeScale(): number;
13
+ set timeScale(value: number);
14
+ get physicsDebugViewActive(): boolean;
15
+ init(): Promise<void>;
16
+ simulate(delta: number): void;
17
+ startDebugger(world: Gg2dWorld, drawer: GgDebugPhysicsDrawer<Point2, number>): void;
18
+ stopDebugger(): void;
19
+ dispose(): void;
20
+ }
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.Gg2dPhysicsWorld = void 0;
13
+ const matter_js_1 = require("matter-js");
14
+ const gg_2d_body_factory_1 = require("./gg-2d-body-factory");
15
+ class Gg2dPhysicsWorld {
16
+ constructor() {
17
+ this.matterEngine = null;
18
+ this.factory = new gg_2d_body_factory_1.Gg2dBodyFactory();
19
+ this._gravity = { x: 0, y: 9.82 };
20
+ this._timeScale = 1;
21
+ }
22
+ get matterWorld() {
23
+ return this.matterEngine && this.matterEngine.world;
24
+ }
25
+ get gravity() {
26
+ return this._gravity;
27
+ }
28
+ set gravity(value) {
29
+ this._gravity = value;
30
+ if (this.matterEngine) {
31
+ this.matterEngine.gravity.x = this._gravity.x;
32
+ this.matterEngine.gravity.y = this._gravity.y;
33
+ }
34
+ }
35
+ get timeScale() {
36
+ return this._timeScale;
37
+ }
38
+ set timeScale(value) {
39
+ this._timeScale = value;
40
+ }
41
+ get physicsDebugViewActive() {
42
+ return false;
43
+ }
44
+ init() {
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ this.matterEngine = matter_js_1.Engine.create({ gravity: Object.assign(Object.assign({}, this._gravity), { scale: 0.0001 }) });
47
+ });
48
+ }
49
+ simulate(delta) {
50
+ matter_js_1.Engine.update(this.matterEngine, this._timeScale * delta);
51
+ }
52
+ startDebugger(world, drawer) {
53
+ // TODO
54
+ throw new Error('Matter.js DebugDrawer not implemented');
55
+ }
56
+ stopDebugger() {
57
+ // TODO
58
+ throw new Error('Matter.js DebugDrawer not implemented');
59
+ }
60
+ dispose() {
61
+ matter_js_1.Engine.clear(this.matterEngine);
62
+ }
63
+ }
64
+ exports.Gg2dPhysicsWorld = Gg2dPhysicsWorld;
@@ -0,0 +1,3 @@
1
+ export * from './impl/gg-2d-body';
2
+ export * from './impl/gg-2d-body-factory';
3
+ export * from './impl/gg-2d-physics-world';
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./impl/gg-2d-body"), exports);
18
+ __exportStar(require("./impl/gg-2d-body-factory"), exports);
19
+ __exportStar(require("./impl/gg-2d-physics-world"), exports);
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@gg-web-engine/matter",
3
+ "version": "0.0.01",
4
+ "description": "An attempt to create open source game engine for browser",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "test": "echo \"Error: no test specified\" && exit 1",
9
+ "prettier-format": "prettier --config ../core/.prettierrc 'src/**/*.ts' --write",
10
+ "prepublish": "tsc",
11
+ "build": "tsc"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/AndyGura/gg-web-engine.git"
16
+ },
17
+ "keywords": [
18
+ "game-development",
19
+ "game-engine",
20
+ "game-engine-framework",
21
+ "gamedev"
22
+ ],
23
+ "author": "AndyGura",
24
+ "license": "Apache-2.0",
25
+ "bugs": {
26
+ "url": "https://github.com/AndyGura/gg-web-engine/issues"
27
+ },
28
+ "homepage": "https://github.com/AndyGura/gg-web-engine#readme",
29
+ "dependencies": {
30
+ "@gg-web-engine/core": "^0.0.1",
31
+ "matter-js": "^0.18.0"
32
+ },
33
+ "devDependencies": {
34
+ "@types/matter-js": "^0.18.2",
35
+ "prettier": "^2.8.6",
36
+ "typescript": "~4.7.2"
37
+ }
38
+ }
@@ -0,0 +1,60 @@
1
+ import { Body2DOptions, BodyShape2DDescriptor, IGg2dBodyFactory, Point2, Shape2DDescriptor } from '@gg-web-engine/core';
2
+ import { Gg2dBody } from './gg-2d-body';
3
+ import { Bodies, IBodyDefinition, Vector, Body } from 'matter-js';
4
+
5
+ export class Gg2dBodyFactory implements IGg2dBodyFactory<Gg2dBody, any> {
6
+ createRigidBody(
7
+ descriptor: BodyShape2DDescriptor,
8
+ transform?: {
9
+ position?: Point2;
10
+ rotation?: number;
11
+ },
12
+ ): Gg2dBody {
13
+ let nativeBody: Body | null = null;
14
+ switch (descriptor.shape.shape) {
15
+ case 'SQUARE':
16
+ nativeBody = Bodies.rectangle(
17
+ 0,
18
+ 0,
19
+ descriptor.shape.dimensions.x,
20
+ descriptor.shape.dimensions.y,
21
+ this.transformOptions(descriptor.body),
22
+ );
23
+ break;
24
+ case 'CIRCLE':
25
+ nativeBody = Bodies.circle(0, 0, descriptor.shape.radius, this.transformOptions(descriptor.body));
26
+ break;
27
+ }
28
+ if (!nativeBody) {
29
+ throw new Error(`Shape "${descriptor.shape}" not implemented for Matter.js`);
30
+ }
31
+ nativeBody.position = Vector.create(transform?.position?.x || 0, transform?.position?.y || 0);
32
+ nativeBody.angle = transform?.rotation || 0;
33
+ return new Gg2dBody(nativeBody);
34
+ }
35
+
36
+ createTrigger(
37
+ descriptor: Shape2DDescriptor,
38
+ transform?: {
39
+ position?: Point2;
40
+ rotation?: number;
41
+ },
42
+ ): any {
43
+ throw new Error('Triggers not implemented for Matter.js');
44
+ }
45
+
46
+ private transformOptions(options: Partial<Body2DOptions>): IBodyDefinition {
47
+ const res: IBodyDefinition = {
48
+ isStatic: options.dynamic !== undefined ? !options.dynamic : !options.mass,
49
+ mass: options.mass,
50
+ restitution: options.restitution,
51
+ friction: options.friction,
52
+ };
53
+ for (const key in res) {
54
+ if ((res as any)[key] === undefined) {
55
+ delete (res as any)[key];
56
+ }
57
+ }
58
+ return res;
59
+ }
60
+ }
@@ -0,0 +1,52 @@
1
+ import { IGg2dBody, Point2, Gg2dEntity } from '@gg-web-engine/core';
2
+ import { Gg2dPhysicsWorld } from './gg-2d-physics-world';
3
+ import { Body, Composite, Vector } from 'matter-js';
4
+
5
+ export class Gg2dBody implements IGg2dBody {
6
+ public get position(): Point2 {
7
+ return this.nativeBody.position;
8
+ }
9
+
10
+ public set position(value: Point2) {
11
+ Body.translate(this.nativeBody, Vector.create(value.x, value.y));
12
+ }
13
+
14
+ public get rotation(): number {
15
+ return this.nativeBody.angle;
16
+ }
17
+
18
+ public set rotation(value: number) {
19
+ this.nativeBody.angle = value;
20
+ }
21
+
22
+ public get scale(): Point2 {
23
+ // hmm, is it even possible to be different?
24
+ return { x: 1, y: 1 };
25
+ }
26
+
27
+ public name: string = '';
28
+
29
+ public entity: Gg2dEntity | null = null;
30
+
31
+ constructor(public nativeBody: Body) {}
32
+
33
+ clone(): Gg2dBody {
34
+ // TODO
35
+ throw new Error('Gg2dBody.clone() not implemented for Matter.js');
36
+ }
37
+
38
+ addToWorld(world: Gg2dPhysicsWorld): void {
39
+ Composite.add(world.matterWorld!, this.nativeBody);
40
+ }
41
+
42
+ removeFromWorld(world: Gg2dPhysicsWorld): void {
43
+ Composite.remove(world.matterWorld!, this.nativeBody);
44
+ }
45
+
46
+ dispose(): void {}
47
+
48
+ resetMotion(): void {
49
+ Body.setVelocity(this.nativeBody, { x: 0, y: 0 });
50
+ Body.setAngularVelocity(this.nativeBody, 0);
51
+ }
52
+ }
@@ -0,0 +1,59 @@
1
+ import { IGg2dPhysicsWorld, GgDebugPhysicsDrawer, Point2, Gg2dWorld } from '@gg-web-engine/core';
2
+ import { Engine, World } from 'matter-js';
3
+ import { Gg2dBodyFactory } from './gg-2d-body-factory';
4
+
5
+ export class Gg2dPhysicsWorld implements IGg2dPhysicsWorld {
6
+ private matterEngine: Engine | null = null;
7
+
8
+ public get matterWorld(): World | null {
9
+ return this.matterEngine && this.matterEngine.world;
10
+ }
11
+
12
+ public readonly factory: Gg2dBodyFactory = new Gg2dBodyFactory();
13
+
14
+ private _gravity: Point2 = { x: 0, y: 9.82 };
15
+ public get gravity(): Point2 {
16
+ return this._gravity;
17
+ }
18
+ public set gravity(value: Point2) {
19
+ this._gravity = value;
20
+ if (this.matterEngine) {
21
+ this.matterEngine.gravity.x = this._gravity.x;
22
+ this.matterEngine.gravity.y = this._gravity.y;
23
+ }
24
+ }
25
+
26
+ private _timeScale: number = 1;
27
+ public get timeScale(): number {
28
+ return this._timeScale;
29
+ }
30
+ public set timeScale(value: number) {
31
+ this._timeScale = value;
32
+ }
33
+
34
+ public get physicsDebugViewActive(): boolean {
35
+ return false;
36
+ }
37
+
38
+ async init(): Promise<void> {
39
+ this.matterEngine = Engine.create({ gravity: { ...this._gravity, scale: 0.0001 } });
40
+ }
41
+
42
+ simulate(delta: number): void {
43
+ Engine.update(this.matterEngine!, this._timeScale * delta);
44
+ }
45
+
46
+ startDebugger(world: Gg2dWorld, drawer: GgDebugPhysicsDrawer<Point2, number>): void {
47
+ // TODO
48
+ throw new Error('Matter.js DebugDrawer not implemented');
49
+ }
50
+
51
+ stopDebugger(): void {
52
+ // TODO
53
+ throw new Error('Matter.js DebugDrawer not implemented');
54
+ }
55
+
56
+ dispose(): void {
57
+ Engine.clear(this.matterEngine!);
58
+ }
59
+ }
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './impl/gg-2d-body';
2
+ export * from './impl/gg-2d-body-factory';
3
+ export * from './impl/gg-2d-physics-world';
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "./../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "baseUrl": "./src/",
5
+ "outDir": "./dist/",
6
+ "paths": {
7
+ "mini-signals": ["./node_modules/mini-signals/index.js"],
8
+ "path": ["./node_modules/path-browserify"],
9
+ "fs": ["./node_modules/fs-web"]
10
+ }
11
+ },
12
+ "include": ["*.ts", "**/*.ts"],
13
+ }