rngine 0.7.1 → 0.8.0
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 +1 -1
- package/lib/module/GameMethods.js +2 -2
- package/lib/module/GameMethods.js.map +1 -1
- package/lib/module/GameMethods.nitro.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/GameMethods.d.ts +1 -1
- package/lib/typescript/src/GameMethods.d.ts.map +1 -1
- package/lib/typescript/src/GameMethods.nitro.d.ts +2 -2
- package/lib/typescript/src/GameMethods.nitro.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/nativeTypes.d.ts +16 -0
- package/lib/typescript/src/nativeTypes.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +7 -10
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/nitrogen/generated/shared/c++/Collision.hpp +10 -2
- package/nitrogen/generated/shared/c++/Entity.hpp +10 -2
- package/nitrogen/generated/shared/c++/EntityUpdate.hpp +10 -2
- package/nitrogen/generated/shared/c++/HybridGameMethodsSpec.cpp +1 -1
- package/nitrogen/generated/shared/c++/HybridGameMethodsSpec.hpp +4 -1
- package/nitrogen/generated/shared/c++/World.hpp +91 -0
- package/package.json +1 -1
- package/shared/CollisionUtils.cpp +57 -21
- package/shared/CollisionUtils.hpp +17 -10
- package/shared/GameLoop.cpp +103 -24
- package/shared/GameLoop.hpp +9 -3
- package/shared/GameMethods.cpp +11 -4
- package/shared/GameMethods.hpp +2 -1
- package/src/GameMethods.nitro.ts +8 -2
- package/src/GameMethods.ts +2 -2
- package/src/index.tsx +1 -0
- package/src/nativeTypes.ts +17 -0
- package/src/types.ts +7 -9
- package/android/kls_database.db +0 -0
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { gameMethods } from "./GameMethods.nitro.js";
|
|
4
4
|
/** Sets up the game engine with the given configuration. Call this before anything else. */
|
|
5
5
|
export const configure = ({
|
|
6
|
-
|
|
6
|
+
world,
|
|
7
7
|
screen,
|
|
8
8
|
entities = [],
|
|
9
9
|
systems = [],
|
|
@@ -22,7 +22,7 @@ export const configure = ({
|
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
|
-
gameMethods.
|
|
25
|
+
gameMethods.setWorld(world);
|
|
26
26
|
gameMethods.setScreen(screen);
|
|
27
27
|
gameMethods.setEntities(entities);
|
|
28
28
|
gameMethods.setSystems(nativeSystems);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["gameMethods","configure","
|
|
1
|
+
{"version":3,"names":["gameMethods","configure","world","screen","entities","systems","paused","nativeSystems","system","push","collisions","onTick","e","c","start","Date","now","finish","setWorld","setScreen","setEntities","setSystems","pause","resume","spawn","entityArray","Array","isArray","despawn","id","update","updates","entityUpdateArray"],"sourceRoot":"../../src","sources":["GameMethods.ts"],"mappings":";;AAAA,SAASA,WAAW,QAAQ,wBAAqB;AAIjD;AACA,OAAO,MAAMC,SAAS,GAAGA,CAAC;EACxBC,KAAK;EACLC,MAAM;EACNC,QAAQ,GAAG,EAAE;EACbC,OAAO,GAAG,EAAE;EACZC,MAAM,GAAG;AACH,CAAC,KAAK;EACZ,IAAIC,aAAuB,GAAG,EAAE;EAEhC,KAAK,MAAMC,MAAM,IAAIH,OAAO,EAAE;IAC5BE,aAAa,CAACE,IAAI,CAAC;MACjBL,QAAQ,EAAEI,MAAM,CAACJ,QAAQ;MACzBM,UAAU,EAAEF,MAAM,CAACE,UAAU;MAC7BC,MAAM,EAAEA,CAACC,CAAC,EAAEC,CAAC,KAAK;QAChB,MAAMC,KAAK,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC;QACxBR,MAAM,CAACG,MAAM,CAACC,CAAC,EAAEC,CAAC,CAAC;QACnB,MAAMI,MAAM,GAAGF,IAAI,CAACC,GAAG,CAAC,CAAC;QACzB,OAAOC,MAAM,GAAGH,KAAK;MACvB;IACF,CAAC,CAAC;EACJ;EAEAd,WAAW,CAACkB,QAAQ,CAAChB,KAAK,CAAC;EAC3BF,WAAW,CAACmB,SAAS,CAAChB,MAAM,CAAC;EAC7BH,WAAW,CAACoB,WAAW,CAAChB,QAAQ,CAAC;EACjCJ,WAAW,CAACqB,UAAU,CAACd,aAAa,CAAC;EACrC,IAAID,MAAM,EAAE;IACVN,WAAW,CAACsB,KAAK,CAAC,CAAC;EACrB,CAAC,MAAM;IACLtB,WAAW,CAACuB,MAAM,CAAC,CAAC;EACtB;AACF,CAAC;;AAED;AACA,OAAO,MAAMD,KAAK,GAAGA,CAAA,KAAMtB,WAAW,CAACsB,KAAK,CAAC,CAAC;;AAE9C;AACA,OAAO,MAAMC,MAAM,GAAGA,CAAA,KAAMvB,WAAW,CAACuB,MAAM,CAAC,CAAC;;AAEhD;AACA,OAAO,MAAMC,KAAK,GAAIpB,QAA2B,IAAK;EACpD,MAAMqB,WAAW,GAAGC,KAAK,CAACC,OAAO,CAACvB,QAAQ,CAAC,GAAGA,QAAQ,GAAG,CAACA,QAAQ,CAAC;EACnEJ,WAAW,CAACwB,KAAK,CAACC,WAAW,CAAC;AAChC,CAAC;;AAED;AACA,OAAO,MAAMG,OAAO,GAAIC,EAAU,IAAK7B,WAAW,CAAC4B,OAAO,CAACC,EAAE,CAAC;;AAE9D;AACA,OAAO,MAAMC,MAAM,GAAIC,OAAsC,IAAK;EAChE,MAAMC,iBAAiB,GAAGN,KAAK,CAACC,OAAO,CAACI,OAAO,CAAC,GAAGA,OAAO,GAAG,CAACA,OAAO,CAAC;EACtE/B,WAAW,CAAC8B,MAAM,CAACE,iBAAiB,CAAC;AACvC,CAAC","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NitroModules","gameMethods","createHybridObject"],"sourceRoot":"../../src","sources":["GameMethods.nitro.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"names":["NitroModules","gameMethods","createHybridObject"],"sourceRoot":"../../src","sources":["GameMethods.nitro.ts"],"mappings":";;AAQA,SAASA,YAAY,QAAQ,4BAA4B;AAiBzD,OAAO,MAAMC,WAAW,GACtBD,YAAY,CAACE,kBAAkB,CAAc,aAAa,CAAC","ignoreList":[]}
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["GameEngine"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,UAAU,MAAM,iBAAc;AAErC,cAAc,kBAAe;AAC7B,cAAc,iBAAc;AAC5B,cAAc,YAAS;
|
|
1
|
+
{"version":3,"names":["GameEngine"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,UAAU,MAAM,iBAAc;AAErC,cAAc,kBAAe;AAC7B,cAAc,iBAAc;AAC5B,cAAc,YAAS;AASvB,SAASA,UAAU","ignoreList":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Entity, EntityUpdate } from './nativeTypes';
|
|
2
2
|
import type { Config } from './types';
|
|
3
3
|
/** Sets up the game engine with the given configuration. Call this before anything else. */
|
|
4
|
-
export declare const configure: ({
|
|
4
|
+
export declare const configure: ({ world, screen, entities, systems, paused, }: Config) => void;
|
|
5
5
|
/** Pauses the game loop. Systems will stop running. */
|
|
6
6
|
export declare const pause: () => void;
|
|
7
7
|
/** Resumes the game loop. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GameMethods.d.ts","sourceRoot":"","sources":["../../../src/GameMethods.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAU,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,4FAA4F;AAC5F,eAAO,MAAM,SAAS,GAAI,
|
|
1
|
+
{"version":3,"file":"GameMethods.d.ts","sourceRoot":"","sources":["../../../src/GameMethods.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAU,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,4FAA4F;AAC5F,eAAO,MAAM,SAAS,GAAI,+CAMvB,MAAM,SAyBR,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,KAAK,YAA4B,CAAC;AAE/C,6BAA6B;AAC7B,eAAO,MAAM,MAAM,YAA6B,CAAC;AAEjD,0EAA0E;AAC1E,eAAO,MAAM,KAAK,GAAI,UAAU,MAAM,GAAG,MAAM,EAAE,SAGhD,CAAC;AAEF,qFAAqF;AACrF,eAAO,MAAM,OAAO,GAAI,IAAI,MAAM,SAA4B,CAAC;AAE/D,0EAA0E;AAC1E,eAAO,MAAM,MAAM,GAAI,SAAS,YAAY,GAAG,YAAY,EAAE,SAG5D,CAAC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
-
import type { Entity, EntityUpdate, System, Screen } from './nativeTypes';
|
|
2
|
+
import type { Entity, EntityUpdate, System, Screen, World } from './nativeTypes';
|
|
3
3
|
interface GameMethods extends HybridObject<{
|
|
4
4
|
ios: 'c++';
|
|
5
5
|
android: 'c++';
|
|
6
6
|
}> {
|
|
7
|
-
|
|
7
|
+
setWorld(world: World): void;
|
|
8
8
|
setScreen(screen: Screen): void;
|
|
9
9
|
setEntities(entities: Entity[]): void;
|
|
10
10
|
setSystems(systems: System[]): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GameMethods.nitro.d.ts","sourceRoot":"","sources":["../../../src/GameMethods.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"GameMethods.nitro.d.ts","sourceRoot":"","sources":["../../../src/GameMethods.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EACV,MAAM,EACN,YAAY,EACZ,MAAM,EACN,MAAM,EACN,KAAK,EACN,MAAM,eAAe,CAAC;AAGvB,UAAU,WAAY,SAAQ,YAAY,CAAC;IACzC,GAAG,EAAE,KAAK,CAAC;IACX,OAAO,EAAE,KAAK,CAAC;CAChB,CAAC;IACA,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACtC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACpC,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,IAAI,IAAI,CAAC;IACf,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;CACvC;AAED,eAAO,MAAM,WAAW,aACqC,CAAC"}
|
|
@@ -2,6 +2,6 @@ import GameEngine from './GameEngine';
|
|
|
2
2
|
export * from './GameMethods';
|
|
3
3
|
export * from './GameAssets';
|
|
4
4
|
export * from './types';
|
|
5
|
-
export type { Screen, Entity, CollisionPair, Collision, EntityUpdate, } from './nativeTypes';
|
|
5
|
+
export type { World, Screen, Entity, CollisionPair, Collision, EntityUpdate, } from './nativeTypes';
|
|
6
6
|
export { GameEngine };
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,cAAc,CAAC;AAEtC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,YAAY,EACV,MAAM,EACN,MAAM,EACN,aAAa,EACb,SAAS,EACT,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,cAAc,CAAC;AAEtC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,YAAY,EACV,KAAK,EACL,MAAM,EACN,MAAM,EACN,aAAa,EACb,SAAS,EACT,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -17,6 +17,8 @@ interface Circle {
|
|
|
17
17
|
interface Shaped {
|
|
18
18
|
/** Shape of the entity. */
|
|
19
19
|
shape: Rect | Circle;
|
|
20
|
+
/** Indicates whether the entity is a sensor. Sensors trigger collision events but don't react physically. */
|
|
21
|
+
isSensor?: boolean;
|
|
20
22
|
}
|
|
21
23
|
interface Renderable {
|
|
22
24
|
/** Fill color as a hex string e.g. `'#00ff00'`. */
|
|
@@ -35,6 +37,16 @@ interface Kinematic {
|
|
|
35
37
|
ax?: number;
|
|
36
38
|
/** Vertical acceleration in game units per second squared. */
|
|
37
39
|
ay?: number;
|
|
40
|
+
/** Mass in arbitrary units. */
|
|
41
|
+
mass?: number;
|
|
42
|
+
}
|
|
43
|
+
export interface World {
|
|
44
|
+
/** Number of game logic updates per second. */
|
|
45
|
+
tickRate: number;
|
|
46
|
+
/** Horizontal gravitational acceleration in game units per second squared. */
|
|
47
|
+
gx?: number;
|
|
48
|
+
/** Vertical gravitational acceleration in game units per second squared. */
|
|
49
|
+
gy?: number;
|
|
38
50
|
}
|
|
39
51
|
export interface Screen extends Rect, Renderable {
|
|
40
52
|
}
|
|
@@ -59,6 +71,10 @@ export interface Collision {
|
|
|
59
71
|
b: string;
|
|
60
72
|
/** Penetration depth of the collision. */
|
|
61
73
|
depth: number;
|
|
74
|
+
/** X component of a normalised vector that represents the direction between the bodies providing the minimum separating distance. */
|
|
75
|
+
nx: number;
|
|
76
|
+
/** Y component of a normalised vector that represents the direction between the bodies providing the minimum separating distance. */
|
|
77
|
+
ny: number;
|
|
62
78
|
}
|
|
63
79
|
export interface System {
|
|
64
80
|
/** Entity ids or prefixes this system subscribes to. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nativeTypes.d.ts","sourceRoot":"","sources":["../../../src/nativeTypes.ts"],"names":[],"mappings":"AAAA,UAAU,UAAU;IAClB,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,UAAU,IAAI;IACZ,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,MAAM;IACd,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,MAAM;IACd,2BAA2B;IAC3B,KAAK,EAAE,IAAI,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"nativeTypes.d.ts","sourceRoot":"","sources":["../../../src/nativeTypes.ts"],"names":[],"mappings":"AAAA,UAAU,UAAU;IAClB,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,UAAU,IAAI;IACZ,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,MAAM;IACd,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,MAAM;IACd,2BAA2B;IAC3B,KAAK,EAAE,IAAI,GAAG,MAAM,CAAC;IACrB,6GAA6G;IAC7G,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,UAAU,UAAU;IAClB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,SAAS;IACjB,oDAAoD;IACpD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kDAAkD;IAClD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,gEAAgE;IAChE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,8DAA8D;IAC9D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,KAAK;IACpB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,4EAA4E;IAC5E,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,MAAO,SAAQ,IAAI,EAAE,UAAU;CAAG;AAEnD,MAAM,WAAW,MAAO,SAAQ,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS;IACvE,oFAAoF;IACpF,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,YAAa,SAAQ,OAAO,CAC3C,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAC7C;IACC,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,aAAa;IAC5B,wDAAwD;IACxD,CAAC,EAAE,MAAM,CAAC;IACV,yDAAyD;IACzD,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,SAAS;IACxB,wDAAwD;IACxD,CAAC,EAAE,MAAM,CAAC;IACV,yDAAyD;IACzD,CAAC,EAAE,MAAM,CAAC;IACV,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,qIAAqI;IACrI,EAAE,EAAE,MAAM,CAAC;IACX,qIAAqI;IACrI,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,MAAM;IACrB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,mEAAmE;IACnE,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,MAAM,CAAC;CACjE"}
|
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
import type { System as NativeSystem, Collision, Screen, Entity } from './nativeTypes';
|
|
1
|
+
import type { System as NativeSystem, Collision, Screen, Entity, World } from './nativeTypes';
|
|
2
2
|
export type System = Omit<NativeSystem, 'onTick'> & {
|
|
3
3
|
/** Called every tick with the resolved entities and collisions. */
|
|
4
4
|
onTick: (entities: Entity[], collisions: Collision[]) => void;
|
|
5
5
|
};
|
|
6
6
|
export type Config = {
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
/** Screen dimensions and background
|
|
7
|
+
/** World settings: tick rate and gravity. */
|
|
8
|
+
world: World;
|
|
9
|
+
/** Screen dimensions and background. */
|
|
10
10
|
screen: Screen;
|
|
11
|
-
/**
|
|
11
|
+
/** Entities to spawn when the game starts. */
|
|
12
12
|
entities?: Entity[];
|
|
13
|
-
/**
|
|
14
|
-
* Systems that define the game logic. Each system runs every tick
|
|
15
|
-
* and receives the entities matching its ids.
|
|
16
|
-
*/
|
|
13
|
+
/** Systems that define game logic, each running every tick against its subscribed entities and collisions. */
|
|
17
14
|
systems?: System[];
|
|
18
|
-
/** Whether
|
|
15
|
+
/** Whether the game starts paused. Defaults to true. */
|
|
19
16
|
paused?: boolean;
|
|
20
17
|
};
|
|
21
18
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,IAAI,YAAY,EACtB,SAAS,EACT,MAAM,EACN,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,IAAI,YAAY,EACtB,SAAS,EACT,MAAM,EACN,MAAM,EACN,KAAK,EACN,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,GAAG;IAClD,mEAAmE;IACnE,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;CAC/D,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,6CAA6C;IAC7C,KAAK,EAAE,KAAK,CAAC;IACb,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,8GAA8G;IAC9G,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,wDAAwD;IACxD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC"}
|
|
@@ -42,10 +42,12 @@ namespace margelo::nitro::rngine {
|
|
|
42
42
|
std::string a SWIFT_PRIVATE;
|
|
43
43
|
std::string b SWIFT_PRIVATE;
|
|
44
44
|
double depth SWIFT_PRIVATE;
|
|
45
|
+
double nx SWIFT_PRIVATE;
|
|
46
|
+
double ny SWIFT_PRIVATE;
|
|
45
47
|
|
|
46
48
|
public:
|
|
47
49
|
Collision() = default;
|
|
48
|
-
explicit Collision(std::string a, std::string b, double depth): a(a), b(b), depth(depth) {}
|
|
50
|
+
explicit Collision(std::string a, std::string b, double depth, double nx, double ny): a(a), b(b), depth(depth), nx(nx), ny(ny) {}
|
|
49
51
|
|
|
50
52
|
public:
|
|
51
53
|
friend bool operator==(const Collision& lhs, const Collision& rhs) = default;
|
|
@@ -63,7 +65,9 @@ namespace margelo::nitro {
|
|
|
63
65
|
return margelo::nitro::rngine::Collision(
|
|
64
66
|
JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "a"))),
|
|
65
67
|
JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "b"))),
|
|
66
|
-
JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "depth")))
|
|
68
|
+
JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "depth"))),
|
|
69
|
+
JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "nx"))),
|
|
70
|
+
JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ny")))
|
|
67
71
|
);
|
|
68
72
|
}
|
|
69
73
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::rngine::Collision& arg) {
|
|
@@ -71,6 +75,8 @@ namespace margelo::nitro {
|
|
|
71
75
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "a"), JSIConverter<std::string>::toJSI(runtime, arg.a));
|
|
72
76
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "b"), JSIConverter<std::string>::toJSI(runtime, arg.b));
|
|
73
77
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "depth"), JSIConverter<double>::toJSI(runtime, arg.depth));
|
|
78
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "nx"), JSIConverter<double>::toJSI(runtime, arg.nx));
|
|
79
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "ny"), JSIConverter<double>::toJSI(runtime, arg.ny));
|
|
74
80
|
return obj;
|
|
75
81
|
}
|
|
76
82
|
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
@@ -84,6 +90,8 @@ namespace margelo::nitro {
|
|
|
84
90
|
if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "a")))) return false;
|
|
85
91
|
if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "b")))) return false;
|
|
86
92
|
if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "depth")))) return false;
|
|
93
|
+
if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "nx")))) return false;
|
|
94
|
+
if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ny")))) return false;
|
|
87
95
|
return true;
|
|
88
96
|
}
|
|
89
97
|
};
|
|
@@ -50,6 +50,7 @@ namespace margelo::nitro::rngine {
|
|
|
50
50
|
double px SWIFT_PRIVATE;
|
|
51
51
|
double py SWIFT_PRIVATE;
|
|
52
52
|
std::variant<Rect, Circle> shape SWIFT_PRIVATE;
|
|
53
|
+
std::optional<bool> isSensor SWIFT_PRIVATE;
|
|
53
54
|
std::optional<std::string> color SWIFT_PRIVATE;
|
|
54
55
|
std::optional<double> asset SWIFT_PRIVATE;
|
|
55
56
|
std::optional<double> progress SWIFT_PRIVATE;
|
|
@@ -57,10 +58,11 @@ namespace margelo::nitro::rngine {
|
|
|
57
58
|
std::optional<double> vy SWIFT_PRIVATE;
|
|
58
59
|
std::optional<double> ax SWIFT_PRIVATE;
|
|
59
60
|
std::optional<double> ay SWIFT_PRIVATE;
|
|
61
|
+
std::optional<double> mass SWIFT_PRIVATE;
|
|
60
62
|
|
|
61
63
|
public:
|
|
62
64
|
Entity() = default;
|
|
63
|
-
explicit Entity(std::string id, double px, double py, std::variant<Rect, Circle> shape, std::optional<std::string> color, std::optional<double> asset, std::optional<double> progress, std::optional<double> vx, std::optional<double> vy, std::optional<double> ax, std::optional<double> ay): id(id), px(px), py(py), shape(shape), color(color), asset(asset), progress(progress), vx(vx), vy(vy), ax(ax), ay(ay) {}
|
|
65
|
+
explicit Entity(std::string id, double px, double py, std::variant<Rect, Circle> shape, std::optional<bool> isSensor, std::optional<std::string> color, std::optional<double> asset, std::optional<double> progress, std::optional<double> vx, std::optional<double> vy, std::optional<double> ax, std::optional<double> ay, std::optional<double> mass): id(id), px(px), py(py), shape(shape), isSensor(isSensor), color(color), asset(asset), progress(progress), vx(vx), vy(vy), ax(ax), ay(ay), mass(mass) {}
|
|
64
66
|
|
|
65
67
|
public:
|
|
66
68
|
friend bool operator==(const Entity& lhs, const Entity& rhs) = default;
|
|
@@ -80,13 +82,15 @@ namespace margelo::nitro {
|
|
|
80
82
|
JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "px"))),
|
|
81
83
|
JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "py"))),
|
|
82
84
|
JSIConverter<std::variant<margelo::nitro::rngine::Rect, margelo::nitro::rngine::Circle>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "shape"))),
|
|
85
|
+
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "isSensor"))),
|
|
83
86
|
JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "color"))),
|
|
84
87
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "asset"))),
|
|
85
88
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress"))),
|
|
86
89
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vx"))),
|
|
87
90
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vy"))),
|
|
88
91
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ax"))),
|
|
89
|
-
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ay")))
|
|
92
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ay"))),
|
|
93
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "mass")))
|
|
90
94
|
);
|
|
91
95
|
}
|
|
92
96
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::rngine::Entity& arg) {
|
|
@@ -95,6 +99,7 @@ namespace margelo::nitro {
|
|
|
95
99
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "px"), JSIConverter<double>::toJSI(runtime, arg.px));
|
|
96
100
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "py"), JSIConverter<double>::toJSI(runtime, arg.py));
|
|
97
101
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "shape"), JSIConverter<std::variant<margelo::nitro::rngine::Rect, margelo::nitro::rngine::Circle>>::toJSI(runtime, arg.shape));
|
|
102
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "isSensor"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.isSensor));
|
|
98
103
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "color"), JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.color));
|
|
99
104
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "asset"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.asset));
|
|
100
105
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "progress"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.progress));
|
|
@@ -102,6 +107,7 @@ namespace margelo::nitro {
|
|
|
102
107
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "vy"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.vy));
|
|
103
108
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "ax"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.ax));
|
|
104
109
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "ay"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.ay));
|
|
110
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "mass"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.mass));
|
|
105
111
|
return obj;
|
|
106
112
|
}
|
|
107
113
|
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
@@ -116,6 +122,7 @@ namespace margelo::nitro {
|
|
|
116
122
|
if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "px")))) return false;
|
|
117
123
|
if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "py")))) return false;
|
|
118
124
|
if (!JSIConverter<std::variant<margelo::nitro::rngine::Rect, margelo::nitro::rngine::Circle>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "shape")))) return false;
|
|
125
|
+
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "isSensor")))) return false;
|
|
119
126
|
if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "color")))) return false;
|
|
120
127
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "asset")))) return false;
|
|
121
128
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress")))) return false;
|
|
@@ -123,6 +130,7 @@ namespace margelo::nitro {
|
|
|
123
130
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vy")))) return false;
|
|
124
131
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ax")))) return false;
|
|
125
132
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ay")))) return false;
|
|
133
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "mass")))) return false;
|
|
126
134
|
return true;
|
|
127
135
|
}
|
|
128
136
|
};
|
|
@@ -50,6 +50,7 @@ namespace margelo::nitro::rngine {
|
|
|
50
50
|
std::optional<double> px SWIFT_PRIVATE;
|
|
51
51
|
std::optional<double> py SWIFT_PRIVATE;
|
|
52
52
|
std::optional<std::variant<Rect, Circle>> shape SWIFT_PRIVATE;
|
|
53
|
+
std::optional<bool> isSensor SWIFT_PRIVATE;
|
|
53
54
|
std::optional<std::string> color SWIFT_PRIVATE;
|
|
54
55
|
std::optional<double> asset SWIFT_PRIVATE;
|
|
55
56
|
std::optional<double> progress SWIFT_PRIVATE;
|
|
@@ -57,10 +58,11 @@ namespace margelo::nitro::rngine {
|
|
|
57
58
|
std::optional<double> vy SWIFT_PRIVATE;
|
|
58
59
|
std::optional<double> ax SWIFT_PRIVATE;
|
|
59
60
|
std::optional<double> ay SWIFT_PRIVATE;
|
|
61
|
+
std::optional<double> mass SWIFT_PRIVATE;
|
|
60
62
|
|
|
61
63
|
public:
|
|
62
64
|
EntityUpdate() = default;
|
|
63
|
-
explicit EntityUpdate(std::string id, std::optional<double> px, std::optional<double> py, std::optional<std::variant<Rect, Circle>> shape, std::optional<std::string> color, std::optional<double> asset, std::optional<double> progress, std::optional<double> vx, std::optional<double> vy, std::optional<double> ax, std::optional<double> ay): id(id), px(px), py(py), shape(shape), color(color), asset(asset), progress(progress), vx(vx), vy(vy), ax(ax), ay(ay) {}
|
|
65
|
+
explicit EntityUpdate(std::string id, std::optional<double> px, std::optional<double> py, std::optional<std::variant<Rect, Circle>> shape, std::optional<bool> isSensor, std::optional<std::string> color, std::optional<double> asset, std::optional<double> progress, std::optional<double> vx, std::optional<double> vy, std::optional<double> ax, std::optional<double> ay, std::optional<double> mass): id(id), px(px), py(py), shape(shape), isSensor(isSensor), color(color), asset(asset), progress(progress), vx(vx), vy(vy), ax(ax), ay(ay), mass(mass) {}
|
|
64
66
|
|
|
65
67
|
public:
|
|
66
68
|
friend bool operator==(const EntityUpdate& lhs, const EntityUpdate& rhs) = default;
|
|
@@ -80,13 +82,15 @@ namespace margelo::nitro {
|
|
|
80
82
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "px"))),
|
|
81
83
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "py"))),
|
|
82
84
|
JSIConverter<std::optional<std::variant<margelo::nitro::rngine::Rect, margelo::nitro::rngine::Circle>>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "shape"))),
|
|
85
|
+
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "isSensor"))),
|
|
83
86
|
JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "color"))),
|
|
84
87
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "asset"))),
|
|
85
88
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress"))),
|
|
86
89
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vx"))),
|
|
87
90
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vy"))),
|
|
88
91
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ax"))),
|
|
89
|
-
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ay")))
|
|
92
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ay"))),
|
|
93
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "mass")))
|
|
90
94
|
);
|
|
91
95
|
}
|
|
92
96
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::rngine::EntityUpdate& arg) {
|
|
@@ -95,6 +99,7 @@ namespace margelo::nitro {
|
|
|
95
99
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "px"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.px));
|
|
96
100
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "py"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.py));
|
|
97
101
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "shape"), JSIConverter<std::optional<std::variant<margelo::nitro::rngine::Rect, margelo::nitro::rngine::Circle>>>::toJSI(runtime, arg.shape));
|
|
102
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "isSensor"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.isSensor));
|
|
98
103
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "color"), JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.color));
|
|
99
104
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "asset"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.asset));
|
|
100
105
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "progress"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.progress));
|
|
@@ -102,6 +107,7 @@ namespace margelo::nitro {
|
|
|
102
107
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "vy"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.vy));
|
|
103
108
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "ax"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.ax));
|
|
104
109
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "ay"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.ay));
|
|
110
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "mass"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.mass));
|
|
105
111
|
return obj;
|
|
106
112
|
}
|
|
107
113
|
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
@@ -116,6 +122,7 @@ namespace margelo::nitro {
|
|
|
116
122
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "px")))) return false;
|
|
117
123
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "py")))) return false;
|
|
118
124
|
if (!JSIConverter<std::optional<std::variant<margelo::nitro::rngine::Rect, margelo::nitro::rngine::Circle>>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "shape")))) return false;
|
|
125
|
+
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "isSensor")))) return false;
|
|
119
126
|
if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "color")))) return false;
|
|
120
127
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "asset")))) return false;
|
|
121
128
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress")))) return false;
|
|
@@ -123,6 +130,7 @@ namespace margelo::nitro {
|
|
|
123
130
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vy")))) return false;
|
|
124
131
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ax")))) return false;
|
|
125
132
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ay")))) return false;
|
|
133
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "mass")))) return false;
|
|
126
134
|
return true;
|
|
127
135
|
}
|
|
128
136
|
};
|
|
@@ -14,7 +14,7 @@ namespace margelo::nitro::rngine {
|
|
|
14
14
|
HybridObject::loadHybridMethods();
|
|
15
15
|
// load custom methods/properties
|
|
16
16
|
registerHybrids(this, [](Prototype& prototype) {
|
|
17
|
-
prototype.registerHybridMethod("
|
|
17
|
+
prototype.registerHybridMethod("setWorld", &HybridGameMethodsSpec::setWorld);
|
|
18
18
|
prototype.registerHybridMethod("setScreen", &HybridGameMethodsSpec::setScreen);
|
|
19
19
|
prototype.registerHybridMethod("setEntities", &HybridGameMethodsSpec::setEntities);
|
|
20
20
|
prototype.registerHybridMethod("setSystems", &HybridGameMethodsSpec::setSystems);
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
14
|
#endif
|
|
15
15
|
|
|
16
|
+
// Forward declaration of `World` to properly resolve imports.
|
|
17
|
+
namespace margelo::nitro::rngine { struct World; }
|
|
16
18
|
// Forward declaration of `Screen` to properly resolve imports.
|
|
17
19
|
namespace margelo::nitro::rngine { struct Screen; }
|
|
18
20
|
// Forward declaration of `Entity` to properly resolve imports.
|
|
@@ -22,6 +24,7 @@ namespace margelo::nitro::rngine { struct System; }
|
|
|
22
24
|
// Forward declaration of `EntityUpdate` to properly resolve imports.
|
|
23
25
|
namespace margelo::nitro::rngine { struct EntityUpdate; }
|
|
24
26
|
|
|
27
|
+
#include "World.hpp"
|
|
25
28
|
#include "Screen.hpp"
|
|
26
29
|
#include "Entity.hpp"
|
|
27
30
|
#include <vector>
|
|
@@ -60,7 +63,7 @@ namespace margelo::nitro::rngine {
|
|
|
60
63
|
|
|
61
64
|
public:
|
|
62
65
|
// Methods
|
|
63
|
-
virtual void
|
|
66
|
+
virtual void setWorld(const World& world) = 0;
|
|
64
67
|
virtual void setScreen(const Screen& screen) = 0;
|
|
65
68
|
virtual void setEntities(const std::vector<Entity>& entities) = 0;
|
|
66
69
|
virtual void setSystems(const std::vector<System>& systems) = 0;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// World.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
11
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
16
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
#if __has_include(<NitroModules/JSIHelpers.hpp>)
|
|
21
|
+
#include <NitroModules/JSIHelpers.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
25
|
+
#if __has_include(<NitroModules/PropNameIDCache.hpp>)
|
|
26
|
+
#include <NitroModules/PropNameIDCache.hpp>
|
|
27
|
+
#else
|
|
28
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
#include <optional>
|
|
34
|
+
|
|
35
|
+
namespace margelo::nitro::rngine {
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A struct which can be represented as a JavaScript object (World).
|
|
39
|
+
*/
|
|
40
|
+
struct World final {
|
|
41
|
+
public:
|
|
42
|
+
double tickRate SWIFT_PRIVATE;
|
|
43
|
+
std::optional<double> gx SWIFT_PRIVATE;
|
|
44
|
+
std::optional<double> gy SWIFT_PRIVATE;
|
|
45
|
+
|
|
46
|
+
public:
|
|
47
|
+
World() = default;
|
|
48
|
+
explicit World(double tickRate, std::optional<double> gx, std::optional<double> gy): tickRate(tickRate), gx(gx), gy(gy) {}
|
|
49
|
+
|
|
50
|
+
public:
|
|
51
|
+
friend bool operator==(const World& lhs, const World& rhs) = default;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
} // namespace margelo::nitro::rngine
|
|
55
|
+
|
|
56
|
+
namespace margelo::nitro {
|
|
57
|
+
|
|
58
|
+
// C++ World <> JS World (object)
|
|
59
|
+
template <>
|
|
60
|
+
struct JSIConverter<margelo::nitro::rngine::World> final {
|
|
61
|
+
static inline margelo::nitro::rngine::World fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
62
|
+
jsi::Object obj = arg.asObject(runtime);
|
|
63
|
+
return margelo::nitro::rngine::World(
|
|
64
|
+
JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "tickRate"))),
|
|
65
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "gx"))),
|
|
66
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "gy")))
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::rngine::World& arg) {
|
|
70
|
+
jsi::Object obj(runtime);
|
|
71
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "tickRate"), JSIConverter<double>::toJSI(runtime, arg.tickRate));
|
|
72
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "gx"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.gx));
|
|
73
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "gy"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.gy));
|
|
74
|
+
return obj;
|
|
75
|
+
}
|
|
76
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
77
|
+
if (!value.isObject()) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
jsi::Object obj = value.getObject(runtime);
|
|
81
|
+
if (!nitro::isPlainObject(runtime, obj)) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "tickRate")))) return false;
|
|
85
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "gx")))) return false;
|
|
86
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "gy")))) return false;
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
} // namespace margelo::nitro
|
package/package.json
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
#include "CollisionUtils.hpp"
|
|
2
|
+
#include "Collision.hpp"
|
|
3
|
+
#include <optional>
|
|
2
4
|
|
|
3
5
|
namespace margelo::nitro::rngine::CollisionUtils {
|
|
4
|
-
std::optional<
|
|
5
|
-
|
|
6
|
+
std::optional<Overlap> overlap(const Rect &a, double ax, double ay,
|
|
7
|
+
const Rect &b, double bx, double by) {
|
|
6
8
|
|
|
7
9
|
double aLeft = ax - a.width / 2.0, aRight = ax + a.width / 2.0;
|
|
8
10
|
double aTop = ay - a.height / 2.0, aBottom = ay + a.height / 2.0;
|
|
@@ -12,24 +14,35 @@ std::optional<double> overlap(const Rect &a, double ax, double ay,
|
|
|
12
14
|
double overlapX = std::min(aRight, bRight) - std::max(aLeft, bLeft);
|
|
13
15
|
double overlapY = std::min(aBottom, bBottom) - std::max(aTop, bTop);
|
|
14
16
|
|
|
15
|
-
if (overlapX
|
|
16
|
-
return std::
|
|
17
|
-
|
|
17
|
+
if (overlapX <= 0 || overlapY <= 0)
|
|
18
|
+
return std::nullopt;
|
|
19
|
+
|
|
20
|
+
if (overlapX < overlapY) {
|
|
21
|
+
double nx = (bx >= ax) ? 1.0 : -1.0;
|
|
22
|
+
return Overlap{overlapX, nx, 0.0};
|
|
23
|
+
} else {
|
|
24
|
+
double ny = (by >= ay) ? 1.0 : -1.0;
|
|
25
|
+
return Overlap{overlapY, 0.0, ny};
|
|
26
|
+
}
|
|
18
27
|
}
|
|
19
28
|
|
|
20
|
-
std::optional<
|
|
21
|
-
|
|
29
|
+
std::optional<Overlap> overlap(const Circle &a, double ax, double ay,
|
|
30
|
+
const Circle &b, double bx, double by) {
|
|
22
31
|
double dx = bx - ax, dy = by - ay;
|
|
23
32
|
double dist = std::sqrt(dx * dx + dy * dy);
|
|
24
33
|
double depth = (a.radius + b.radius) - dist;
|
|
25
34
|
|
|
26
|
-
if (depth
|
|
27
|
-
return
|
|
28
|
-
|
|
35
|
+
if (depth <= 0)
|
|
36
|
+
return std::nullopt;
|
|
37
|
+
|
|
38
|
+
if (dist == 0.0)
|
|
39
|
+
return Overlap{depth, 0.0, -1.0};
|
|
40
|
+
|
|
41
|
+
return Overlap{depth, dx / dist, dy / dist};
|
|
29
42
|
}
|
|
30
43
|
|
|
31
|
-
std::optional<
|
|
32
|
-
|
|
44
|
+
std::optional<Overlap> overlap(const Rect &a, double ax, double ay,
|
|
45
|
+
const Circle &b, double bx, double by) {
|
|
33
46
|
double left = ax - a.width / 2.0, right = ax + a.width / 2.0;
|
|
34
47
|
double top = ay - a.height / 2.0, bottom = ay + a.height / 2.0;
|
|
35
48
|
|
|
@@ -42,26 +55,49 @@ std::optional<double> overlap(const Rect &a, double ax, double ay,
|
|
|
42
55
|
if (distSq >= b.radius * b.radius)
|
|
43
56
|
return std::nullopt;
|
|
44
57
|
|
|
58
|
+
if (distSq == 0.0) {
|
|
59
|
+
double cdx = bx - ax, cdy = by - ay;
|
|
60
|
+
double cdist = std::sqrt(cdx * cdx + cdy * cdy);
|
|
61
|
+
if (cdist == 0.0)
|
|
62
|
+
return Overlap{b.radius, 0.0, -1.0};
|
|
63
|
+
return Overlap{b.radius, cdx / cdist, cdy / cdist};
|
|
64
|
+
}
|
|
65
|
+
|
|
45
66
|
double dist = std::sqrt(distSq);
|
|
46
|
-
return b.radius - dist;
|
|
67
|
+
return Overlap{b.radius - dist, dx / dist, dy / dist};
|
|
47
68
|
}
|
|
48
69
|
|
|
49
|
-
std::optional<
|
|
50
|
-
|
|
51
|
-
|
|
70
|
+
std::optional<Overlap> overlap(const Circle &a, double ax, double ay,
|
|
71
|
+
const Rect &b, double bx, double by) {
|
|
72
|
+
auto result = overlap(b, bx, by, a, ax, ay);
|
|
73
|
+
|
|
74
|
+
if (!result.has_value()) {
|
|
75
|
+
return std::nullopt;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
result.value().nx = -result.value().nx;
|
|
79
|
+
result.value().ny = -result.value().ny;
|
|
80
|
+
|
|
81
|
+
return result;
|
|
52
82
|
}
|
|
53
83
|
|
|
54
|
-
std::optional<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
[&](const auto &shapeA) -> std::optional<
|
|
84
|
+
std::optional<Collision> shapeOverlap(const Entity &entityA,
|
|
85
|
+
const Entity &entityB) {
|
|
86
|
+
auto result = std::visit(
|
|
87
|
+
[&](const auto &shapeA) -> std::optional<Overlap> {
|
|
58
88
|
return std::visit(
|
|
59
|
-
[&](const auto &shapeB) -> std::optional<
|
|
89
|
+
[&](const auto &shapeB) -> std::optional<Overlap> {
|
|
60
90
|
return overlap(shapeA, entityA.px, entityA.py, shapeB, entityB.px,
|
|
61
91
|
entityB.py);
|
|
62
92
|
},
|
|
63
93
|
entityB.shape);
|
|
64
94
|
},
|
|
65
95
|
entityA.shape);
|
|
96
|
+
if (!result.has_value()) {
|
|
97
|
+
return nullopt;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return Collision{entityA.id, entityB.id, result->depth, result->nx,
|
|
101
|
+
result->ny};
|
|
66
102
|
}
|
|
67
103
|
} // namespace margelo::nitro::rngine::CollisionUtils
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
3
|
#include "Circle.hpp"
|
|
4
|
+
#include "Collision.hpp"
|
|
4
5
|
#include "Entity.hpp"
|
|
5
6
|
#include "Rect.hpp"
|
|
6
7
|
#include <optional>
|
|
7
8
|
|
|
8
9
|
namespace margelo::nitro::rngine::CollisionUtils {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
std::optional<
|
|
16
|
-
|
|
17
|
-
std::optional<
|
|
18
|
-
|
|
10
|
+
struct Overlap {
|
|
11
|
+
double depth;
|
|
12
|
+
double nx;
|
|
13
|
+
double ny;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
std::optional<Overlap> overlap(const Rect &a, double ax, double ay,
|
|
17
|
+
const Rect &b, double bx, double by);
|
|
18
|
+
std::optional<Overlap> overlap(const Circle &a, double ax, double ay,
|
|
19
|
+
const Circle &b, double bx, double by);
|
|
20
|
+
std::optional<Overlap> overlap(const Rect &a, double ax, double ay,
|
|
21
|
+
const Circle &b, double bx, double by);
|
|
22
|
+
std::optional<Overlap> overlap(const Circle &a, double ax, double ay,
|
|
23
|
+
const Rect &b, double bx, double by);
|
|
24
|
+
std::optional<Collision> shapeOverlap(const Entity &entityA,
|
|
25
|
+
const Entity &entityB);
|
|
19
26
|
} // namespace margelo::nitro::rngine::CollisionUtils
|
package/shared/GameLoop.cpp
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
#include <android/log.h>
|
|
6
6
|
#include <chrono>
|
|
7
7
|
#include <cinttypes>
|
|
8
|
-
#include <set>
|
|
9
8
|
|
|
10
9
|
namespace margelo::nitro::rngine {
|
|
11
10
|
|
|
@@ -32,6 +31,11 @@ GameLoop::~GameLoop() {
|
|
|
32
31
|
__android_log_print(ANDROID_LOG_INFO, "GameLoop", "Destructor - Complete");
|
|
33
32
|
}
|
|
34
33
|
|
|
34
|
+
bool GameLoop::entityIdMatches(const std::string &entityId,
|
|
35
|
+
const std::string &prefix) {
|
|
36
|
+
return entityId == prefix || entityId.starts_with(prefix + "_");
|
|
37
|
+
}
|
|
38
|
+
|
|
35
39
|
std::vector<Entity *>
|
|
36
40
|
GameLoop::resolveEntitiesInternal(const std::string &prefix) {
|
|
37
41
|
std::vector<Entity *> results;
|
|
@@ -69,7 +73,11 @@ void GameLoop::runGameLoop() {
|
|
|
69
73
|
double accumulator = 0.0;
|
|
70
74
|
|
|
71
75
|
while (_isRunning) {
|
|
72
|
-
double targetDeltaTime
|
|
76
|
+
double targetDeltaTime;
|
|
77
|
+
{
|
|
78
|
+
std::lock_guard<std::mutex> lock(_worldMutex);
|
|
79
|
+
targetDeltaTime = 1.0 / _world.tickRate;
|
|
80
|
+
}
|
|
73
81
|
auto currentTime = steady_clock::now();
|
|
74
82
|
double frameTime = duration<double>(currentTime - previousTime).count();
|
|
75
83
|
previousTime = currentTime;
|
|
@@ -108,28 +116,14 @@ void GameLoop::runSystems() {
|
|
|
108
116
|
}
|
|
109
117
|
|
|
110
118
|
if (system.collisions.has_value()) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (entityA == entityB)
|
|
120
|
-
continue;
|
|
121
|
-
|
|
122
|
-
auto uniqueEntityIdPairKey = std::minmax(entityA->id, entityB->id);
|
|
123
|
-
|
|
124
|
-
if (uniqueEntityIdPairs.count(uniqueEntityIdPairKey))
|
|
125
|
-
continue;
|
|
126
|
-
|
|
127
|
-
uniqueEntityIdPairs.insert(uniqueEntityIdPairKey);
|
|
128
|
-
|
|
129
|
-
if (auto ov = CollisionUtils::shapeOverlap(*entityA, *entityB)) {
|
|
130
|
-
collisions.push_back(
|
|
131
|
-
Collision(entityA->id, entityB->id, ov.value()));
|
|
132
|
-
}
|
|
119
|
+
for (const auto &pair : system.collisions.value()) {
|
|
120
|
+
for (const auto &c : _collisions) {
|
|
121
|
+
bool matchesForward =
|
|
122
|
+
entityIdMatches(c.a, pair.a) && entityIdMatches(c.b, pair.b);
|
|
123
|
+
bool matchesReverse =
|
|
124
|
+
entityIdMatches(c.a, pair.b) && entityIdMatches(c.b, pair.a);
|
|
125
|
+
if (matchesForward || matchesReverse) {
|
|
126
|
+
collisions.push_back(c);
|
|
133
127
|
}
|
|
134
128
|
}
|
|
135
129
|
}
|
|
@@ -161,6 +155,8 @@ void GameLoop::captureSnapshot() {
|
|
|
161
155
|
void GameLoop::update(double deltaTime) {
|
|
162
156
|
updateStats(deltaTime);
|
|
163
157
|
updateEntities(deltaTime);
|
|
158
|
+
computeCollisions();
|
|
159
|
+
resolveCollisions();
|
|
164
160
|
runSystems();
|
|
165
161
|
captureSnapshot();
|
|
166
162
|
}
|
|
@@ -189,10 +185,20 @@ void GameLoop::updateStats(double deltaTime) {
|
|
|
189
185
|
}
|
|
190
186
|
|
|
191
187
|
void GameLoop::updateEntities(double deltaTime) {
|
|
188
|
+
std::lock_guard<std::mutex> worldLock(_worldMutex);
|
|
192
189
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
193
190
|
|
|
194
191
|
for (auto &[id, entity] : _entities) {
|
|
195
192
|
|
|
193
|
+
if (entity.mass.has_value() && entity.mass.value() > 0.0) {
|
|
194
|
+
if (_world.gx.has_value()) {
|
|
195
|
+
entity.vx = entity.vx.value_or(0.0) + _world.gx.value() * deltaTime;
|
|
196
|
+
}
|
|
197
|
+
if (_world.gy.has_value()) {
|
|
198
|
+
entity.vy = entity.vy.value_or(0.0) + _world.gy.value() * deltaTime;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
196
202
|
if (entity.ax.has_value()) {
|
|
197
203
|
entity.vx = entity.vx.value_or(0.0) + entity.ax.value() * deltaTime;
|
|
198
204
|
}
|
|
@@ -216,4 +222,77 @@ void GameLoop::updateEntities(double deltaTime) {
|
|
|
216
222
|
}
|
|
217
223
|
}
|
|
218
224
|
}
|
|
225
|
+
|
|
226
|
+
void GameLoop::computeCollisions() {
|
|
227
|
+
std::lock_guard<std::mutex> lock(_mutex);
|
|
228
|
+
_collisions.clear();
|
|
229
|
+
|
|
230
|
+
std::vector<Entity *> entities;
|
|
231
|
+
entities.reserve(_entities.size());
|
|
232
|
+
for (auto &[id, entity] : _entities) {
|
|
233
|
+
entities.push_back(&entity);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
for (size_t i = 0; i < entities.size(); ++i) {
|
|
237
|
+
for (size_t j = i + 1; j < entities.size(); ++j) {
|
|
238
|
+
auto result = CollisionUtils::shapeOverlap(*entities[i], *entities[j]);
|
|
239
|
+
if (result.has_value()) {
|
|
240
|
+
_collisions.push_back(result.value());
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
void GameLoop::resolveCollisions() {
|
|
247
|
+
std::lock_guard<std::mutex> lock(_mutex);
|
|
248
|
+
|
|
249
|
+
const double percent = 0.8;
|
|
250
|
+
const double slop = 0.01;
|
|
251
|
+
|
|
252
|
+
for (const auto &c : _collisions) {
|
|
253
|
+
auto itA = _entities.find(c.a);
|
|
254
|
+
auto itB = _entities.find(c.b);
|
|
255
|
+
if (itA == _entities.end() || itB == _entities.end())
|
|
256
|
+
continue;
|
|
257
|
+
|
|
258
|
+
Entity &a = itA->second;
|
|
259
|
+
Entity &b = itB->second;
|
|
260
|
+
|
|
261
|
+
if (a.isSensor.value_or(false) || b.isSensor.value_or(false))
|
|
262
|
+
continue;
|
|
263
|
+
|
|
264
|
+
double inverseMassA = (a.mass.has_value() && a.mass.value() > 0.0)
|
|
265
|
+
? 1.0 / a.mass.value()
|
|
266
|
+
: 0.0;
|
|
267
|
+
double inverseMassB = (b.mass.has_value() && b.mass.value() > 0.0)
|
|
268
|
+
? 1.0 / b.mass.value()
|
|
269
|
+
: 0.0;
|
|
270
|
+
double totalInverseMass = inverseMassA + inverseMassB;
|
|
271
|
+
if (totalInverseMass == 0.0)
|
|
272
|
+
continue;
|
|
273
|
+
|
|
274
|
+
double correctionDepth = std::max(c.depth - slop, 0.0);
|
|
275
|
+
double correction = (correctionDepth / totalInverseMass) * percent;
|
|
276
|
+
a.px -= c.nx * correction * inverseMassA;
|
|
277
|
+
a.py -= c.ny * correction * inverseMassA;
|
|
278
|
+
b.px += c.nx * correction * inverseMassB;
|
|
279
|
+
b.py += c.ny * correction * inverseMassB;
|
|
280
|
+
|
|
281
|
+
double avx = a.vx.value_or(0.0), avy = a.vy.value_or(0.0);
|
|
282
|
+
double bvx = b.vx.value_or(0.0), bvy = b.vy.value_or(0.0);
|
|
283
|
+
double relativeVx = bvx - avx, relativeVy = bvy - avy;
|
|
284
|
+
double velocityAlongNormal = relativeVx * c.nx + relativeVy * c.ny;
|
|
285
|
+
if (velocityAlongNormal > 0)
|
|
286
|
+
continue;
|
|
287
|
+
|
|
288
|
+
double restitution = 0.0;
|
|
289
|
+
double impulse =
|
|
290
|
+
-(1 + restitution) * velocityAlongNormal / totalInverseMass;
|
|
291
|
+
|
|
292
|
+
a.vx = avx - impulse * c.nx * inverseMassA;
|
|
293
|
+
a.vy = avy - impulse * c.ny * inverseMassA;
|
|
294
|
+
b.vx = bvx + impulse * c.nx * inverseMassB;
|
|
295
|
+
b.vy = bvy + impulse * c.ny * inverseMassB;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
219
298
|
} // namespace margelo::nitro::rngine
|
package/shared/GameLoop.hpp
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#include "GameStats.hpp"
|
|
5
5
|
#include "Screen.hpp"
|
|
6
6
|
#include "System.hpp"
|
|
7
|
+
#include "World.hpp"
|
|
7
8
|
#include <atomic>
|
|
8
9
|
#include <memory>
|
|
9
10
|
#include <thread>
|
|
@@ -20,6 +21,7 @@ public:
|
|
|
20
21
|
|
|
21
22
|
~GameLoop();
|
|
22
23
|
|
|
24
|
+
std::mutex &getWorldMutexInternal() { return _worldMutex; };
|
|
23
25
|
std::mutex &getMutexInternal() { return _mutex; };
|
|
24
26
|
std::mutex &getSnapshotMutexInternal() { return _snapshotMutex; };
|
|
25
27
|
std::map<string, Entity> &getEntitiesInternal() { return _entities; };
|
|
@@ -28,25 +30,27 @@ public:
|
|
|
28
30
|
};
|
|
29
31
|
std::vector<System> &getSystemsInternal() { return _systems; };
|
|
30
32
|
std::atomic<bool> &getIsPausedInternal() { return _isPaused; };
|
|
33
|
+
World &getWorldInternal() { return _world; };
|
|
31
34
|
Screen &getScreenInternal() { return _screen; };
|
|
32
35
|
Screen &getScreenSnapshotInternal() { return _screenSnapshot; };
|
|
33
36
|
|
|
37
|
+
bool entityIdMatches(const std::string &entityId, const std::string &prefix);
|
|
34
38
|
std::vector<Entity *> resolveEntitiesInternal(const std::string &prefix);
|
|
35
39
|
void registerLottieDuration(double, double);
|
|
36
40
|
|
|
37
|
-
void setTickRate(double tickRate) { _tickRate.store(tickRate); };
|
|
38
|
-
|
|
39
41
|
private:
|
|
40
42
|
explicit GameLoop();
|
|
43
|
+
std::mutex _worldMutex;
|
|
41
44
|
std::mutex _mutex;
|
|
42
45
|
std::mutex _snapshotMutex;
|
|
43
46
|
std::map<std::string, Entity> _entities;
|
|
44
47
|
std::map<std::string, Entity> _entitiesSnapshot;
|
|
45
48
|
std::map<double, double> _lottieDurations;
|
|
49
|
+
std::vector<Collision> _collisions{};
|
|
46
50
|
std::vector<System> _systems{};
|
|
47
51
|
std::atomic<bool> _isRunning{true};
|
|
48
52
|
std::atomic<bool> _isPaused{true};
|
|
49
|
-
|
|
53
|
+
World _world;
|
|
50
54
|
Screen _screen;
|
|
51
55
|
Screen _screenSnapshot;
|
|
52
56
|
GameStats _gameStats;
|
|
@@ -54,6 +58,8 @@ private:
|
|
|
54
58
|
|
|
55
59
|
void runGameLoop();
|
|
56
60
|
void runSystems();
|
|
61
|
+
void computeCollisions();
|
|
62
|
+
void resolveCollisions();
|
|
57
63
|
void captureSnapshot();
|
|
58
64
|
void update(double deltaTime);
|
|
59
65
|
void updateStats(double deltaTime);
|
package/shared/GameMethods.cpp
CHANGED
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
#include <android/log.h>
|
|
5
5
|
|
|
6
6
|
namespace margelo::nitro::rngine {
|
|
7
|
-
void GameMethods::
|
|
7
|
+
void GameMethods::setWorld(const World &world) {
|
|
8
8
|
auto &instance = GameLoop::getInstance();
|
|
9
|
-
instance.
|
|
9
|
+
std::lock_guard<std::mutex> lock(instance.getWorldMutexInternal());
|
|
10
|
+
instance.getWorldInternal() = world;
|
|
10
11
|
__android_log_print(ANDROID_LOG_INFO, "GameMethods",
|
|
11
|
-
"
|
|
12
|
+
"setWorld: tickRate=%.1f", world.tickRate);
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
void GameMethods::setScreen(const Screen &screen) {
|
|
@@ -19,7 +20,7 @@ void GameMethods::setScreen(const Screen &screen) {
|
|
|
19
20
|
instance.getScreenSnapshotInternal() = screen;
|
|
20
21
|
|
|
21
22
|
__android_log_print(ANDROID_LOG_INFO, "GameMethods",
|
|
22
|
-
"
|
|
23
|
+
"setScreen: width=%.0f height=%.0f", screen.width,
|
|
23
24
|
screen.height);
|
|
24
25
|
}
|
|
25
26
|
|
|
@@ -130,6 +131,9 @@ void GameMethods::update(const std::vector<EntityUpdate> &updates) {
|
|
|
130
131
|
if (update.shape.has_value()) {
|
|
131
132
|
entity->shape = update.shape.value();
|
|
132
133
|
}
|
|
134
|
+
if (update.isSensor.has_value()) {
|
|
135
|
+
entity->isSensor = update.isSensor.value();
|
|
136
|
+
}
|
|
133
137
|
if (update.asset.has_value()) {
|
|
134
138
|
entity->asset = update.asset.value();
|
|
135
139
|
}
|
|
@@ -151,6 +155,9 @@ void GameMethods::update(const std::vector<EntityUpdate> &updates) {
|
|
|
151
155
|
if (update.ay.has_value()) {
|
|
152
156
|
entity->ay = update.ay.value();
|
|
153
157
|
}
|
|
158
|
+
if (update.mass.has_value()) {
|
|
159
|
+
entity->mass = update.mass.value();
|
|
160
|
+
}
|
|
154
161
|
}
|
|
155
162
|
|
|
156
163
|
__android_log_print(ANDROID_LOG_INFO, "GameMethods",
|
package/shared/GameMethods.hpp
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
3
|
#include "HybridGameMethodsSpec.hpp"
|
|
4
|
+
#include "World.hpp"
|
|
4
5
|
|
|
5
6
|
namespace margelo::nitro::rngine {
|
|
6
7
|
class GameMethods : public HybridGameMethodsSpec {
|
|
7
8
|
public:
|
|
8
9
|
GameMethods() : HybridObject(TAG) {}
|
|
9
|
-
void
|
|
10
|
+
void setWorld(const World &world) override;
|
|
10
11
|
void setScreen(const Screen &screen) override;
|
|
11
12
|
void setEntities(const std::vector<Entity> &entities) override;
|
|
12
13
|
void setSystems(const std::vector<System> &systems) override;
|
package/src/GameMethods.nitro.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
Entity,
|
|
4
|
+
EntityUpdate,
|
|
5
|
+
System,
|
|
6
|
+
Screen,
|
|
7
|
+
World,
|
|
8
|
+
} from './nativeTypes';
|
|
3
9
|
import { NitroModules } from 'react-native-nitro-modules';
|
|
4
10
|
|
|
5
11
|
interface GameMethods extends HybridObject<{
|
|
6
12
|
ios: 'c++';
|
|
7
13
|
android: 'c++';
|
|
8
14
|
}> {
|
|
9
|
-
|
|
15
|
+
setWorld(world: World): void;
|
|
10
16
|
setScreen(screen: Screen): void;
|
|
11
17
|
setEntities(entities: Entity[]): void;
|
|
12
18
|
setSystems(systems: System[]): void;
|
package/src/GameMethods.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { Config } from './types';
|
|
|
4
4
|
|
|
5
5
|
/** Sets up the game engine with the given configuration. Call this before anything else. */
|
|
6
6
|
export const configure = ({
|
|
7
|
-
|
|
7
|
+
world,
|
|
8
8
|
screen,
|
|
9
9
|
entities = [],
|
|
10
10
|
systems = [],
|
|
@@ -25,7 +25,7 @@ export const configure = ({
|
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
gameMethods.
|
|
28
|
+
gameMethods.setWorld(world);
|
|
29
29
|
gameMethods.setScreen(screen);
|
|
30
30
|
gameMethods.setEntities(entities);
|
|
31
31
|
gameMethods.setSystems(nativeSystems);
|
package/src/index.tsx
CHANGED
package/src/nativeTypes.ts
CHANGED
|
@@ -20,6 +20,8 @@ interface Circle {
|
|
|
20
20
|
interface Shaped {
|
|
21
21
|
/** Shape of the entity. */
|
|
22
22
|
shape: Rect | Circle;
|
|
23
|
+
/** Indicates whether the entity is a sensor. Sensors trigger collision events but don't react physically. */
|
|
24
|
+
isSensor?: boolean;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
interface Renderable {
|
|
@@ -40,6 +42,17 @@ interface Kinematic {
|
|
|
40
42
|
ax?: number;
|
|
41
43
|
/** Vertical acceleration in game units per second squared. */
|
|
42
44
|
ay?: number;
|
|
45
|
+
/** Mass in arbitrary units. */
|
|
46
|
+
mass?: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface World {
|
|
50
|
+
/** Number of game logic updates per second. */
|
|
51
|
+
tickRate: number;
|
|
52
|
+
/** Horizontal gravitational acceleration in game units per second squared. */
|
|
53
|
+
gx?: number;
|
|
54
|
+
/** Vertical gravitational acceleration in game units per second squared. */
|
|
55
|
+
gy?: number;
|
|
43
56
|
}
|
|
44
57
|
|
|
45
58
|
export interface Screen extends Rect, Renderable {}
|
|
@@ -70,6 +83,10 @@ export interface Collision {
|
|
|
70
83
|
b: string;
|
|
71
84
|
/** Penetration depth of the collision. */
|
|
72
85
|
depth: number;
|
|
86
|
+
/** X component of a normalised vector that represents the direction between the bodies providing the minimum separating distance. */
|
|
87
|
+
nx: number;
|
|
88
|
+
/** Y component of a normalised vector that represents the direction between the bodies providing the minimum separating distance. */
|
|
89
|
+
ny: number;
|
|
73
90
|
}
|
|
74
91
|
|
|
75
92
|
export interface System {
|
package/src/types.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type {
|
|
|
3
3
|
Collision,
|
|
4
4
|
Screen,
|
|
5
5
|
Entity,
|
|
6
|
+
World,
|
|
6
7
|
} from './nativeTypes';
|
|
7
8
|
|
|
8
9
|
export type System = Omit<NativeSystem, 'onTick'> & {
|
|
@@ -11,17 +12,14 @@ export type System = Omit<NativeSystem, 'onTick'> & {
|
|
|
11
12
|
};
|
|
12
13
|
|
|
13
14
|
export type Config = {
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
/** Screen dimensions and background
|
|
15
|
+
/** World settings: tick rate and gravity. */
|
|
16
|
+
world: World;
|
|
17
|
+
/** Screen dimensions and background. */
|
|
17
18
|
screen: Screen;
|
|
18
|
-
/**
|
|
19
|
+
/** Entities to spawn when the game starts. */
|
|
19
20
|
entities?: Entity[];
|
|
20
|
-
/**
|
|
21
|
-
* Systems that define the game logic. Each system runs every tick
|
|
22
|
-
* and receives the entities matching its ids.
|
|
23
|
-
*/
|
|
21
|
+
/** Systems that define game logic, each running every tick against its subscribed entities and collisions. */
|
|
24
22
|
systems?: System[];
|
|
25
|
-
/** Whether
|
|
23
|
+
/** Whether the game starts paused. Defaults to true. */
|
|
26
24
|
paused?: boolean;
|
|
27
25
|
};
|
package/android/kls_database.db
DELETED
|
Binary file
|