@rpgjs/common 5.0.0-alpha.1 → 5.0.0-alpha.11

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/dist/Physic.d.ts CHANGED
@@ -136,11 +136,29 @@ export declare class RpgCommonPhysic {
136
136
  *
137
137
  * @example
138
138
  * ```ts
139
- * // Add a wall
139
+ * // Add a rectangular wall
140
140
  * physic.addStaticHitbox('wall1', 100, 50, 32, 128);
141
141
  * ```
142
142
  */
143
143
  addStaticHitbox(id: string, x: number, y: number, width: number, height: number): string;
144
+ /**
145
+ * Add a static hitbox with polygon shape (immovable objects like walls, obstacles)
146
+ *
147
+ * @param id - Unique identifier for the hitbox
148
+ * @param points - Array of 2D points [[x1, y1], [x2, y2], ...] to create a polygon
149
+ * @returns The id of the created hitbox
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * // Add a triangular obstacle
154
+ * physic.addStaticHitbox('triangle1', [
155
+ * [100, 100],
156
+ * [150, 50],
157
+ * [200, 100]
158
+ * ]);
159
+ * ```
160
+ */
161
+ addStaticHitbox(id: string, points: number[][]): string;
144
162
  /**
145
163
  * Add a movable hitbox (players, NPCs, dynamic objects)
146
164
  *
@@ -425,6 +443,40 @@ export declare class RpgCommonPhysic {
425
443
  * ```
426
444
  */
427
445
  getWorld(): Matter.World;
446
+ /**
447
+ * Get debug information about all hitboxes
448
+ *
449
+ * Useful for debugging collision issues
450
+ *
451
+ * @returns Array of hitbox debug information
452
+ *
453
+ * @example
454
+ * ```ts
455
+ * // Debug all hitboxes
456
+ * const info = physic.getDebugInfo();
457
+ * console.log('All hitboxes:', info);
458
+ * ```
459
+ */
460
+ getDebugInfo(): Array<{
461
+ id: string;
462
+ type: 'static' | 'movable';
463
+ position: {
464
+ x: number;
465
+ y: number;
466
+ };
467
+ bounds: {
468
+ min: {
469
+ x: number;
470
+ y: number;
471
+ };
472
+ max: {
473
+ x: number;
474
+ y: number;
475
+ };
476
+ };
477
+ verticesCount: number;
478
+ isPolygon: boolean;
479
+ }>;
428
480
  /**
429
481
  * Create a new Zone sensor. Never collides physically but triggers events.
430
482
  *
package/dist/Player.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Item } from './database';
2
2
  import { Observable } from 'rxjs';
3
- import * as Matter from 'matter-js';
3
+ import { Constructor } from './Utils';
4
+ import * as Matter from "matter-js";
4
5
  export declare enum Direction {
5
6
  Up = "up",
6
7
  Down = "down",
@@ -37,14 +38,16 @@ export interface AttachShapeOptions {
37
38
  /** If true, walls (static hitboxes) stop vision */
38
39
  limitedByWalls?: boolean;
39
40
  /** Indicate where the shape is placed relative to the player */
40
- positioning?: 'center' | 'top' | 'bottom' | 'left' | 'right';
41
+ positioning?: "center" | "top" | "bottom" | "left" | "right";
41
42
  /** The name of the shape */
42
43
  name?: string;
43
44
  /** An object to retrieve information when interacting with the shape */
44
45
  properties?: object;
45
46
  }
46
- export declare class RpgCommonPlayer {
47
+ export declare abstract class RpgCommonPlayer {
47
48
  id: string;
49
+ name: import('@signe/reactive').WritableSignal<string>;
50
+ type: import('@signe/reactive').WritableSignal<string>;
48
51
  x: import('@signe/reactive').WritableSignal<number>;
49
52
  y: import('@signe/reactive').WritableSignal<number>;
50
53
  z: import('@signe/reactive').WritableSignal<number>;
@@ -56,8 +59,8 @@ export declare class RpgCommonPlayer {
56
59
  hitbox: import('@signe/reactive').WritableObjectSignal<Hitbox>;
57
60
  _gold: import('@signe/reactive').WritableSignal<number>;
58
61
  animationName: import('@signe/reactive').WritableSignal<string>;
59
- _hp: import('@signe/reactive').WritableSignal<number>;
60
- _sp: import('@signe/reactive').WritableSignal<number>;
62
+ hpSignal: import('@signe/reactive').WritableSignal<number>;
63
+ spSignal: import('@signe/reactive').WritableSignal<number>;
61
64
  _exp: import('@signe/reactive').WritableSignal<number>;
62
65
  _level: import('@signe/reactive').WritableSignal<number>;
63
66
  _class: import('@signe/reactive').WritableObjectSignal<{}>;
@@ -152,6 +155,36 @@ export declare class RpgCommonPlayer {
152
155
  * ```
153
156
  */
154
157
  applyPhysic(body: Matter.Body): void;
158
+ abstract setAnimation(animationName: string, nbTimes: number): void;
159
+ abstract showComponentAnimation(id: string, params: any): void;
160
+ /**
161
+ * Display a spritesheet animation on the player
162
+ *
163
+ * This method displays a temporary visual animation using a spritesheet.
164
+ * The animation can either be displayed as an overlay on the player or replace
165
+ * the player's current graphic temporarily. This is useful for spell effects,
166
+ * transformations, or other visual feedback that uses predefined spritesheets.
167
+ *
168
+ * @param graphic - The ID of the spritesheet to use for the animation
169
+ * @param animationName - The name of the animation within the spritesheet (default: 'default')
170
+ * @param replaceGraphic - Whether to replace the player's sprite with the animation (default: false)
171
+ *
172
+ * @example
173
+ * ```ts
174
+ * // Show explosion animation as overlay on player
175
+ * player.showAnimation("explosion");
176
+ *
177
+ * // Show specific spell effect animation
178
+ * player.showAnimation("spell-effects", "fireball");
179
+ *
180
+ * // Transform player graphic temporarily with animation
181
+ * player.showAnimation("transformation", "werewolf", true);
182
+ *
183
+ * // Show healing effect on player
184
+ * player.showAnimation("healing-effects", "holy-light");
185
+ * ```
186
+ */
187
+ showAnimation(graphic: string, animationName?: string, replaceGraphic?: boolean): void;
155
188
  _showAnimation(params: ShowAnimationParams): void;
156
189
  /**
157
190
  * Create a temporary and moving hitbox relative to the player's position
@@ -195,4 +228,7 @@ export declare class RpgCommonPlayer {
195
228
  speed?: number;
196
229
  }): Observable<any[]>;
197
230
  getCurrentMap(): any;
231
+ get hp(): number;
232
+ get sp(): number;
198
233
  }
234
+ export type PlayerCtor<T extends RpgCommonPlayer = RpgCommonPlayer> = Constructor<T>;
package/dist/index.d.ts CHANGED
@@ -7,3 +7,4 @@ export * from './PrebuiltGui';
7
7
  export * from './movement';
8
8
  export * as Matter from 'matter-js';
9
9
  export * from './database';
10
+ export * from './Physic';
package/dist/index.js CHANGED
@@ -2275,6 +2275,8 @@ var Animation = /* @__PURE__ */ ((Animation2) => {
2275
2275
  })(Animation || {});
2276
2276
  class RpgCommonPlayer {
2277
2277
  constructor() {
2278
+ this.name = signal("");
2279
+ this.type = signal("");
2278
2280
  this.x = signal(0);
2279
2281
  this.y = signal(0);
2280
2282
  this.z = signal(0);
@@ -2289,8 +2291,8 @@ class RpgCommonPlayer {
2289
2291
  });
2290
2292
  this._gold = signal(0);
2291
2293
  this.animationName = signal("stand");
2292
- this._hp = signal(0);
2293
- this._sp = signal(0);
2294
+ this.hpSignal = signal(0);
2295
+ this.spSignal = signal(0);
2294
2296
  this._exp = signal(0);
2295
2297
  this._level = signal(0);
2296
2298
  this._class = signal({});
@@ -2308,14 +2310,14 @@ class RpgCommonPlayer {
2308
2310
  }
2309
2311
  /**
2310
2312
  * Change the player's facing direction
2311
- *
2313
+ *
2312
2314
  * Updates the direction the player is facing, which affects animations
2313
2315
  * and directional abilities. This should be called when the player
2314
2316
  * intends to move in a specific direction, not when they are pushed
2315
2317
  * by physics or sliding.
2316
- *
2318
+ *
2317
2319
  * @param direction - The new direction to face
2318
- *
2320
+ *
2319
2321
  * @example
2320
2322
  * ```ts
2321
2323
  * // Player presses right arrow key
@@ -2327,9 +2329,9 @@ class RpgCommonPlayer {
2327
2329
  }
2328
2330
  /**
2329
2331
  * Get the current facing direction
2330
- *
2332
+ *
2331
2333
  * @returns Current direction the player is facing
2332
- *
2334
+ *
2333
2335
  * @example
2334
2336
  * ```ts
2335
2337
  * const currentDirection = player.getDirection();
@@ -2343,18 +2345,18 @@ class RpgCommonPlayer {
2343
2345
  }
2344
2346
  /**
2345
2347
  * Set the intended movement direction
2346
- *
2348
+ *
2347
2349
  * This should be called when the player intends to move in a direction,
2348
2350
  * typically from input handling. This direction will be used to update
2349
2351
  * the player's facing direction regardless of physics interactions.
2350
- *
2352
+ *
2351
2353
  * @param direction - The intended movement direction, or null if not moving
2352
- *
2354
+ *
2353
2355
  * @example
2354
2356
  * ```ts
2355
2357
  * // Player presses down arrow key
2356
2358
  * player.setIntendedDirection(Direction.Down);
2357
- *
2359
+ *
2358
2360
  * // Player releases all movement keys
2359
2361
  * player.setIntendedDirection(null);
2360
2362
  * ```
@@ -2367,9 +2369,9 @@ class RpgCommonPlayer {
2367
2369
  }
2368
2370
  /**
2369
2371
  * Get the intended movement direction
2370
- *
2372
+ *
2371
2373
  * @returns The direction the player intends to move, or null if not moving
2372
- *
2374
+ *
2373
2375
  * @example
2374
2376
  * ```ts
2375
2377
  * const intended = player.getIntendedDirection();
@@ -2383,14 +2385,14 @@ class RpgCommonPlayer {
2383
2385
  }
2384
2386
  /**
2385
2387
  * Apply physics body position to player coordinates
2386
- *
2388
+ *
2387
2389
  * Synchronizes the player's position with their physics body after
2388
2390
  * physics calculations. This method no longer automatically changes
2389
2391
  * the player's direction based on position changes, as direction
2390
2392
  * should be controlled by intended movement instead.
2391
- *
2393
+ *
2392
2394
  * @param body - The Matter.js physics body
2393
- *
2395
+ *
2394
2396
  * @example
2395
2397
  * ```ts
2396
2398
  * // Called automatically by physics system
@@ -2408,6 +2410,43 @@ class RpgCommonPlayer {
2408
2410
  this.y.set(topLeftY);
2409
2411
  }
2410
2412
  }
2413
+ /**
2414
+ * Display a spritesheet animation on the player
2415
+ *
2416
+ * This method displays a temporary visual animation using a spritesheet.
2417
+ * The animation can either be displayed as an overlay on the player or replace
2418
+ * the player's current graphic temporarily. This is useful for spell effects,
2419
+ * transformations, or other visual feedback that uses predefined spritesheets.
2420
+ *
2421
+ * @param graphic - The ID of the spritesheet to use for the animation
2422
+ * @param animationName - The name of the animation within the spritesheet (default: 'default')
2423
+ * @param replaceGraphic - Whether to replace the player's sprite with the animation (default: false)
2424
+ *
2425
+ * @example
2426
+ * ```ts
2427
+ * // Show explosion animation as overlay on player
2428
+ * player.showAnimation("explosion");
2429
+ *
2430
+ * // Show specific spell effect animation
2431
+ * player.showAnimation("spell-effects", "fireball");
2432
+ *
2433
+ * // Transform player graphic temporarily with animation
2434
+ * player.showAnimation("transformation", "werewolf", true);
2435
+ *
2436
+ * // Show healing effect on player
2437
+ * player.showAnimation("healing-effects", "holy-light");
2438
+ * ```
2439
+ */
2440
+ showAnimation(graphic, animationName = "default", replaceGraphic = false) {
2441
+ if (replaceGraphic) {
2442
+ this.setAnimation(animationName, 1);
2443
+ return;
2444
+ }
2445
+ this.showComponentAnimation("animation", {
2446
+ graphic,
2447
+ animationName
2448
+ });
2449
+ }
2411
2450
  _showAnimation(params) {
2412
2451
  const { graphic, animationName, loop } = params;
2413
2452
  if (graphic) {
@@ -2420,20 +2459,20 @@ class RpgCommonPlayer {
2420
2459
  }
2421
2460
  /**
2422
2461
  * Create a temporary and moving hitbox relative to the player's position
2423
- *
2462
+ *
2424
2463
  * Creates a temporary hitbox that moves through multiple positions sequentially,
2425
2464
  * with all coordinates being relative to the player's current position.
2426
2465
  * For example, you can use it for player attacks, spells, or area effects
2427
2466
  * that should follow the player's position.
2428
- *
2467
+ *
2429
2468
  * The method creates a zone sensor that moves through the specified hitbox positions
2430
2469
  * at the given speed, detecting collisions with other players and events at each step.
2431
- *
2470
+ *
2432
2471
  * @param hitboxes - Array of hitbox positions relative to player position
2433
2472
  * @param options - Configuration options for the movement
2434
2473
  * @param map - Reference to the map instance for physics access
2435
2474
  * @returns Observable that emits arrays of hit entities and completes when movement is finished
2436
- *
2475
+ *
2437
2476
  * @example
2438
2477
  * ```ts
2439
2478
  * // Create a forward attack relative to player position
@@ -2463,10 +2502,22 @@ class RpgCommonPlayer {
2463
2502
  getCurrentMap() {
2464
2503
  return this["map"];
2465
2504
  }
2505
+ get hp() {
2506
+ return this.hpSignal();
2507
+ }
2508
+ get sp() {
2509
+ return this.spSignal();
2510
+ }
2466
2511
  }
2467
2512
  __decorateClass([
2468
2513
  id()
2469
2514
  ], RpgCommonPlayer.prototype, "id");
2515
+ __decorateClass([
2516
+ sync()
2517
+ ], RpgCommonPlayer.prototype, "name");
2518
+ __decorateClass([
2519
+ sync()
2520
+ ], RpgCommonPlayer.prototype, "type");
2470
2521
  __decorateClass([
2471
2522
  sync()
2472
2523
  ], RpgCommonPlayer.prototype, "x");
@@ -2502,10 +2553,10 @@ __decorateClass([
2502
2553
  ], RpgCommonPlayer.prototype, "animationName");
2503
2554
  __decorateClass([
2504
2555
  sync()
2505
- ], RpgCommonPlayer.prototype, "_hp");
2556
+ ], RpgCommonPlayer.prototype, "hpSignal");
2506
2557
  __decorateClass([
2507
2558
  sync()
2508
- ], RpgCommonPlayer.prototype, "_sp");
2559
+ ], RpgCommonPlayer.prototype, "spSignal");
2509
2560
  __decorateClass([
2510
2561
  sync()
2511
2562
  ], RpgCommonPlayer.prototype, "_exp");
@@ -14079,32 +14130,61 @@ class RpgCommonPhysic {
14079
14130
  return dy > 0 ? Direction.Down : Direction.Up;
14080
14131
  }
14081
14132
  }
14082
- /**
14083
- * Add a static hitbox (immovable objects like walls, obstacles)
14084
- *
14085
- * @param id - Unique identifier for the hitbox
14086
- * @param x - X position
14087
- * @param y - Y position
14088
- * @param width - Width of hitbox
14089
- * @param height - Height of hitbox
14090
- * @returns The id of the created hitbox
14091
- *
14092
- * @example
14093
- * ```ts
14094
- * // Add a wall
14095
- * physic.addStaticHitbox('wall1', 100, 50, 32, 128);
14096
- * ```
14097
- */
14098
- addStaticHitbox(id, x, y, width, height) {
14133
+ addStaticHitbox(id, xOrPoints, y, width, height) {
14099
14134
  if (this.hitboxes.has(id)) {
14100
14135
  throw new Error(`Hitbox with id ${id} already exists`);
14101
14136
  }
14102
- const centerX = x + width / 2;
14103
- const centerY = y + height / 2;
14104
- const body = matterExports.Bodies.rectangle(centerX, centerY, width, height, {
14105
- isStatic: true,
14106
- label: id
14107
- });
14137
+ let body;
14138
+ if (Array.isArray(xOrPoints)) {
14139
+ const points = xOrPoints;
14140
+ if (points.length < 3) {
14141
+ throw new Error(`Polygon must have at least 3 points, got ${points.length}`);
14142
+ }
14143
+ for (let i = 0; i < points.length; i++) {
14144
+ const point = points[i];
14145
+ if (!Array.isArray(point) || point.length !== 2 || typeof point[0] !== "number" || typeof point[1] !== "number") {
14146
+ throw new Error(`Invalid point at index ${i}: ${JSON.stringify(point)}. Expected [x, y] with numbers.`);
14147
+ }
14148
+ }
14149
+ let centerX = 0, centerY = 0;
14150
+ for (const point of points) {
14151
+ centerX += point[0];
14152
+ centerY += point[1];
14153
+ }
14154
+ centerX /= points.length;
14155
+ centerY /= points.length;
14156
+ const vertices = points.map((point) => ({
14157
+ x: point[0] - centerX,
14158
+ y: point[1] - centerY
14159
+ }));
14160
+ try {
14161
+ body = matterExports.Bodies.fromVertices(0, 0, [vertices], {
14162
+ isStatic: true,
14163
+ label: id
14164
+ });
14165
+ if (!body) {
14166
+ throw new Error(`Matter.Bodies.fromVertices returned null/undefined`);
14167
+ }
14168
+ if (!body.vertices || body.vertices.length === 0) {
14169
+ throw new Error(`Created body has no vertices`);
14170
+ }
14171
+ matterExports.Body.setPosition(body, { x: centerX, y: centerY });
14172
+ } catch (error) {
14173
+ const errorMessage = error instanceof Error ? error.message : String(error);
14174
+ throw new Error(`Failed to create polygon body from points ${JSON.stringify(points)}: ${errorMessage}`);
14175
+ }
14176
+ } else {
14177
+ const x = xOrPoints;
14178
+ if (y === void 0 || width === void 0 || height === void 0) {
14179
+ throw new Error("Rectangle hitbox requires x, y, width, and height parameters");
14180
+ }
14181
+ const centerX = x + width / 2;
14182
+ const centerY = y + height / 2;
14183
+ body = matterExports.Bodies.rectangle(centerX, centerY, width, height, {
14184
+ isStatic: true,
14185
+ label: id
14186
+ });
14187
+ }
14108
14188
  matterExports.Composite.add(this.world, body);
14109
14189
  this.hitboxes.set(id, {
14110
14190
  id,
@@ -14688,6 +14768,39 @@ class RpgCommonPhysic {
14688
14768
  getWorld() {
14689
14769
  return this.world;
14690
14770
  }
14771
+ /**
14772
+ * Get debug information about all hitboxes
14773
+ *
14774
+ * Useful for debugging collision issues
14775
+ *
14776
+ * @returns Array of hitbox debug information
14777
+ *
14778
+ * @example
14779
+ * ```ts
14780
+ * // Debug all hitboxes
14781
+ * const info = physic.getDebugInfo();
14782
+ * console.log('All hitboxes:', info);
14783
+ * ```
14784
+ */
14785
+ getDebugInfo() {
14786
+ const info = [];
14787
+ for (const [id, hitboxData] of this.hitboxes.entries()) {
14788
+ const body = hitboxData.body;
14789
+ info.push({
14790
+ id,
14791
+ type: hitboxData.type,
14792
+ position: { x: body.position.x, y: body.position.y },
14793
+ bounds: {
14794
+ min: { x: body.bounds.min.x, y: body.bounds.min.y },
14795
+ max: { x: body.bounds.max.x, y: body.bounds.max.y }
14796
+ },
14797
+ verticesCount: body.vertices.length,
14798
+ isPolygon: body.vertices.length > 4
14799
+ // Rectangles have 4 vertices
14800
+ });
14801
+ }
14802
+ return info;
14803
+ }
14691
14804
  /* ----------------------------------------------------------------------- */
14692
14805
  /* ZONES */
14693
14806
  /* ----------------------------------------------------------------------- */
@@ -16227,7 +16340,11 @@ class RpgCommonMap {
16227
16340
  this.physic.addStaticHitbox("map-height-top", 0, -100, this.data().width, gap);
16228
16341
  this.physic.addStaticHitbox("map-height-bottom", 0, this.data().height, this.data().width, gap);
16229
16342
  for (let staticHitbox of hitboxes) {
16230
- this.physic.addStaticHitbox(staticHitbox.id ?? generateShortUUID(), staticHitbox.x, staticHitbox.y, staticHitbox.width, staticHitbox.height);
16343
+ if ("x" in staticHitbox) {
16344
+ this.physic.addStaticHitbox(staticHitbox.id ?? generateShortUUID(), staticHitbox.x, staticHitbox.y, staticHitbox.width, staticHitbox.height);
16345
+ } else if ("points" in staticHitbox) {
16346
+ this.physic.addStaticHitbox(staticHitbox.id ?? generateShortUUID(), staticHitbox.points);
16347
+ }
16231
16348
  }
16232
16349
  this.events.observable.subscribe(({ value: event, type }) => {
16233
16350
  if (type == "add") {
@@ -16737,5 +16854,5 @@ var PrebuiltGui = /* @__PURE__ */ ((PrebuiltGui2) => {
16737
16854
  return PrebuiltGui2;
16738
16855
  })(PrebuiltGui || {});
16739
16856
 
16740
- export { Animation, CompositeMovement, Dash, Direction, Hooks, IceMovement, Item, Knockback, LinearMove, LinearRepulsion, matter$1 as Matter, ModulesToken, MovementManager, Oscillate, PathFollow, PrebuiltGui, ProjectileMovement, ProjectileType, RpgCommonMap, RpgCommonPlayer, SeekAvoid, UpdateMapService, UpdateMapToken, applyMixins, arrayEquals, arrayFlat, arrayUniq, basename, camelToKebab, capitalize, combineMixins, createConstructor, createModule, defineModule, elementToPositionAbsolute, extractId, findModules, fps2ms, generateUID, hexaToNumber, intersection, isArray, isBrowser, isClass, isFunction, isInstanceOf, isObject, isPromise, isString, mergeObjectWithMethods, preciseNow, provideModules, random, round, set, sharedArrayBuffer, toRadians };
16857
+ export { Animation, CompositeMovement, Dash, Direction, Hooks, IceMovement, Item, Knockback, LinearMove, LinearRepulsion, matter$1 as Matter, ModulesToken, MovementManager, Oscillate, PathFollow, PrebuiltGui, ProjectileMovement, ProjectileType, RpgCommonMap, RpgCommonPhysic, RpgCommonPlayer, SeekAvoid, UpdateMapService, UpdateMapToken, applyMixins, arrayEquals, arrayFlat, arrayUniq, basename, camelToKebab, capitalize, combineMixins, createConstructor, createModule, defineModule, elementToPositionAbsolute, extractId, findModules, fps2ms, generateUID, hexaToNumber, intersection, isArray, isBrowser, isClass, isFunction, isInstanceOf, isObject, isPromise, isString, mergeObjectWithMethods, preciseNow, provideModules, random, round, set, sharedArrayBuffer, toRadians };
16741
16858
  //# sourceMappingURL=index.js.map