rngine 0.2.1 → 0.3.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 CHANGED
@@ -1,4 +1,4 @@
1
- # rngine
1
+ # Rngine
2
2
 
3
3
  A React Native game engine for building 2D games, powered by [Nitro Modules](https://nitro.margelo.com/) for high-performance C++ game logic.
4
4
 
@@ -13,7 +13,7 @@ npm install rngine react-native-nitro-modules
13
13
  ## Usage
14
14
 
15
15
  ```tsx
16
- import { GameEngine, configure, setVelocity } from 'rngine';
16
+ import { GameEngine, configure, update } from 'rngine';
17
17
 
18
18
  configure({
19
19
  tickRate: 60,
@@ -26,8 +26,6 @@ configure({
26
26
  width: 40,
27
27
  height: 40,
28
28
  color: '#00ff00',
29
- vx: 0,
30
- vy: 0,
31
29
  },
32
30
  {
33
31
  id: 'enemy_1',
@@ -37,7 +35,6 @@ configure({
37
35
  height: 40,
38
36
  color: '#ff0000',
39
37
  vx: 1000,
40
- vy: 0,
41
38
  },
42
39
  {
43
40
  id: 'enemy_2',
@@ -47,7 +44,6 @@ configure({
47
44
  height: 40,
48
45
  color: '#ff0000',
49
46
  vx: -1000,
50
- vy: 0,
51
47
  },
52
48
  ],
53
49
  systems: [
@@ -58,7 +54,7 @@ configure({
58
54
  enemies.forEach((enemy) => {
59
55
  // reverse direction when reaching world edges
60
56
  if (enemy.px <= 0 || enemy.px + enemy.width >= 800) {
61
- setVelocity(enemy.id, -enemy.vx, enemy.vy);
57
+ update({ id: enemy.id, vx: -enemy.vx });
62
58
  }
63
59
  });
64
60
  },
@@ -82,7 +78,7 @@ export default function App() {
82
78
 
83
79
  ## Entity Querying
84
80
 
85
- Entity ids use `_` as a hierarchy separator, which enables prefix matching in systems and functions like `setVelocity`. Querying `'enemy'` matches all entities whose id starts with `enemy_`. So `enemy_1`, `enemy_magician_1`, and `enemy_warrior_2` are all returned. Querying `'enemy_magician'` narrows it down to only magician entities. Querying `'enemy_magician_1'` is an exact match.
81
+ Entity ids use `_` as a hierarchy separator, which enables prefix matching in systems and functions like `update`. Querying `'enemy'` matches all entities whose id starts with `enemy_`. So `enemy_1`, `enemy_magician_1`, and `enemy_warrior_2` are all returned. Querying `'enemy_magician'` narrows it down to only magician entities. Querying `'enemy_magician_1'` is an exact match.
86
82
 
87
83
  This makes it easy to build entity groups naturally through naming. No extra configuration needed.
88
84
 
@@ -105,8 +101,8 @@ Sets up the game engine. Call this before anything else.
105
101
 
106
102
  | param | required | type | default | description |
107
103
  | ---------- | -------- | ---------- | ------- | ------------------------------------- |
108
- | `tickRate` | ✓ | `number` | | Game logic updates per second |
109
- | `world` | ✓ | `World` | | World dimensions and background color |
104
+ | `tickRate` | ✓ | `number` | - | Game logic updates per second |
105
+ | `world` | ✓ | `World` | - | World dimensions and background color |
110
106
  | `entities` | | `Entity[]` | `[]` | Initial entities to spawn |
111
107
  | `systems` | | `System[]` | `[]` | Systems to run each tick |
112
108
  | `paused` | | `boolean` | `true` | Whether to start paused |
@@ -119,13 +115,10 @@ Spawns one or more entities into the world. Skips duplicates by id.
119
115
 
120
116
  Removes the entity with the given id, or all entities matching the given prefix.
121
117
 
122
- ### `setPosition(id, px, py)`
118
+ ### `update(entityUpdate | entityUpdate[])`
123
119
 
124
- Sets the position of a single entity. Requires an exact id.
125
-
126
- ### `setVelocity(id, vx, vy)`
127
-
128
- Sets the velocity of all entities matching the given id or prefix.
120
+ Updates one or more entities. Only the provided fields are changed.
121
+ Matches entities by exact id or prefix.
129
122
 
130
123
  ### `pause()`
131
124
 
@@ -36,9 +36,8 @@ export const spawn = entities => {
36
36
  /** Removes an entity or all entities matching the given id prefix from the world. */
37
37
  export const despawn = id => gameMethods.despawn(id);
38
38
 
39
- /** Sets the position of the entity with the exact given id. */
40
- export const setPosition = (id, px, py) => gameMethods.setP(id, px, py);
41
-
42
- /** Sets the velocity of all entities matching the given id or prefix. */
43
- export const setVelocity = (id, vx, vy) => gameMethods.setV(id, vx, vy);
39
+ /** Updates one or more entities. Only the provided fields are changed. */
40
+ export const update = updates => {
41
+ gameMethods.update(Array.isArray(updates) ? updates : [updates]);
42
+ };
44
43
  //# sourceMappingURL=GameMethods.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["NitroModules","gameMethods","createHybridObject","configure","tickRate","world","entities","systems","paused","setTickRate","setWorld","setEntities","setSystems","pause","resume","spawn","Array","isArray","despawn","id","setPosition","px","py","setP","setVelocity","vx","vy","setV"],"sourceRoot":"../../src","sources":["GameMethods.ts"],"mappings":";;AAAA,SAASA,YAAY,QAAQ,4BAA4B;AAIzD,MAAMC,WAAW,GAAGD,YAAY,CAACE,kBAAkB,CAAc,aAAa,CAAC;;AAE/E;AACA,OAAO,SAASC,SAASA,CAAC;EACxBC,QAAQ;EACRC,KAAK;EACLC,QAAQ,GAAG,EAAE;EACbC,OAAO,GAAG,EAAE;EACZC,MAAM,GAAG;AACH,CAAC,EAAE;EACTP,WAAW,CAACQ,WAAW,CAACL,QAAQ,CAAC;EACjCH,WAAW,CAACS,QAAQ,CAACL,KAAK,CAAC;EAC3BJ,WAAW,CAACU,WAAW,CAACL,QAAQ,CAAC;EACjCL,WAAW,CAACW,UAAU,CAACL,OAAO,CAAC;EAC/B,IAAIC,MAAM,EAAE;IACVP,WAAW,CAACY,KAAK,CAAC,CAAC;EACrB,CAAC,MAAM;IACLZ,WAAW,CAACa,MAAM,CAAC,CAAC;EACtB;AACF;;AAEA;AACA,OAAO,MAAMD,KAAK,GAAGA,CAAA,KAAMZ,WAAW,CAACY,KAAK,CAAC,CAAC;;AAE9C;AACA,OAAO,MAAMC,MAAM,GAAGA,CAAA,KAAMb,WAAW,CAACa,MAAM,CAAC,CAAC;;AAEhD;AACA,OAAO,MAAMC,KAAK,GAAIT,QAA2B,IAAK;EACpDL,WAAW,CAACc,KAAK,CAACC,KAAK,CAACC,OAAO,CAACX,QAAQ,CAAC,GAAGA,QAAQ,GAAG,CAACA,QAAQ,CAAC,CAAC;AACpE,CAAC;;AAED;AACA,OAAO,MAAMY,OAAO,GAAIC,EAAU,IAAKlB,WAAW,CAACiB,OAAO,CAACC,EAAE,CAAC;;AAE9D;AACA,OAAO,MAAMC,WAAW,GAAGA,CAACD,EAAU,EAAEE,EAAU,EAAEC,EAAU,KAC5DrB,WAAW,CAACsB,IAAI,CAACJ,EAAE,EAAEE,EAAE,EAAEC,EAAE,CAAC;;AAE9B;AACA,OAAO,MAAME,WAAW,GAAGA,CAACL,EAAU,EAAEM,EAAU,EAAEC,EAAU,KAC5DzB,WAAW,CAAC0B,IAAI,CAACR,EAAE,EAAEM,EAAE,EAAEC,EAAE,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["NitroModules","gameMethods","createHybridObject","configure","tickRate","world","entities","systems","paused","setTickRate","setWorld","setEntities","setSystems","pause","resume","spawn","Array","isArray","despawn","id","update","updates"],"sourceRoot":"../../src","sources":["GameMethods.ts"],"mappings":";;AAAA,SAASA,YAAY,QAAQ,4BAA4B;AAIzD,MAAMC,WAAW,GAAGD,YAAY,CAACE,kBAAkB,CAAc,aAAa,CAAC;;AAE/E;AACA,OAAO,SAASC,SAASA,CAAC;EACxBC,QAAQ;EACRC,KAAK;EACLC,QAAQ,GAAG,EAAE;EACbC,OAAO,GAAG,EAAE;EACZC,MAAM,GAAG;AACH,CAAC,EAAE;EACTP,WAAW,CAACQ,WAAW,CAACL,QAAQ,CAAC;EACjCH,WAAW,CAACS,QAAQ,CAACL,KAAK,CAAC;EAC3BJ,WAAW,CAACU,WAAW,CAACL,QAAQ,CAAC;EACjCL,WAAW,CAACW,UAAU,CAACL,OAAO,CAAC;EAC/B,IAAIC,MAAM,EAAE;IACVP,WAAW,CAACY,KAAK,CAAC,CAAC;EACrB,CAAC,MAAM;IACLZ,WAAW,CAACa,MAAM,CAAC,CAAC;EACtB;AACF;;AAEA;AACA,OAAO,MAAMD,KAAK,GAAGA,CAAA,KAAMZ,WAAW,CAACY,KAAK,CAAC,CAAC;;AAE9C;AACA,OAAO,MAAMC,MAAM,GAAGA,CAAA,KAAMb,WAAW,CAACa,MAAM,CAAC,CAAC;;AAEhD;AACA,OAAO,MAAMC,KAAK,GAAIT,QAA2B,IAAK;EACpDL,WAAW,CAACc,KAAK,CAACC,KAAK,CAACC,OAAO,CAACX,QAAQ,CAAC,GAAGA,QAAQ,GAAG,CAACA,QAAQ,CAAC,CAAC;AACpE,CAAC;;AAED;AACA,OAAO,MAAMY,OAAO,GAAIC,EAAU,IAAKlB,WAAW,CAACiB,OAAO,CAACC,EAAE,CAAC;;AAE9D;AACA,OAAO,MAAMC,MAAM,GAAIC,OAAsC,IAAK;EAChEpB,WAAW,CAACmB,MAAM,CAACJ,KAAK,CAACC,OAAO,CAACI,OAAO,CAAC,GAAGA,OAAO,GAAG,CAACA,OAAO,CAAC,CAAC;AAClE,CAAC","ignoreList":[]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
3
  import GameEngine from "./GameEngine.js";
4
- import { configure, pause, resume, spawn, despawn, setPosition, setVelocity } from "./GameMethods.js";
5
- export { GameEngine, configure, pause, resume, spawn, despawn, setPosition, setVelocity };
4
+ import { configure, pause, resume, spawn, despawn, update } from "./GameMethods.js";
5
+ export { GameEngine, configure, pause, resume, spawn, despawn, update };
6
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["GameEngine","configure","pause","resume","spawn","despawn","setPosition","setVelocity"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,UAAU,MAAM,iBAAc;AACrC,SACEC,SAAS,EACTC,KAAK,EACLC,MAAM,EACNC,KAAK,EACLC,OAAO,EACPC,WAAW,EACXC,WAAW,QACN,kBAAe;AAEtB,SACEP,UAAU,EACVC,SAAS,EACTC,KAAK,EACLC,MAAM,EACNC,KAAK,EACLC,OAAO,EACPC,WAAW,EACXC,WAAW","ignoreList":[]}
1
+ {"version":3,"names":["GameEngine","configure","pause","resume","spawn","despawn","update"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,UAAU,MAAM,iBAAc;AACrC,SACEC,SAAS,EACTC,KAAK,EACLC,MAAM,EACNC,KAAK,EACLC,OAAO,EACPC,MAAM,QACD,kBAAe;AAEtB,SAASN,UAAU,EAAEC,SAAS,EAAEC,KAAK,EAAEC,MAAM,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM","ignoreList":[]}
@@ -1,4 +1,4 @@
1
- import type { Config, Entity } from './types';
1
+ import type { Config, Entity, EntityUpdate } from './types';
2
2
  /** Sets up the game engine with the given configuration. Call this before anything else. */
3
3
  export declare function configure({ tickRate, world, entities, systems, paused, }: Config): void;
4
4
  /** Pauses the game loop. Systems will stop running. */
@@ -9,8 +9,6 @@ export declare const resume: () => void;
9
9
  export declare const spawn: (entities: Entity | Entity[]) => void;
10
10
  /** Removes an entity or all entities matching the given id prefix from the world. */
11
11
  export declare const despawn: (id: string) => void;
12
- /** Sets the position of the entity with the exact given id. */
13
- export declare const setPosition: (id: string, px: number, py: number) => void;
14
- /** Sets the velocity of all entities matching the given id or prefix. */
15
- export declare const setVelocity: (id: string, vx: number, vy: number) => void;
12
+ /** Updates one or more entities. Only the provided fields are changed. */
13
+ export declare const update: (updates: EntityUpdate | EntityUpdate[]) => void;
16
14
  //# sourceMappingURL=GameMethods.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GameMethods.d.ts","sourceRoot":"","sources":["../../../src/GameMethods.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAI9C,4FAA4F;AAC5F,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,KAAK,EACL,QAAa,EACb,OAAY,EACZ,MAAa,GACd,EAAE,MAAM,QAUR;AAED,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,SAEhD,CAAC;AAEF,qFAAqF;AACrF,eAAO,MAAM,OAAO,GAAI,IAAI,MAAM,SAA4B,CAAC;AAE/D,+DAA+D;AAC/D,eAAO,MAAM,WAAW,GAAI,IAAI,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,MAAM,SAChC,CAAC;AAE/B,yEAAyE;AACzE,eAAO,MAAM,WAAW,GAAI,IAAI,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,MAAM,SAChC,CAAC"}
1
+ {"version":3,"file":"GameMethods.d.ts","sourceRoot":"","sources":["../../../src/GameMethods.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI5D,4FAA4F;AAC5F,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,KAAK,EACL,QAAa,EACb,OAAY,EACZ,MAAa,GACd,EAAE,MAAM,QAUR;AAED,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,SAEhD,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,SAE5D,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { HybridObject } from 'react-native-nitro-modules';
2
- import type { Entity, System, World } from './types';
2
+ import type { Entity, EntityUpdate, System, World } from './types';
3
3
  export interface GameMethods extends HybridObject<{
4
4
  ios: 'c++';
5
5
  android: 'c++';
@@ -12,7 +12,6 @@ export interface GameMethods extends HybridObject<{
12
12
  resume(): void;
13
13
  spawn(entities: Entity[]): void;
14
14
  despawn(id: string): void;
15
- setP(id: string, px: number, py: number): void;
16
- setV(id: string, vx: number, vy: number): void;
15
+ update(updates: EntityUpdate[]): void;
17
16
  }
18
17
  //# sourceMappingURL=GameMethods.nitro.d.ts.map
@@ -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,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErD,MAAM,WAAW,WAAY,SAAQ,YAAY,CAAC;IAChD,GAAG,EAAE,KAAK,CAAC;IACX,OAAO,EAAE,KAAK,CAAC;CAChB,CAAC;IACA,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC7B,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,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/C,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CAChD"}
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,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEnE,MAAM,WAAW,WAAY,SAAQ,YAAY,CAAC;IAChD,GAAG,EAAE,KAAK,CAAC;IACX,OAAO,EAAE,KAAK,CAAC;CAChB,CAAC;IACA,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC7B,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"}
@@ -1,4 +1,4 @@
1
1
  import GameEngine from './GameEngine';
2
- import { configure, pause, resume, spawn, despawn, setPosition, setVelocity } from './GameMethods';
3
- export { GameEngine, configure, pause, resume, spawn, despawn, setPosition, setVelocity, };
2
+ import { configure, pause, resume, spawn, despawn, update } from './GameMethods';
3
+ export { GameEngine, configure, pause, resume, spawn, despawn, update };
4
4
  //# 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;AACtC,OAAO,EACL,SAAS,EACT,KAAK,EACL,MAAM,EACN,KAAK,EACL,OAAO,EACP,WAAW,EACX,WAAW,EACZ,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,UAAU,EACV,SAAS,EACT,KAAK,EACL,MAAM,EACN,KAAK,EACL,OAAO,EACP,WAAW,EACX,WAAW,GACZ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,cAAc,CAAC;AACtC,OAAO,EACL,SAAS,EACT,KAAK,EACL,MAAM,EACN,KAAK,EACL,OAAO,EACP,MAAM,EACP,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC"}
@@ -20,9 +20,9 @@ export type Entity = {
20
20
  /** Fill color as a hex string e.g. `'#00ff00'`. */
21
21
  color: string;
22
22
  /** Velocity on the X axis in game units per second. */
23
- vx: number;
23
+ vx?: number;
24
24
  /** Velocity on the Y axis in game units per second. */
25
- vy: number;
25
+ vy?: number;
26
26
  };
27
27
  export type System = {
28
28
  /** Entity ids or prefixes this system subscribes to. */
@@ -30,6 +30,24 @@ export type System = {
30
30
  /** Called every tick with the resolved entities. */
31
31
  onTick: (entities: Entity[]) => void;
32
32
  };
33
+ export type EntityUpdate = {
34
+ /** Unique identifier or prefix of the entities to update. */
35
+ id: string;
36
+ /** X position in game units. */
37
+ px?: number;
38
+ /** Y position in game units. */
39
+ py?: number;
40
+ /** Width in game units. */
41
+ width?: number;
42
+ /** Height in game units. */
43
+ height?: number;
44
+ /** Fill color as a hex string e.g. `'#00ff00'`. */
45
+ color?: string;
46
+ /** Velocity on the X axis in game units per second. */
47
+ vx?: number;
48
+ /** Velocity on the Y axis in game units per second. */
49
+ vy?: number;
50
+ };
33
51
  export type Config = {
34
52
  /** Number of game logic updates per second. */
35
53
  tickRate: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,GAAG;IAClB,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,oFAAoF;IACpF,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,EAAE,EAAE,MAAM,CAAC;IACX,uDAAuD;IACvD,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,wDAAwD;IACxD,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,oDAAoD;IACpD,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,KAAK,EAAE,KAAK,CAAC;IACb,iCAAiC;IACjC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,iDAAiD;IACjD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,GAAG;IAClB,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,oFAAoF;IACpF,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,wDAAwD;IACxD,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,oDAAoD;IACpD,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,gCAAgC;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,KAAK,EAAE,KAAK,CAAC;IACb,iCAAiC;IACjC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,iDAAiD;IACjD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC"}
@@ -31,6 +31,7 @@
31
31
 
32
32
 
33
33
  #include <string>
34
+ #include <optional>
34
35
 
35
36
  namespace margelo::nitro::rngine {
36
37
 
@@ -45,12 +46,12 @@ namespace margelo::nitro::rngine {
45
46
  double width SWIFT_PRIVATE;
46
47
  double height SWIFT_PRIVATE;
47
48
  std::string color SWIFT_PRIVATE;
48
- double vx SWIFT_PRIVATE;
49
- double vy SWIFT_PRIVATE;
49
+ std::optional<double> vx SWIFT_PRIVATE;
50
+ std::optional<double> vy SWIFT_PRIVATE;
50
51
 
51
52
  public:
52
53
  Entity() = default;
53
- explicit Entity(std::string id, double px, double py, double width, double height, std::string color, double vx, double vy): id(id), px(px), py(py), width(width), height(height), color(color), vx(vx), vy(vy) {}
54
+ explicit Entity(std::string id, double px, double py, double width, double height, std::string color, std::optional<double> vx, std::optional<double> vy): id(id), px(px), py(py), width(width), height(height), color(color), vx(vx), vy(vy) {}
54
55
 
55
56
  public:
56
57
  friend bool operator==(const Entity& lhs, const Entity& rhs) = default;
@@ -72,8 +73,8 @@ namespace margelo::nitro {
72
73
  JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width"))),
73
74
  JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height"))),
74
75
  JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "color"))),
75
- JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vx"))),
76
- JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vy")))
76
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vx"))),
77
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vy")))
77
78
  );
78
79
  }
79
80
  static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::rngine::Entity& arg) {
@@ -84,8 +85,8 @@ namespace margelo::nitro {
84
85
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "width"), JSIConverter<double>::toJSI(runtime, arg.width));
85
86
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "height"), JSIConverter<double>::toJSI(runtime, arg.height));
86
87
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "color"), JSIConverter<std::string>::toJSI(runtime, arg.color));
87
- obj.setProperty(runtime, PropNameIDCache::get(runtime, "vx"), JSIConverter<double>::toJSI(runtime, arg.vx));
88
- obj.setProperty(runtime, PropNameIDCache::get(runtime, "vy"), JSIConverter<double>::toJSI(runtime, arg.vy));
88
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "vx"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.vx));
89
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "vy"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.vy));
89
90
  return obj;
90
91
  }
91
92
  static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
@@ -102,8 +103,8 @@ namespace margelo::nitro {
102
103
  if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width")))) return false;
103
104
  if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height")))) return false;
104
105
  if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "color")))) return false;
105
- if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vx")))) return false;
106
- if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vy")))) return false;
106
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vx")))) return false;
107
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vy")))) return false;
107
108
  return true;
108
109
  }
109
110
  };
@@ -0,0 +1,112 @@
1
+ ///
2
+ /// EntityUpdate.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 <string>
34
+ #include <optional>
35
+
36
+ namespace margelo::nitro::rngine {
37
+
38
+ /**
39
+ * A struct which can be represented as a JavaScript object (EntityUpdate).
40
+ */
41
+ struct EntityUpdate final {
42
+ public:
43
+ std::string id SWIFT_PRIVATE;
44
+ std::optional<double> px SWIFT_PRIVATE;
45
+ std::optional<double> py SWIFT_PRIVATE;
46
+ std::optional<double> width SWIFT_PRIVATE;
47
+ std::optional<double> height SWIFT_PRIVATE;
48
+ std::optional<std::string> color SWIFT_PRIVATE;
49
+ std::optional<double> vx SWIFT_PRIVATE;
50
+ std::optional<double> vy SWIFT_PRIVATE;
51
+
52
+ public:
53
+ EntityUpdate() = default;
54
+ explicit EntityUpdate(std::string id, std::optional<double> px, std::optional<double> py, std::optional<double> width, std::optional<double> height, std::optional<std::string> color, std::optional<double> vx, std::optional<double> vy): id(id), px(px), py(py), width(width), height(height), color(color), vx(vx), vy(vy) {}
55
+
56
+ public:
57
+ friend bool operator==(const EntityUpdate& lhs, const EntityUpdate& rhs) = default;
58
+ };
59
+
60
+ } // namespace margelo::nitro::rngine
61
+
62
+ namespace margelo::nitro {
63
+
64
+ // C++ EntityUpdate <> JS EntityUpdate (object)
65
+ template <>
66
+ struct JSIConverter<margelo::nitro::rngine::EntityUpdate> final {
67
+ static inline margelo::nitro::rngine::EntityUpdate fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
68
+ jsi::Object obj = arg.asObject(runtime);
69
+ return margelo::nitro::rngine::EntityUpdate(
70
+ JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "id"))),
71
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "px"))),
72
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "py"))),
73
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width"))),
74
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height"))),
75
+ JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "color"))),
76
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vx"))),
77
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vy")))
78
+ );
79
+ }
80
+ static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::rngine::EntityUpdate& arg) {
81
+ jsi::Object obj(runtime);
82
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "id"), JSIConverter<std::string>::toJSI(runtime, arg.id));
83
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "px"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.px));
84
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "py"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.py));
85
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "width"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.width));
86
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "height"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.height));
87
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "color"), JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.color));
88
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "vx"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.vx));
89
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "vy"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.vy));
90
+ return obj;
91
+ }
92
+ static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
93
+ if (!value.isObject()) {
94
+ return false;
95
+ }
96
+ jsi::Object obj = value.getObject(runtime);
97
+ if (!nitro::isPlainObject(runtime, obj)) {
98
+ return false;
99
+ }
100
+ if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "id")))) return false;
101
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "px")))) return false;
102
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "py")))) return false;
103
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width")))) return false;
104
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height")))) return false;
105
+ if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "color")))) return false;
106
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vx")))) return false;
107
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vy")))) return false;
108
+ return true;
109
+ }
110
+ };
111
+
112
+ } // namespace margelo::nitro
@@ -22,8 +22,7 @@ namespace margelo::nitro::rngine {
22
22
  prototype.registerHybridMethod("resume", &HybridGameMethodsSpec::resume);
23
23
  prototype.registerHybridMethod("spawn", &HybridGameMethodsSpec::spawn);
24
24
  prototype.registerHybridMethod("despawn", &HybridGameMethodsSpec::despawn);
25
- prototype.registerHybridMethod("setP", &HybridGameMethodsSpec::setP);
26
- prototype.registerHybridMethod("setV", &HybridGameMethodsSpec::setV);
25
+ prototype.registerHybridMethod("update", &HybridGameMethodsSpec::update);
27
26
  });
28
27
  }
29
28
 
@@ -19,12 +19,15 @@ namespace margelo::nitro::rngine { struct World; }
19
19
  namespace margelo::nitro::rngine { struct Entity; }
20
20
  // Forward declaration of `System` to properly resolve imports.
21
21
  namespace margelo::nitro::rngine { struct System; }
22
+ // Forward declaration of `EntityUpdate` to properly resolve imports.
23
+ namespace margelo::nitro::rngine { struct EntityUpdate; }
22
24
 
23
25
  #include "World.hpp"
24
26
  #include "Entity.hpp"
25
27
  #include <vector>
26
28
  #include "System.hpp"
27
29
  #include <string>
30
+ #include "EntityUpdate.hpp"
28
31
 
29
32
  namespace margelo::nitro::rngine {
30
33
 
@@ -65,8 +68,7 @@ namespace margelo::nitro::rngine {
65
68
  virtual void resume() = 0;
66
69
  virtual void spawn(const std::vector<Entity>& entities) = 0;
67
70
  virtual void despawn(const std::string& id) = 0;
68
- virtual void setP(const std::string& id, double px, double py) = 0;
69
- virtual void setV(const std::string& id, double vx, double vy) = 0;
71
+ virtual void update(const std::vector<EntityUpdate>& updates) = 0;
70
72
 
71
73
  protected:
72
74
  // Hybrid Setup
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rngine",
3
- "version": "0.2.1",
4
- "description": "React native library for building 2d games",
3
+ "version": "0.3.0",
4
+ "description": "React Native 2D game engine powered by Nitro Modules",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
7
7
  "exports": {
@@ -64,12 +64,11 @@ std::vector<Rect> GameLoop::getRectsSnapshot() {
64
64
  continue;
65
65
  }
66
66
 
67
- rects.push_back(
68
- {std::clamp(entity.px, 0.0, _world.width),
69
- std::clamp(entity.px + entity.width, 0.0, _world.width),
70
- std::clamp(entity.py, 0.0, _world.height),
71
- std::clamp(entity.py + entity.height, 0.0, _world.height),
72
- parseHexColor(entity.color)});
67
+ rects.push_back({std::clamp(entity.px, 0.0, _world.width),
68
+ std::clamp(entity.px + entity.width, 0.0, _world.width),
69
+ std::clamp(entity.py, 0.0, _world.height),
70
+ std::clamp(entity.py + entity.height, 0.0, _world.height),
71
+ parseHexColor(entity.color)});
73
72
  }
74
73
  return rects;
75
74
  }
@@ -154,8 +153,12 @@ void GameLoop::updateEntities(double deltaTime) {
154
153
  std::lock_guard<std::mutex> lock(_mutex);
155
154
 
156
155
  for (auto &[id, entity] : _entities) {
157
- entity.px += entity.vx * deltaTime;
158
- entity.py += entity.vy * deltaTime;
156
+ if (entity.vx) {
157
+ entity.px += *entity.vx * deltaTime;
158
+ }
159
+ if (entity.vy) {
160
+ entity.py += *entity.vy * deltaTime;
161
+ }
159
162
  }
160
163
  }
161
164
  } // namespace margelo::nitro::rngine
@@ -1,4 +1,5 @@
1
1
  #include "GameMethods.hpp"
2
+ #include "EntityUpdate.hpp"
2
3
  #include "GameLoop.hpp"
3
4
  #include <android/log.h>
4
5
 
@@ -99,39 +100,39 @@ void GameMethods::despawn(const std::string &id) {
99
100
  }
100
101
  }
101
102
 
102
- void GameMethods::setP(const std::string &id, double px, double py) {
103
+ void GameMethods::update(const std::vector<EntityUpdate> &updates) {
103
104
  auto &instance = GameLoop::getInstance();
104
105
  std::lock_guard<std::mutex> lock(instance.getMutexInternal());
105
- auto &entitiesInternal = instance.getEntitiesInternal();
106
- auto it = entitiesInternal.find(id);
107
-
108
- if (it == entitiesInternal.end()) {
109
- __android_log_print(ANDROID_LOG_WARN, "GameMethods",
110
- "setP: entity not found for id=%s", id.c_str());
111
- return;
112
- }
113
- __android_log_print(ANDROID_LOG_INFO, "GameMethods",
114
- "setP: entity found, setting px=%f py=%f", px, py);
115
- it->second.px = px;
116
- it->second.py = py;
117
- }
106
+ for (const auto &update : updates) {
107
+ auto resolvedEntitiesInternals =
108
+ instance.resolveEntitiesInternal(update.id);
109
+ if (resolvedEntitiesInternals.empty()) {
110
+ __android_log_print(ANDROID_LOG_WARN, "GameMethods",
111
+ "update: no entity found for id=%s",
112
+ update.id.c_str());
113
+ continue;
114
+ }
118
115
 
119
- void GameMethods::setV(const std::string &id, double vx, double vy) {
120
- auto &instance = GameLoop::getInstance();
121
- std::lock_guard<std::mutex> lock(instance.getMutexInternal());
122
- auto resolvedEntitiesInternals = instance.resolveEntitiesInternal(id);
116
+ for (auto *entity : resolvedEntitiesInternals) {
117
+ if (update.px.has_value())
118
+ entity->px = update.px.value();
119
+ if (update.py.has_value())
120
+ entity->py = update.py.value();
121
+ if (update.width.has_value())
122
+ entity->width = update.width.value();
123
+ if (update.height.has_value())
124
+ entity->height = update.height.value();
125
+ if (update.color.has_value())
126
+ entity->color = update.color.value();
127
+ if (update.vx.has_value())
128
+ entity->vx = update.vx.value();
129
+ if (update.vy.has_value())
130
+ entity->vy = update.vy.value();
131
+ }
123
132
 
124
- if (resolvedEntitiesInternals.empty()) {
125
- __android_log_print(ANDROID_LOG_WARN, "GameMethods",
126
- "setV: entity not found for id=%s", id.c_str());
127
- return;
128
- }
129
- for (auto *entity : resolvedEntitiesInternals) {
130
- entity->vx = vx;
131
- entity->vy = vy;
133
+ __android_log_print(ANDROID_LOG_INFO, "GameMethods",
134
+ "update: patched %zu entities for id=%s",
135
+ resolvedEntitiesInternals.size(), update.id.c_str());
132
136
  }
133
- __android_log_print(ANDROID_LOG_INFO, "GameMethods",
134
- "setV: set vx=%f vy=%f for %zu entities matching id=%s",
135
- vx, vy, resolvedEntitiesInternals.size(), id.c_str());
136
137
  }
137
138
  } // namespace margelo::nitro::rngine
@@ -14,7 +14,6 @@ public:
14
14
  void resume() override;
15
15
  void spawn(const std::vector<Entity> &entities) override;
16
16
  void despawn(const std::string &id) override;
17
- void setP(const std::string &id, double px, double py) override;
18
- void setV(const std::string &id, double vx, double vy) override;
17
+ void update(const std::vector<EntityUpdate> &updates) override;
19
18
  };
20
19
  } // namespace margelo::nitro::rngine
@@ -1,5 +1,5 @@
1
1
  import type { HybridObject } from 'react-native-nitro-modules';
2
- import type { Entity, System, World } from './types';
2
+ import type { Entity, EntityUpdate, System, World } from './types';
3
3
 
4
4
  export interface GameMethods extends HybridObject<{
5
5
  ios: 'c++';
@@ -13,6 +13,5 @@ export interface GameMethods extends HybridObject<{
13
13
  resume(): void;
14
14
  spawn(entities: Entity[]): void;
15
15
  despawn(id: string): void;
16
- setP(id: string, px: number, py: number): void;
17
- setV(id: string, vx: number, vy: number): void;
16
+ update(updates: EntityUpdate[]): void;
18
17
  }
@@ -1,6 +1,6 @@
1
1
  import { NitroModules } from 'react-native-nitro-modules';
2
2
  import type { GameMethods } from './GameMethods.nitro';
3
- import type { Config, Entity } from './types';
3
+ import type { Config, Entity, EntityUpdate } from './types';
4
4
 
5
5
  const gameMethods = NitroModules.createHybridObject<GameMethods>('GameMethods');
6
6
 
@@ -37,10 +37,7 @@ export const spawn = (entities: Entity | Entity[]) => {
37
37
  /** Removes an entity or all entities matching the given id prefix from the world. */
38
38
  export const despawn = (id: string) => gameMethods.despawn(id);
39
39
 
40
- /** Sets the position of the entity with the exact given id. */
41
- export const setPosition = (id: string, px: number, py: number) =>
42
- gameMethods.setP(id, px, py);
43
-
44
- /** Sets the velocity of all entities matching the given id or prefix. */
45
- export const setVelocity = (id: string, vx: number, vy: number) =>
46
- gameMethods.setV(id, vx, vy);
40
+ /** Updates one or more entities. Only the provided fields are changed. */
41
+ export const update = (updates: EntityUpdate | EntityUpdate[]) => {
42
+ gameMethods.update(Array.isArray(updates) ? updates : [updates]);
43
+ };
package/src/index.tsx CHANGED
@@ -5,17 +5,7 @@ import {
5
5
  resume,
6
6
  spawn,
7
7
  despawn,
8
- setPosition,
9
- setVelocity,
8
+ update,
10
9
  } from './GameMethods';
11
10
 
12
- export {
13
- GameEngine,
14
- configure,
15
- pause,
16
- resume,
17
- spawn,
18
- despawn,
19
- setPosition,
20
- setVelocity,
21
- };
11
+ export { GameEngine, configure, pause, resume, spawn, despawn, update };
package/src/types.ts CHANGED
@@ -21,9 +21,9 @@ export type Entity = {
21
21
  /** Fill color as a hex string e.g. `'#00ff00'`. */
22
22
  color: string;
23
23
  /** Velocity on the X axis in game units per second. */
24
- vx: number;
24
+ vx?: number;
25
25
  /** Velocity on the Y axis in game units per second. */
26
- vy: number;
26
+ vy?: number;
27
27
  };
28
28
 
29
29
  export type System = {
@@ -33,6 +33,25 @@ export type System = {
33
33
  onTick: (entities: Entity[]) => void;
34
34
  };
35
35
 
36
+ export type EntityUpdate = {
37
+ /** Unique identifier or prefix of the entities to update. */
38
+ id: string;
39
+ /** X position in game units. */
40
+ px?: number;
41
+ /** Y position in game units. */
42
+ py?: number;
43
+ /** Width in game units. */
44
+ width?: number;
45
+ /** Height in game units. */
46
+ height?: number;
47
+ /** Fill color as a hex string e.g. `'#00ff00'`. */
48
+ color?: string;
49
+ /** Velocity on the X axis in game units per second. */
50
+ vx?: number;
51
+ /** Velocity on the Y axis in game units per second. */
52
+ vy?: number;
53
+ };
54
+
36
55
  export type Config = {
37
56
  /** Number of game logic updates per second. */
38
57
  tickRate: number;