kadou-game-sdk 1.0.2 → 1.0.3

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,878 +1,73 @@
1
- # kadou-game-sdk
2
-
3
- Kadou 游戏通信 SDK,用于宿主页面与 iframe 游戏页面之间的通信、生命周期管理、主题同步,以及开始页 / 结束页等覆盖层页面的统一控制。
4
-
5
- 适用于以下场景:
6
-
7
- - Vue / React / 原生 HTML 宿主页中嵌入 iframe 游戏
8
- - 线上配置加载 / 离线本地 JSON 加载的统一接入
9
- - 游戏页面与宿主页面通过 `postMessage` 通信
10
- - 宿主页统一控制主题、开始页、结束页、游戏状态
11
- - 不同技术栈游戏统一接入(HTML / Canvas / Vue / Construct 等)
12
-
13
- ---
14
-
15
- ## 目录
16
-
17
- - [特性](#特性)
18
- - [安装](#安装)
19
- - [包导出说明](#包导出说明)
20
- - [核心概念](#核心概念)
21
- - [快速开始](#快速开始)
22
- - [Host 宿主页接入](#host-宿主页接入)
23
- - [Game 游戏页接入](#game-游戏页接入)
24
- - [API 文档](#api-文档)
25
- - [GameRuntime](#gameruntime)
26
- - [实例方法](#实例方法)
27
- - [实例事件](#实例事件)
28
- - [状态字段](#状态字段)
29
- - [消息流转时序](#消息流转时序)
30
- ---
31
-
32
- ## 特性
33
-
34
- - 统一封装 iframe 与宿主页的 `postMessage` 通信
35
- - 提供事件机制,方便监听游戏生命周期
36
- - 管理 SDK / Game 状态
37
- - 支持开始页、结束页渲染
38
- - 支持主题同步与动态主题加载
39
- - 支持心跳检测
40
- - 支持题目流程、答题流程、排行榜、音量等扩展能力
41
- - 支持 ESM / CJS / UMD
42
- - 兼容老项目,构建目标包含 IE11
43
-
44
- ---
45
-
46
- ## 安装
47
-
48
- ### npm
49
-
50
- ```bash
51
- npm install kadou-game-sdk
52
- ```
53
-
54
- ### yarn
55
-
56
- ```bash
57
- yarn add kadou-game-sdk
58
- ```
59
-
60
- ### pnpm
61
-
62
- ```bash
63
- pnpm add kadou-game-sdk
64
- ```
65
-
66
- ---
67
-
68
- ## 包导出说明
69
-
70
- 本包默认提供以下产物:
71
-
72
- - `dist/kadou-game-sdk.esm.js`
73
- - `dist/kadou-game-sdk.cjs`
74
- - `dist/kadou-game-sdk.umd.js`
75
- - `dist/kadou-game-sdk.umd.min.js`
76
-
77
- ### 包信息
78
-
79
- - 包名:`kadou-game-sdk`
80
- - `main`: `dist/kadou-game-sdk.cjs`
81
- - `module`: `dist/kadou-game-sdk.esm.js`
82
- - `browser`: `dist/kadou-game-sdk.umd.js`
83
- - `unpkg/jsdelivr`: `dist/kadou-game-sdk.umd.min.js`
84
-
85
- ### UMD 全局变量
86
-
87
- 浏览器通过 script 标签引入后,可通过全局变量访问:
88
-
89
- ```js
90
- window.KadouGameSDK
91
- ```
92
-
93
- ---
94
-
95
- ## 核心概念
96
-
97
- SDK 中有两个核心角色:
98
-
99
- ### 1. host
100
-
101
- 宿主页面,通常是你的 Vue 壳、React 壳、官网页面、企业平台页面。
102
-
103
- 职责通常包括:
104
-
105
- - 创建 iframe
106
- - 初始化 SDK
107
- - 把 iframe 的 `contentWindow` 作为通信目标
108
- - 拉取游戏配置
109
- - 拉取主题配置
110
- - 通知游戏加载、开始、结束、配置变更等
111
- - 接收游戏回传的结果、答题数据、错误信息等
112
-
113
- ### 2. game
114
-
115
- 真正运行游戏的 iframe 页面。
116
-
117
- 职责通常包括:
118
-
119
- - 初始化 SDK
120
- - 与宿主页通信
121
- - 接收主题
122
- - 接收开始页 / 结束页显示指令
123
- - 在游戏开始、结束、答题时向宿主上报状态
124
- - 渲染覆盖层 UI(开始页、结束页)
125
-
126
- ---
127
-
128
- ## 快速开始
129
-
130
- ### ESM 方式
131
-
132
- ```js
133
- import { GameRuntime, MESSAGE_TYPES } from 'kadou-game-sdk';
134
-
135
- const runtime = new GameRuntime({
136
- role: 'host',
137
- debug: true
138
- });
139
-
140
- runtime.init();
141
-
142
- runtime.on('game:ready', function () {
143
- console.log('游戏已准备完成');
144
- });
145
- ```
146
-
147
- ### CommonJS 方式
148
-
149
- ```js
150
- const sdk = require('kadou-game-sdk');
151
- const GameRuntime = sdk.GameRuntime;
152
- const MESSAGE_TYPES = sdk.MESSAGE_TYPES;
153
-
154
- const runtime = new GameRuntime({
155
- role: 'host',
156
- debug: true
157
- });
158
-
159
- runtime.init();
160
- ```
161
-
162
- ### script 方式
163
-
164
- ```html
165
- <script src="./dist/kadou-game-sdk.umd.min.js"></script>
166
- <script>
167
- var GameRuntime = window.KadouGameSDK.GameRuntime;
168
- var MESSAGE_TYPES = window.KadouGameSDK.MESSAGE_TYPES;
169
-
170
- var runtime = new GameRuntime({
171
- role: 'host',
172
- debug: true
173
- });
174
-
175
- runtime.init();
176
- </script>
177
- ```
178
-
179
- ---
180
-
181
- ## Host 宿主页接入
182
-
183
- 下面是宿主页最常见的接入方式。
184
-
185
- ```js
186
- import { GameRuntime } from 'kadou-game-sdk';
187
-
188
- const iframe = document.getElementById('gameIframe');
189
-
190
- const runtime = new GameRuntime({
191
- role: 'host',
192
- selfWindow: window,
193
- targetWindow: iframe.contentWindow,
194
- targetOrigin: '*',
195
- allowedOrigins: ['*'],
196
- debug: true
197
- });
198
-
199
- runtime.init();
200
-
201
- runtime.on('game:ready', function (payload) {
202
- console.log('game ready', payload);
203
- });
204
-
205
- runtime.on('question:submit', function (payload) {
206
- console.log('学生单题提交答案', payload);
207
- });
208
-
209
- runtime.on('result:report', function (payload) {
210
- console.log('游戏报告', payload);
211
- });
212
-
213
- runtime.notifySdkReady();
214
-
215
- runtime.loadGame({
216
- gameId: 'game_001',
217
- title: '动物单词挑战赛',
218
- questionCount: 10
219
- });
220
-
221
- runtime.applyTheme('theme-default', {
222
- startPage: {
223
- title: '动物单词挑战赛',
224
- desc: '本轮共 10 题,答对越多得分越高',
225
- buttonText: '立即开始'
226
- },
227
- endPage: {
228
- title: '挑战完成',
229
- buttonText: '再来一次'
230
- }
231
- });
232
-
233
- runtime.showStartPage({
234
- title: '动物单词挑战赛',
235
- desc: '点击开始进入游戏',
236
- buttonText: '开始挑战'
237
- });
238
- ```
239
-
240
- ---
241
-
242
- ## Game 游戏页接入
243
-
244
- iframe 游戏页中一般这样接入:
245
-
246
- ```js
247
- import { GameRuntime } from 'kadou-game-sdk';
248
-
249
- const runtime = new GameRuntime({
250
- role: 'game',
251
- selfWindow: window,
252
- targetWindow: window.parent,
253
- targetOrigin: '*',
254
- allowedOrigins: ['*'],
255
- root: document.body,
256
- debug: true
257
- });
258
-
259
- runtime.init();
260
-
261
- runtime.on('sdk:ready', function () {
262
- console.log('宿主页 SDK 已准备完成');
263
- });
264
-
265
- runtime.on('game:load', function (payload) {
266
- console.log('收到游戏配置', payload);
267
-
268
- runtime.showStartPage({
269
- title: payload.title || '游戏开始',
270
- desc: '准备好后点击开始',
271
- buttonText: '立即开始'
272
- });
273
- });
274
-
275
- runtime.on('theme:update', function (payload) {
276
- console.log('收到主题', payload);
277
- });
278
-
279
- runtime.on('game:start', function () {
280
- console.log('游戏开始');
281
- startRealGame();
282
- });
283
-
284
- runtime.on('game:restart', function () {
285
- console.log('重新开始');
286
- restartRealGame();
287
- });
288
-
289
- runtime.gameReady();
290
-
291
- function startRealGame() {
292
- // 你的真实游戏逻辑
293
- }
294
-
295
- function restartRealGame() {
296
- // 你的重开逻辑
297
- }
298
- ```
299
-
300
- ## API 文档
301
-
302
- ## GameRuntime
303
-
304
- `GameRuntime` 是 SDK 对外的核心类。
305
-
306
- ### 引入
307
-
308
- ```js
309
- import { GameRuntime } from 'kadou-game-sdk';
310
- ```
311
-
312
- ### 创建实例
313
-
314
- ```js
315
- const runtime = new GameRuntime(options);
316
- ```
317
-
318
- ### options 参数
319
-
320
- ```js
321
- {
322
- root,
323
- debug,
324
- role,
325
- selfWindow,
326
- targetWindow,
327
- targetOrigin,
328
- allowedOrigins,
329
- source
330
- }
331
- ```
332
-
333
- ### 示例
334
-
335
- ```js
336
- const runtime = new GameRuntime({
337
- root: document.body,
338
- role: 'game',
339
- selfWindow: window,
340
- targetWindow: window.parent,
341
- targetOrigin: '*',
342
- allowedOrigins: ['*'],
343
- debug: true
344
- });
345
- ```
346
-
347
- ---
348
-
349
- ## 实例方法
350
-
351
- ### 生命周期
352
-
353
- #### `init()`
354
-
355
- 启动 SDK,开始监听消息。
356
-
357
- ```js
358
- runtime.init();
359
- ```
360
-
361
- #### `destroy()`
362
-
363
- 销毁 SDK,移除消息监听,隐藏覆盖层,清理事件。
364
-
365
- ```js
366
- runtime.destroy();
367
- ```
368
-
369
- ### 基础设置
370
-
371
- #### `setTargetWindow(win)`
372
-
373
- 设置消息发送目标窗口。
374
-
375
- ```js
376
- runtime.setTargetWindow(iframe.contentWindow);
377
- ```
378
-
379
- #### `setTargetOrigin(origin)`
380
-
381
- 设置消息发送目标 origin。
382
-
383
- ```js
384
- runtime.setTargetOrigin('*');
385
- ```
386
- ### 通用消息发送
387
-
388
- #### `send(type, payload, meta)`
389
-
390
- 底层通用发送方法。
391
-
392
- ```js
393
- runtime.send('CUSTOM_EVENT', { a: 1 });
394
- ```
395
-
396
- ### Ready / 心跳
397
-
398
- #### `notifySdkReady(extra)`
399
-
400
- 通知对端:SDK 已准备完成。
401
-
402
- ```js
403
- runtime.notifySdkReady();
404
- ```
405
-
406
- #### `gameReady(extra)`
407
-
408
- 通知对端:游戏已准备完成。
409
-
410
- ```js
411
- runtime.gameReady();
412
- ```
413
-
414
- #### `heartbeatPing(extra)`
415
-
416
- 发送心跳检测。
417
-
418
- ```js
419
- runtime.heartbeatPing();
420
- ```
421
-
422
- ### 游戏生命周期
423
-
424
- #### `loadGame(config)`
425
-
426
- 发送游戏加载配置。
427
-
428
- ```js
429
- runtime.loadGame({
430
- gameId: 'g001',
431
- title: '词汇闯关'
432
- });
433
- ```
434
-
435
- #### `gameLoading(config)`
436
-
437
- 发送游戏加载中进度或状态。
438
-
439
- ```js
440
- runtime.gameLoading({
441
- progress: 60
442
- });
443
- ```
444
-
445
- #### `gameLoaded(config)`
446
-
447
- 发送游戏加载完成。
448
-
449
- ```js
450
- runtime.gameLoaded({
451
- success: true
452
- });
453
- ```
454
-
455
- #### `startGame(data)`
456
-
457
- 开始游戏。
458
-
459
- ```js
460
- runtime.startGame({
461
- from: 'host'
462
- });
463
- ```
464
-
465
- #### `restartGame(data)`
466
-
467
- 重新开始游戏。
468
-
469
- ```js
470
- runtime.restartGame();
471
- ```
472
-
473
- #### `pauseGame(data)`
474
-
475
- 暂停游戏。
476
-
477
- ```js
478
- runtime.pauseGame();
479
- ```
480
-
481
- #### `resumeGame(data)`
482
-
483
- 恢复游戏。
484
-
485
- ```js
486
- runtime.resumeGame();
487
- ```
488
-
489
- #### `finishGame(result)`
490
-
491
- 结束游戏。
492
-
493
- ```js
494
- runtime.finishGame({
495
- score: 88
496
- });
497
- ```
498
-
499
- #### `destroyGame(data)`
500
-
501
- 销毁游戏。
502
-
503
- ```js
504
- runtime.destroyGame();
505
- ```
506
-
507
- #### `showGameRank(data)`
508
-
509
- 显示排行榜。
510
-
511
- ```js
512
- runtime.showGameRank({
513
- from: 'end-page'
514
- });
515
- ```
516
-
517
- ### 主题与配置
518
-
519
- #### `updateTheme(theme)`
520
-
521
- 兼容旧接口,直接发送主题对象。
522
-
523
- ```js
524
- runtime.updateTheme({
525
- bg: 'xxx.png'
526
- });
527
- ```
528
-
529
- #### `applyTheme(themeKey, themeConfig, extra)`
530
-
531
- 推荐使用。发送主题 key 与主题配置。
532
-
533
- ```js
534
- runtime.applyTheme('theme-default', {
535
- startPage: {
536
- title: '欢迎开始'
537
- },
538
- endPage: {
539
- title: '挑战完成'
540
- }
541
- });
542
- ```
543
-
544
- #### `updateConfig(config)`
545
-
546
- 更新配置。
547
-
548
- ```js
549
- runtime.updateConfig({
550
- volume: 0.8
551
- });
552
- ```
553
-
554
- ### 页面控制
555
-
556
- #### `showStartPage(data)`
557
-
558
- 请求显示开始页。
559
-
560
- ```js
561
- runtime.showStartPage({
562
- title: '动物单词挑战赛',
563
- desc: '共 10 题',
564
- buttonText: '立即开始'
565
- });
566
- ```
567
-
568
- #### `showEndPage(data)`
569
-
570
- 请求显示结束页。
571
-
572
- ```js
573
- runtime.showEndPage({
574
- title: '挑战完成',
575
- score: 100,
576
- buttonText: '再来一次'
577
- });
578
- ```
579
-
580
- ### 题目 / 答题流程
581
-
582
- #### `submitQuestion(data)`
583
-
584
- 提交题目或学生答案。
585
-
586
- ```js
587
- runtime.submitQuestion({
588
- questionId: 'q1',
589
- answer: 'A'
590
- });
591
- ```
592
-
593
- #### `startAnswer(data)`
594
-
595
- 开始答题。
596
-
597
- ```js
598
- runtime.startAnswer({
599
- questionId: 'q1'
600
- });
601
- ```
602
-
603
- #### `prevQuestion(data)`
604
-
605
- 上一题。
606
-
607
- ```js
608
- runtime.prevQuestion();
609
- ```
610
-
611
- #### `nextQuestion(data)`
612
-
613
- 下一题。
614
-
615
- ```js
616
- runtime.nextQuestion();
617
- ```
618
-
619
- #### `completedAnswer(data)`
620
-
621
- 答题完成。
622
-
623
- ```js
624
- runtime.completedAnswer({
625
- correct: 8,
626
- total: 10
627
- });
628
- ```
629
-
630
- ### 音量与扩展
631
-
632
- #### `changeVolume(data)`
633
-
634
- 调节音量。
635
-
636
- ```js
637
- runtime.changeVolume({
638
- bgmVolume: 0.8,//背景音
639
- bgmMuted: false,
640
- sfxVolume: 0.6,//音效
641
- sfxMuted: false
642
- });
643
- ```
644
-
645
- #### `extensionEvent(extra)`
646
-
647
- 发送扩展事件。
648
-
649
- ```js
650
- runtime.extensionEvent({
651
- type: 'custom-action',
652
- payload: {
653
- foo: 1
654
- }
655
- });
656
- ```
657
-
658
- ### 错误与状态
659
-
660
- #### `reportError(error)`
661
-
662
- 上报错误。
663
-
664
- ```js
665
- runtime.reportError(new Error('资源加载失败'));
666
- ```
667
-
668
-
669
-
670
- ```js
671
- runtime.reportError({
672
- code: 'LOAD_ERROR',
673
- message: '资源加载失败'
674
- });
675
- ```
676
-
677
- #### `getState()`
678
-
679
- 获取当前状态。
680
-
681
- ```js
682
- const state = runtime.getState();
683
- ```
684
-
685
- 返回值:
686
-
687
- ```js
688
- {
689
- sdkReady: false,
690
- gameReady: false,
691
- started: false,
692
- paused: false,
693
- destroyed: false
694
- }
695
- ```
696
-
697
- #### `isReady()`
698
-
699
- 是否同时满足 SDK ready 与 Game ready。
700
-
701
- ```js
702
- if (runtime.isReady()) {
703
- console.log('可开始通信');
704
- }
705
- ```
706
-
707
- ### 主题加载辅助方法
708
-
709
- #### `loadThemeByUrl(url, callback)`
710
-
711
- 按 URL 直接加载主题。
712
-
713
- ```js
714
- runtime.loadThemeByUrl('/themes/default/theme.js', function (themeConfig) {
715
- runtime.applyTheme('default', themeConfig);
716
- });
717
- ```
718
-
719
- #### `ensureTheme(themeKey, themeRoot, callback)`
720
-
721
- 确保某个主题已加载。
722
-
723
- ```js
724
- runtime.ensureTheme('default', '/themes/', function (themeConfig) {
725
- runtime.applyTheme('default', themeConfig);
726
- });
727
- ```
728
-
729
- #### `buildThemeUrl(themeRoot, themeKey)`
730
-
731
- ## 实例事件
732
-
733
- SDK 内部会把消息转换为事件,外部可以通过 `on` 监听。
734
-
735
- ### 基础监听
736
-
737
- ```js
738
- runtime.on('game:ready', function (payload, message, context) {
739
- console.log(payload);
740
- });
741
- ```
742
-
743
- ### 通用消息监听
744
-
745
- #### `message`
746
-
747
- 监听所有消息。
748
-
749
- ```js
750
- runtime.on('message', function (message, context) {
751
- console.log('所有消息', message, context);
752
- });
753
- ```
754
-
755
- ### Ready 相关
756
-
757
- - `sdk:ready`
758
- - `game:ready`
759
-
760
- ### 游戏生命周期
761
-
762
- - `game:load`
763
- - `game:loaded`
764
- - `game:loading`
765
- - `game:start`
766
- - `game:restart`
767
- - `game:pause`
768
- - `game:resume`
769
- - `game:finish`
770
- - `game:destroy`
771
- - `game:rank`
772
-
773
- ### 配置 / 主题
774
-
775
- - `theme:update`
776
- - `config:update`
777
-
778
- ### 页面相关
779
-
780
- - `page:start:show`
781
- - `page:end:show`
782
-
783
- ### 题目 / 答题
784
-
785
- - `question:submit`
786
- - `answer:start`
787
- - `question:prev`
788
- - `question:next`
789
- - `answer:completed`
790
-
791
- ### 结果 / 错误 / 心跳
792
-
793
- - `result:report`
794
- - `error`
795
- - `heartbeat:ping`
796
- - `heartbeat:pong`
797
-
798
- ### 扩展
799
-
800
- - `extension:event`
801
- - `volume:change`
802
-
803
- ---
804
-
805
- ## 状态字段
806
-
807
- SDK 内部维护了以下状态:
808
-
809
- ```js
810
- {
811
- sdkReady: false,
812
- gameReady: false,
813
- started: false,
814
- paused: false,
815
- destroyed: false
816
- }
817
- ```
818
-
819
- ### 字段含义
820
-
821
- - `sdkReady`: 宿主 SDK 是否 ready
822
- - `gameReady`: 游戏页是否 ready
823
- - `started`: 游戏是否开始
824
- - `paused`: 游戏是否暂停
825
- - `destroyed`: 是否已经销毁
826
-
827
- ---
828
-
829
- ## 消息流转时序
830
-
831
- ### 1. 正常初始化时序
832
-
833
- ```text
834
- Host 页面 Game 页面
835
- | |
836
- |------ init() ----------------->|
837
- | |
838
- |------ notifySdkReady() ------->|
839
- | |
840
- |<--------- sdk:ready -----------|
841
- | |
842
- |<--------- gameReady() ---------|
843
- | |
844
- |------ loadGame(config) ------->|
845
- | |
846
- |------ applyTheme(...) -------->|
847
- | |
848
- |------ showStartPage() -------->|
849
- | |
850
- |<----- 用户点击开始页按钮 ------|
851
- | |
852
- |<--------- startGame() ---------|
853
- | |
854
- |------ 游戏正式开始 ------------>|
855
- ```
856
-
857
- ### 2. 游戏结束时序
858
-
859
- ```text
860
- Game 页面 Host 页面
861
- | |
862
- |------ finishGame(result) ----->|
863
- | |
864
- |------ completedAnswer() ------>|
865
- | |
866
- |------ result report ---------->|
867
- | |
868
- |<----- showEndPage(data) -------|
869
- | |
870
- |<----- 用户点击再来一次 --------|
871
- | |
872
- |------ restartGame() ---------->|
873
- ```
874
-
875
-
876
- ## License
877
-
878
- MIT
1
+ # kadou-game-sdk
2
+
3
+ ## 安装
4
+
5
+ ```bash
6
+ npm install kadou-game-sdk
7
+ ```
8
+
9
+ ## 导出内容
10
+
11
+ ```js
12
+ import KadouGameSDK, {
13
+ SDK_VERSION,
14
+ MESSAGE_TYPES,
15
+ EventEmitter,
16
+ MessageBus,
17
+ GameRuntime
18
+ } from 'kadou-game-sdk';
19
+ ```
20
+
21
+ ## 快速使用
22
+
23
+
24
+ ```js
25
+ import { GameRuntime } from 'kadou-game-sdk';
26
+
27
+ const runtime = new GameRuntime({
28
+ role: 'game',
29
+ targetWindow: window.parent,
30
+ targetOrigin: '*',
31
+ root: document.body,
32
+ debug: true
33
+ });
34
+
35
+ runtime.init();
36
+ runtime.gameReady();
37
+
38
+ runtime.on('game:start', function () {
39
+ console.log('游戏开始');
40
+ });
41
+ ```
42
+
43
+ ## 常用能力
44
+
45
+ `GameRuntime` 提供的常用能力包括生命周期控制、页面控制、答题事件上报、主题与配置下发、心跳检测和错误上报。相关方法包括 `startGame`、`pauseGame`、`resumeGame`、`finishGame`、`restartGame`、`showStartPage`、`showEndPage`、`updateConfig`、`applyTheme`、`startAnswer`、`submitQuestion`、`showAnswerPopup`、`extensionEvent` 等。
46
+
47
+ ## 常用事件
48
+
49
+ ```js
50
+ runtime.on('sdk:ready', handler);
51
+ runtime.on('game:ready', handler);
52
+ runtime.on('game:start', handler);
53
+ runtime.on('game:finish', handler);
54
+ runtime.on('question:submit', handler);
55
+ runtime.on('page:start:show', handler);
56
+ runtime.on('page:end:show', handler);
57
+ runtime.on('theme:update', handler);
58
+ runtime.on('config:update', handler);
59
+ runtime.on('error', handler);
60
+ ```
61
+
62
+ 当前 `GameRuntime` 会对游戏开始、暂停、恢复、结束、配置更新、开始页/结束页显示、答题提交、弹窗题、心跳等消息进行统一派发。
63
+
64
+ ## 适用场景
65
+
66
+ - 宿主页面控制 iframe 游戏
67
+ - 课堂互动游戏
68
+ - 题卡 / 答题类 H5 游戏
69
+ - 需要统一通信协议的小游戏容器
70
+
71
+ ## License
72
+
73
+ MIT