@energy8platform/game-engine 0.4.0 → 0.5.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
@@ -51,7 +51,7 @@ npm init -y
51
51
  # Install dependencies
52
52
  npm install pixi.js @energy8platform/game-sdk @energy8platform/game-engine
53
53
 
54
- # Install UI layout dependencies (optional — needed for Layout, Panel, Toast, ScrollContainer)
54
+ # Install UI layout dependencies (optional — needed for Layout, Panel, ScrollContainer)
55
55
  npm install @pixi/ui @pixi/layout yoga-layout
56
56
 
57
57
  # (Optional) install spine and audio support
@@ -124,7 +124,7 @@ bootstrap();
124
124
  | `pixi.js` | `^8.16.0` | Yes |
125
125
  | `@energy8platform/game-sdk` | `^2.6.0` | Yes |
126
126
  | `@pixi/ui` | `^2.3.0` | Optional — for Button, ScrollContainer, ProgressBar |
127
- | `@pixi/layout` | `^3.2.0` | Optional — for Layout, Panel, Toast (Yoga flexbox) |
127
+ | `@pixi/layout` | `^3.2.0` | Optional — for Layout, Panel (Yoga flexbox) |
128
128
  | `yoga-layout` | `^3.0.0` | Optional — peer dep of `@pixi/layout` |
129
129
  | `@pixi/sound` | `^6.0.0` | Optional — for audio |
130
130
  | `@esotericsoftware/spine-pixi-v8` | `~4.2.0` | Optional — for Spine animations |
@@ -707,6 +707,22 @@ console.log(SpineHelper.getAnimationNames(spine));
707
707
  > ```bash
708
708
  > npm install @pixi/ui @pixi/layout yoga-layout
709
709
  > ```
710
+ >
711
+ > **Important:** These packages are optional peer dependencies. Import UI components from the `@energy8platform/game-engine/ui` sub-path to ensure tree-shaking works correctly. The root `@energy8platform/game-engine` barrel re-exports UI components but does **not** activate the `@pixi/layout` mixin — that only happens when importing from `/ui`.
712
+ >
713
+ > **Direct access:** The engine wraps only the most common UI components. For anything else from `@pixi/ui` (e.g. `Slider`, `CheckBox`, `Input`, `Select`, `RadioGroup`, `List`, `DoubleSlider`, `Switcher`) or `@pixi/layout` (e.g. `LayoutContainer`, `LayoutView`, `Trackpad`, layout-aware sprites), import directly from the source package:
714
+ >
715
+ > ```typescript
716
+ > // Engine-wrapped components
717
+ > import { Button, Panel, Layout, ScrollContainer } from '@energy8platform/game-engine/ui';
718
+ >
719
+ > // Raw @pixi/ui components (not wrapped by the engine)
720
+ > import { Slider, CheckBox, Input, Select, RadioGroup } from '@pixi/ui';
721
+ >
722
+ > // Raw @pixi/layout components
723
+ > import { LayoutContainer, LayoutView } from '@pixi/layout/components';
724
+ > import type { LayoutStyles } from '@pixi/layout';
725
+ > ```
710
726
 
711
727
  ### Layout
712
728
 
@@ -776,7 +792,7 @@ const tags = new Layout({
776
792
 
777
793
  **Anchor values:** `top-left`, `top-center`, `top-right`, `center-left`, `center`, `center-right`, `bottom-left`, `bottom-center`, `bottom-right`
778
794
 
779
- > **Under the hood**: Layout maps `direction` → Yoga `flexDirection`/`flexWrap`, `alignment` → `alignItems`, and uses `@pixi/layout`'s `container.layout = { ... }` mixin. Grid mode assigns percentage widths to children.
795
+ > **Under the hood**: Layout maps `direction` → Yoga `flexDirection`/`flexWrap`, `alignment` → `alignItems`, and uses `@pixi/layout`'s `container.layout = { ... }` mixin. Grid mode uses `flexGrow`/`flexBasis` when `gap > 0` to correctly distribute space, and percentage widths when `gap === 0`.
780
796
 
781
797
  ### ScrollContainer
782
798
 
@@ -988,7 +1004,7 @@ await modal.hide();
988
1004
 
989
1005
  ### Toast
990
1006
 
991
- Brief notification messages. Uses `@pixi/layout` `LayoutContainer` for auto-sized background.
1007
+ Brief notification messages with animated appearance/dismissal.
992
1008
 
993
1009
  ```typescript
994
1010
  import { Toast } from '@energy8platform/game-engine';
@@ -1009,6 +1025,48 @@ await toast.dismiss();
1009
1025
 
1010
1026
  ---
1011
1027
 
1028
+ ### Using Raw `@pixi/ui` and `@pixi/layout` Components
1029
+
1030
+ The engine wraps the most common components, but both libraries offer much more. Here are examples of using raw components alongside the engine:
1031
+
1032
+ ```typescript
1033
+ import { Slider, CheckBox, Input, Select } from '@pixi/ui';
1034
+ import { LayoutContainer } from '@pixi/layout/components';
1035
+ import type { LayoutStyles } from '@pixi/layout';
1036
+
1037
+ // Slider (not wrapped by the engine)
1038
+ const volumeSlider = new Slider({
1039
+ bg: bgSprite,
1040
+ fill: fillSprite,
1041
+ slider: handleSprite,
1042
+ min: 0,
1043
+ max: 100,
1044
+ value: 50,
1045
+ });
1046
+
1047
+ // CheckBox
1048
+ const muteCheck = new CheckBox({
1049
+ style: {
1050
+ unchecked: uncheckedView,
1051
+ checked: checkedView,
1052
+ },
1053
+ });
1054
+
1055
+ // LayoutContainer with flexbox styles
1056
+ const row = new LayoutContainer();
1057
+ row.layout = {
1058
+ flexDirection: 'row',
1059
+ gap: 12,
1060
+ alignItems: 'center',
1061
+ padding: 16,
1062
+ } satisfies LayoutStyles;
1063
+ row.addChild(volumeSlider, muteCheck);
1064
+ ```
1065
+
1066
+ > **Tip:** Any container created after importing `@energy8platform/game-engine/ui` can use the `container.layout = { ... }` mixin — the `@pixi/layout` side-effect is automatically activated.
1067
+
1068
+ ---
1069
+
1012
1070
  ## Input
1013
1071
 
1014
1072
  `InputManager` provides unified touch/mouse/keyboard handling with gesture detection:
@@ -1455,7 +1513,7 @@ class ProgressBar extends Container {
1455
1513
 
1456
1514
  ### Toast
1457
1515
 
1458
- > Uses `@pixi/layout` LayoutContainer for auto-sized background. Supports info / success / warning / error types.
1516
+ > Lightweight toast using `Graphics` for the background. Supports info / success / warning / error types.
1459
1517
 
1460
1518
  ```typescript
1461
1519
  class Toast extends Container {
package/dist/index.cjs.js CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  var pixi_js = require('pixi.js');
4
4
  var gameSdk = require('@energy8platform/game-sdk');
5
- require('@pixi/layout');
6
5
  var ui = require('@pixi/ui');
7
6
  var components = require('@pixi/layout/components');
8
7
 
@@ -3569,8 +3568,6 @@ const TOAST_COLORS = {
3569
3568
  /**
3570
3569
  * Toast notification component for displaying transient messages.
3571
3570
  *
3572
- * Uses `@pixi/layout` LayoutContainer for auto-sized background.
3573
- *
3574
3571
  * @example
3575
3572
  * ```ts
3576
3573
  * const toast = new Toast();
@@ -3589,7 +3586,7 @@ class Toast extends pixi_js.Container {
3589
3586
  duration: config.duration ?? 3000,
3590
3587
  bottomOffset: config.bottomOffset ?? 60,
3591
3588
  };
3592
- this._bg = new components.LayoutContainer();
3589
+ this._bg = new pixi_js.Graphics();
3593
3590
  this.addChild(this._bg);
3594
3591
  this._text = new pixi_js.Text({
3595
3592
  text: '',
@@ -3615,16 +3612,10 @@ class Toast extends pixi_js.Container {
3615
3612
  const width = Math.max(200, this._text.width + padding * 2);
3616
3613
  const height = 44;
3617
3614
  const radius = 8;
3618
- // Style the background
3619
- this._bg.layout = {
3620
- width,
3621
- height,
3622
- borderRadius: radius,
3623
- backgroundColor: TOAST_COLORS[type],
3624
- };
3625
- // Center the bg around origin
3626
- this._bg.x = -width / 2;
3627
- this._bg.y = -height / 2;
3615
+ // Draw the background
3616
+ this._bg.clear();
3617
+ this._bg.roundRect(-width / 2, -height / 2, width, height, radius);
3618
+ this._bg.fill(TOAST_COLORS[type]);
3628
3619
  // Position
3629
3620
  if (viewWidth && viewHeight) {
3630
3621
  this.x = viewWidth / 2;
@@ -3811,12 +3802,18 @@ class Layout extends pixi_js.Container {
3811
3802
  applyGridChildWidth(child) {
3812
3803
  const effective = this.resolveConfig();
3813
3804
  const columns = effective.columns ?? this._layoutConfig.columns;
3814
- const pct = `${(100 / columns).toFixed(2)}%`;
3805
+ const gap = effective.gap ?? this._layoutConfig.gap;
3806
+ // Account for gaps between columns: total gap space = gap * (columns - 1)
3807
+ // Each column gets: (100% - total_gap) / columns
3808
+ // We use flexBasis + flexGrow to let Yoga handle the math when gap > 0
3809
+ const styles = gap > 0
3810
+ ? { flexBasis: 0, flexGrow: 1, flexShrink: 1, maxWidth: `${(100 / columns).toFixed(2)}%` }
3811
+ : { width: `${(100 / columns).toFixed(2)}%` };
3815
3812
  if (child._layout) {
3816
- child._layout.setStyle({ width: pct });
3813
+ child._layout.setStyle(styles);
3817
3814
  }
3818
3815
  else {
3819
- child.layout = { width: pct };
3816
+ child.layout = styles;
3820
3817
  }
3821
3818
  }
3822
3819
  applyAnchor() {
@@ -4109,22 +4106,6 @@ class DevBridge {
4109
4106
  }
4110
4107
  }
4111
4108
 
4112
- Object.defineProperty(exports, "ButtonContainer", {
4113
- enumerable: true,
4114
- get: function () { return ui.ButtonContainer; }
4115
- });
4116
- Object.defineProperty(exports, "FancyButton", {
4117
- enumerable: true,
4118
- get: function () { return ui.FancyButton; }
4119
- });
4120
- Object.defineProperty(exports, "ScrollBox", {
4121
- enumerable: true,
4122
- get: function () { return ui.ScrollBox; }
4123
- });
4124
- Object.defineProperty(exports, "LayoutContainer", {
4125
- enumerable: true,
4126
- get: function () { return components.LayoutContainer; }
4127
- });
4128
4109
  exports.AssetManager = AssetManager;
4129
4110
  exports.AudioManager = AudioManager;
4130
4111
  exports.BalanceDisplay = BalanceDisplay;