@maoyugames/phaser-framework 1.0.0 → 1.0.2

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/cli/index.js CHANGED
@@ -236,7 +236,15 @@ function createPlatformConfig(platform, opts) {
236
236
  __FRAMEWORK_VERSION__: JSON.stringify(frameworkVersion)
237
237
  },
238
238
  resolve: {
239
- alias: createAlias(projectRoot)
239
+ alias: createAlias(projectRoot),
240
+ // 去重 phaser:避免框架包与业务解析到不同 phaser 实例
241
+ dedupe: ["phaser"]
242
+ },
243
+ // dev 模式必须预打包 phaser(及框架包)为带 default 导出的 ESM,
244
+ // 否则 vite dev 下 `import Phaser from 'phaser'` 报
245
+ // "phaser does not provide an export named 'default'"(build 模式 rollup 自带 CJS 互操作,不受影响)。
246
+ optimizeDeps: {
247
+ include: ["phaser", "@maoyugames/phaser-framework"]
240
248
  },
241
249
  esbuild: {
242
250
  // 兼容低端 webview / 小游戏 JS 引擎
@@ -1043,27 +1051,25 @@ async function runDev(target) {
1043
1051
  const config = await loadPlatformConfig(ctx);
1044
1052
  const vite = await loadViteFromRoot(ctx.root);
1045
1053
  const cache = cacheDir2(ctx.root);
1046
- fse4.ensureDirSync(cache);
1047
1054
  const hash = randomBytes(4).toString("hex");
1048
- const entryFileName = `main.${platform}.${hash}.ts`;
1049
- const entryPath = join(cache, entryFileName);
1050
- const htmlName = `index.${platform}.${hash}.html`;
1051
- const htmlPath = join(cache, htmlName);
1055
+ const runDir = join(cache, `dev-${platform}-${hash}`);
1056
+ fse4.ensureDirSync(runDir);
1057
+ const entryFileName = `main.${platform}.ts`;
1058
+ const entryPath = join(runDir, entryFileName);
1059
+ const htmlPath = join(runDir, "index.html");
1052
1060
  fse4.writeFileSync(entryPath, renderEntry({ platform, projectRoot: ctx.root }), "utf-8");
1053
1061
  fse4.writeFileSync(htmlPath, renderHtmlShell2(platform, config, `./${entryFileName}`), "utf-8");
1054
1062
  const cleanup = () => {
1055
- for (const f of [entryPath, htmlPath]) {
1056
- try {
1057
- fse4.removeSync(f);
1058
- } catch {
1059
- }
1063
+ try {
1064
+ fse4.removeSync(runDir);
1065
+ } catch {
1060
1066
  }
1061
1067
  };
1062
1068
  try {
1063
1069
  const server = await vite.createServer({
1064
- // root 设为缓存目录(临时 HTML 所在),入口页直接是 /index.<p>.<hash>.html;
1065
- // alias/publicDir 用绝对路径不受影响
1066
- root: cache,
1070
+ // root 设为本次 dev 的独立子目录(其根有 index.html),浏览器打开 / 即入口页;
1071
+ // alias/publicDir 用绝对路径不受 root 影响
1072
+ root: runDir,
1067
1073
  base: "/",
1068
1074
  configFile: false,
1069
1075
  define: {
@@ -1075,7 +1081,14 @@ async function runDev(target) {
1075
1081
  alias: [
1076
1082
  { find: /^@game$/, replacement: resolve(ctx.root, "src/game") },
1077
1083
  { find: /^@game\//, replacement: resolve(ctx.root, "src/game") + "/" }
1078
- ]
1084
+ ],
1085
+ // 去重 phaser,避免框架包与业务解析到不同实例
1086
+ dedupe: ["phaser"]
1087
+ },
1088
+ // 必须预打包 phaser(及框架包)为带 default 导出的 ESM,
1089
+ // 否则 dev 下 `import Phaser from 'phaser'` 报 "does not provide an export named 'default'"。
1090
+ optimizeDeps: {
1091
+ include: ["phaser", "@maoyugames/phaser-framework"]
1079
1092
  },
1080
1093
  publicDir: resolve(ctx.root, "src/game/public"),
1081
1094
  server: { open: false }
@@ -1084,7 +1097,7 @@ async function runDev(target) {
1084
1097
  const info = server.resolvedUrls;
1085
1098
  const url = info?.local?.[0] ?? "http://localhost:5173/";
1086
1099
  console.log(pc4.green(pc4.bold(`\u25B6 [${platform}] dev server \u5C31\u7EEA`)));
1087
- console.log(` \u6253\u5F00:${pc4.cyan(url + htmlName)}`);
1100
+ console.log(` \u6253\u5F00:${pc4.cyan(url)}`);
1088
1101
  console.log(pc4.gray(" (Ctrl+C \u9000\u51FA,\u4E34\u65F6\u5165\u53E3\u4F1A\u81EA\u52A8\u6E05\u7406)"));
1089
1102
  const onExit = async () => {
1090
1103
  cleanup();
package/dist/index.d.ts CHANGED
@@ -962,14 +962,16 @@ declare abstract class BaseScene extends Phaser.Scene {
962
962
  private readonly _bindings;
963
963
  /** 清理钩子是否已注册(防止同一实例重复注册) */
964
964
  private _cleanupArmed;
965
+ constructor(config?: string | Phaser.Types.Scenes.SettingsConfig);
965
966
  /**
966
- * E4 构造时挂上场景生命周期清理钩子。
967
+ * Phaser 生命周期 init:此时 this.events 已就绪。在此挂场景清理钩子(E4)。
968
+ *
969
+ * Phaser 场景实例可被复用(stop → start 重启):每次重启都会再次触发 init / create。
970
+ * armCleanupHooks 内部用 once + 自重注册覆盖每一轮 SHUTDOWN;DESTROY(实例被移除)只需一次。
967
971
  *
968
- * Phaser 场景实例可被复用(stop start 重启):重启时不会再走 constructor,
969
- * 但会再次触发 create。因此清理逻辑必须在每次 SHUTDOWN 都执行,并在执行后
970
- * 重新登记(re-arm),保证下一轮生命周期同样被覆盖;DESTROY(实例被移除)只需一次。
972
+ * 注意:业务场景若覆写 init(data),请调用 super.init(data) 以保留自动清理(this.bind / this.scheduler)
971
973
  */
972
- constructor(config?: string | Phaser.Types.Scenes.SettingsConfig);
974
+ init(_data?: object): void;
973
975
  /**
974
976
  * 登记需在场景关闭时清理的订阅(E4)。
975
977
  * @param unsub App.events.on / socket.onMessage 等返回的 Unsubscribe
package/dist/index.js CHANGED
@@ -2107,13 +2107,20 @@ var SceneManager = class {
2107
2107
  console.warn("[SceneManager] Phaser.Game \u5C1A\u672A\u5C31\u7EEA,goto \u88AB\u5FFD\u7565:", key);
2108
2108
  return;
2109
2109
  }
2110
- for (const scene of manager.getScenes(true)) {
2110
+ const sceneData = asSceneData(data);
2111
+ const all = manager.getScenes(false);
2112
+ const vehicle = all.find((s) => s.scene.key !== key);
2113
+ for (const scene of all) {
2111
2114
  const sceneKey = scene.scene.key;
2112
- if (sceneKey !== key) {
2115
+ if (sceneKey !== key && scene !== vehicle) {
2113
2116
  manager.stop(sceneKey);
2114
2117
  }
2115
2118
  }
2116
- manager.start(key, asSceneData(data));
2119
+ if (vehicle) {
2120
+ vehicle.scene.start(key, sceneData);
2121
+ } else {
2122
+ manager.start(key, sceneData);
2123
+ }
2117
2124
  }
2118
2125
  push(key, data) {
2119
2126
  const manager = this.game?.scene;
@@ -3056,13 +3063,6 @@ var Scheduler = class {
3056
3063
 
3057
3064
  // src/scene/BaseScene.ts
3058
3065
  var BaseScene = class extends Phaser4.Scene {
3059
- /**
3060
- * E4 构造时挂上场景生命周期清理钩子。
3061
- *
3062
- * Phaser 场景实例可被复用(stop → start 重启):重启时不会再走 constructor,
3063
- * 但会再次触发 create。因此清理逻辑必须在每次 SHUTDOWN 都执行,并在执行后
3064
- * 重新登记(re-arm),保证下一轮生命周期同样被覆盖;DESTROY(实例被移除)只需一次。
3065
- */
3066
3066
  constructor(config) {
3067
3067
  super(config);
3068
3068
  /* --------------------------- 自动清理 / 调度 --------------------------- */
@@ -3080,12 +3080,22 @@ var BaseScene = class extends Phaser4.Scene {
3080
3080
  __publicField(this, "_bindings", []);
3081
3081
  /** 清理钩子是否已注册(防止同一实例重复注册) */
3082
3082
  __publicField(this, "_cleanupArmed", false);
3083
- this.armCleanupHooks();
3084
3083
  }
3085
3084
  /** App 门面:业务在场景内访问网络/音频/存储等的统一入口 */
3086
3085
  get app() {
3087
3086
  return App;
3088
3087
  }
3088
+ /**
3089
+ * Phaser 生命周期 init:此时 this.events 已就绪。在此挂场景清理钩子(E4)。
3090
+ *
3091
+ * Phaser 场景实例可被复用(stop → start 重启):每次重启都会再次触发 init / create。
3092
+ * armCleanupHooks 内部用 once + 自重注册覆盖每一轮 SHUTDOWN;DESTROY(实例被移除)只需一次。
3093
+ *
3094
+ * 注意:业务场景若覆写 init(data),请调用 super.init(data) 以保留自动清理(this.bind / this.scheduler)。
3095
+ */
3096
+ init(_data) {
3097
+ this.armCleanupHooks();
3098
+ }
3089
3099
  /**
3090
3100
  * 登记需在场景关闭时清理的订阅(E4)。
3091
3101
  * @param unsub App.events.on / socket.onMessage 等返回的 Unsubscribe
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maoyugames/phaser-framework",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "多平台 Phaser 游戏框架:业务/底层分离,HTTP/WebSocket/KCP,Web/TikTok/微信/Facebook/App 隔离打包",
5
5
  "type": "module",
6
6
  "license": "MIT",