@gg-web-engine/rapier2d 0.0.30 → 0.0.37

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.
@@ -33,7 +33,7 @@ export class Rapier2dTriggerComponent extends Rapier2dRigidBodyComponent {
33
33
  else if (h2 === ((_b = this.nativeBody) === null || _b === void 0 ? void 0 : _b.handle)) {
34
34
  otherBody = this.world.handleIdEntityMap.get(h1);
35
35
  }
36
- if (!otherBody || !otherBody.entity)
36
+ if (!otherBody)
37
37
  return;
38
38
  (started ? this.onEnter$ : this.onLeft$).next(otherBody);
39
39
  });
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@gg-web-engine/rapier2d",
3
- "version": "0.0.30",
3
+ "version": "0.0.37",
4
4
  "description": "An attempt to create open source game engine for browser",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
8
- "test": "echo \"Error: no test specified\" && exit 1",
8
+ "test": "jest",
9
9
  "prettier-format": "prettier --config ../core/.prettierrc 'src/**/*.ts' --write",
10
10
  "prepublish": "rm -rf ./dist/ && tsc",
11
11
  "build": "tsc"
@@ -28,14 +28,40 @@
28
28
  "homepage": "https://github.com/AndyGura/gg-web-engine#readme",
29
29
  "devDependencies": {
30
30
  "@dimforge/rapier2d-compat": "0.0.0-c23a138-20231001",
31
- "@gg-web-engine/core": "0.0.30",
31
+ "@gg-web-engine/core": "0.0.37",
32
+ "@types/jest": "^29.5.0",
33
+ "jest": "^29.5.0",
34
+ "jest-environment-jsdom": "^29.5.0",
32
35
  "prettier": "^2.8.6",
33
36
  "rxjs": "7.8.0",
37
+ "ts-jest": "^29.0.5",
34
38
  "typescript": "~4.7.2"
35
39
  },
36
40
  "peerDependencies": {
37
41
  "@dimforge/rapier2d-compat": "0.0.0-c23a138-20231001",
38
- "@gg-web-engine/core": "0.0.30",
42
+ "@gg-web-engine/core": "0.0.37",
39
43
  "rxjs": "7.8.0"
44
+ },
45
+ "jest": {
46
+ "rootDir": ".",
47
+ "testRegex": "\\.spec\\.ts$",
48
+ "transform": {
49
+ "^.+\\.(t|j)s$": "ts-jest"
50
+ },
51
+ "moduleNameMapper": {
52
+ "@gg-web-engine/core": "<rootDir>/../core/src/index.ts"
53
+ },
54
+ "preset": "ts-jest/presets/default",
55
+ "collectCoverageFrom": [
56
+ "**/*.ts",
57
+ "!**/*.module.ts"
58
+ ],
59
+ "coveragePathIgnorePatterns": [
60
+ "<rootDir>/node_modules/",
61
+ "<rootDir>/dist/",
62
+ "<rootDir>/test/"
63
+ ],
64
+ "coverageDirectory": "./coverage",
65
+ "testEnvironment": "jsdom"
40
66
  }
41
67
  }
@@ -0,0 +1,124 @@
1
+ import { Rapier2dFactory, Rapier2dWorldComponent } from '../../src';
2
+ import { Pnt2 } from '@gg-web-engine/core';
3
+
4
+ describe(`Rapier2dTriggerComponent`, () => {
5
+
6
+ let world: Rapier2dWorldComponent;
7
+ let factory: Rapier2dFactory;
8
+ beforeEach(async () => {
9
+ if (world) {
10
+ world.dispose();
11
+ }
12
+ world = new Rapier2dWorldComponent();
13
+ factory = new Rapier2dFactory(world);
14
+ await world.init();
15
+ world.gravity = Pnt2.O;
16
+ });
17
+
18
+ afterAll(() => {
19
+ world.dispose();
20
+ });
21
+
22
+ it(`should detect object intersection`, async () => {
23
+ const trigger = factory.createTrigger({ shape: 'SQUARE', dimensions: { x: 10, y: 10 } });
24
+ trigger.addToWorld({ physicsWorld: world } as any);
25
+ const ball = factory.createRigidBody({
26
+ shape: { shape: 'CIRCLE', radius: 1 },
27
+ body: { dynamic: true, mass: 1 },
28
+ }, { position: { x: 0, y: 12 } });
29
+ ball.addToWorld({ physicsWorld: world } as any);
30
+ ball.linearVelocity = { x: 0, y: -10 };
31
+ let enterRegistered = false;
32
+ let exitRegistered = false;
33
+ trigger.onEntityEntered.subscribe(((obj) => {
34
+ enterRegistered = obj === ball;
35
+ }));
36
+ trigger.onEntityLeft.subscribe(((obj) => {
37
+ exitRegistered = obj === ball;
38
+ }));
39
+ world.simulate(500);
40
+ trigger.checkOverlaps(); // trigger entity performs that on tick
41
+ expect(enterRegistered).toBe(false);
42
+ expect(exitRegistered).toBe(false);
43
+
44
+ world.simulate(500);
45
+ trigger.checkOverlaps();
46
+ expect(enterRegistered).toBe(true);
47
+ expect(exitRegistered).toBe(false);
48
+ });
49
+
50
+ it(`should detect end of object intersection`, async () => {
51
+ const trigger = factory.createTrigger({ shape: 'SQUARE', dimensions: { x: 10, y: 10 } });
52
+ trigger.addToWorld({ physicsWorld: world } as any);
53
+ const ball = factory.createRigidBody({
54
+ shape: { shape: 'CIRCLE', radius: 1 },
55
+ body: { dynamic: true, mass: 1 },
56
+ }, { position: { x: 0, y: 12 } });
57
+ ball.addToWorld({ physicsWorld: world } as any);
58
+ ball.linearVelocity = { x: 0, y: -10 };
59
+ let exitRegistered = false;
60
+ trigger.onEntityLeft.subscribe(((obj) => {
61
+ exitRegistered = obj === ball;
62
+ }));
63
+ world.simulate(1000);
64
+ trigger.checkOverlaps();
65
+ expect(exitRegistered).toBe(false);
66
+ world.simulate(1000);
67
+ trigger.checkOverlaps();
68
+ expect(exitRegistered).toBe(true);
69
+ });
70
+
71
+ it(`should fire object intersection if spawned inside`, async () => {
72
+ const trigger = factory.createTrigger({ shape: 'SQUARE', dimensions: { x: 10, y: 10 } });
73
+ trigger.addToWorld({ physicsWorld: world } as any);
74
+ const ball = factory.createRigidBody({
75
+ shape: { shape: 'CIRCLE', radius: 1 },
76
+ body: { dynamic: true, mass: 1 },
77
+ }, { position: { x: 0, y: 0 } });
78
+ ball.addToWorld({ physicsWorld: world } as any);
79
+ let enterRegistered = false;
80
+ trigger.onEntityEntered.subscribe(((obj) => {
81
+ enterRegistered = obj === ball;
82
+ }));
83
+ world.simulate(1000);
84
+ trigger.checkOverlaps();
85
+ expect(enterRegistered).toBe(true);
86
+ });
87
+
88
+ // TODO implement functionality below
89
+ // it(`should fire end of object intersection if trigger removed`, async () => {
90
+ // const trigger = factory.createTrigger({ shape: 'SQUARE', dimensions: { x: 10, y: 10 } });
91
+ // trigger.addToWorld({ physicsWorld: world } as any);
92
+ // const ball = factory.createRigidBody({
93
+ // shape: { shape: 'CIRCLE', radius: 1 },
94
+ // body: { dynamic: true, mass: 1 },
95
+ // }, { position: { x: 0, y: 0 } });
96
+ // ball.addToWorld({ physicsWorld: world } as any);
97
+ // let exitRegistered = false;
98
+ // trigger.onEntityLeft.subscribe(((obj) => {
99
+ // exitRegistered = obj === ball;
100
+ // }));
101
+ // world.simulate(1000);
102
+ // trigger.checkOverlaps();
103
+ // trigger.removeFromWorld({ physicsWorld: world } as any);
104
+ // expect(exitRegistered).toBe(true);
105
+ // });
106
+ //
107
+ // it(`should fire end of object intersection if object removed`, async () => {
108
+ // const trigger = factory.createTrigger({ shape: 'SQUARE', dimensions: { x: 10, y: 10 } });
109
+ // trigger.addToWorld({ physicsWorld: world } as any);
110
+ // const ball = factory.createRigidBody({
111
+ // shape: { shape: 'CIRCLE', radius: 1 },
112
+ // body: { dynamic: true, mass: 1 },
113
+ // }, { position: { x: 0, y: 0 } });
114
+ // ball.addToWorld({ physicsWorld: world } as any);
115
+ // let exitRegistered = false;
116
+ // trigger.onEntityLeft.subscribe(((obj) => {
117
+ // exitRegistered = obj === ball;
118
+ // }));
119
+ // world.simulate(1000);
120
+ // trigger.checkOverlaps();
121
+ // ball.removeFromWorld({ physicsWorld: world } as any);
122
+ // expect(exitRegistered).toBe(true);
123
+ // });
124
+ });