drgame-cc 1.0.45 → 1.0.46
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/drres/focus/focus_1/gesture.atlas +34 -0
- package/drres/focus/focus_1/gesture.atlas.meta +6 -0
- package/drres/focus/focus_1/gesture.json +1 -0
- package/drres/focus/focus_1/gesture.json.meta +10 -0
- package/drres/focus/focus_1/gesture.png +0 -0
- package/drres/{icons/pointer-yellow-60.png.meta → focus/focus_1/gesture.png.meta} +14 -14
- package/drres/focus/focus_1.meta +13 -0
- package/drres/focus/focus_2/gesture.atlas +41 -0
- package/drres/focus/focus_2/gesture.atlas.meta +6 -0
- package/drres/focus/focus_2/gesture.json +1 -0
- package/drres/focus/focus_2/gesture.json.meta +10 -0
- package/drres/focus/focus_2/gesture.png +0 -0
- package/drres/{icons/pointer-blue-60.png.meta → focus/focus_2/gesture.png.meta} +13 -13
- package/drres/focus/focus_2.meta +13 -0
- package/drres/focus/focus_3/gesture.atlas +34 -0
- package/drres/focus/focus_3/gesture.atlas.meta +6 -0
- package/drres/focus/focus_3/gesture.json +1 -0
- package/drres/focus/focus_3/gesture.json.meta +10 -0
- package/drres/focus/focus_3/gesture.png +0 -0
- package/drres/{icons/pointer-pink-60.png.meta → focus/focus_3/gesture.png.meta} +12 -12
- package/drres/focus/focus_3.meta +13 -0
- package/drres/focus/focus_4/gesture.atlas +20 -0
- package/drres/focus/focus_4/gesture.atlas.meta +6 -0
- package/drres/focus/focus_4/gesture.json +1 -0
- package/drres/focus/focus_4/gesture.json.meta +10 -0
- package/drres/focus/focus_4/gesture.png +0 -0
- package/drres/focus/focus_4/gesture.png.meta +38 -0
- package/drres/focus/focus_4.meta +13 -0
- package/drres/focus.meta +13 -0
- package/drres/prefab/ExitWin.prefab +2 -2
- package/drres/prefab/Toast.prefab +378 -378
- package/drscript/{ad/AdManager.ts.meta → BtnExtra.ts.meta} +1 -1
- package/drscript/Define.ts +17 -2
- package/drscript/{ad/AdSlot.ts.meta → Define.ts.meta} +1 -1
- package/drscript/{ad/AggregateAdProvider.ts.meta → ExitWin.ts.meta} +1 -1
- package/drscript/GameAnalytics.ts +37 -118
- package/drscript/{ad/IAdProvider.ts.meta → GameAnalytics.ts.meta} +1 -1
- package/drscript/HelperWin.ts.meta +10 -0
- package/drscript/Info.ts.meta +10 -0
- package/drscript/InternalUitl.ts.meta +10 -0
- package/drscript/KeyAdapter.ts +133 -0
- package/drscript/KeyAdapter.ts.meta +10 -0
- package/drscript/Loader.ts.meta +10 -0
- package/drscript/PlatformAdapter.ts +178 -192
- package/drscript/PlatformAdapter.ts.meta +10 -0
- package/drscript/README.md +91 -805
- package/drscript/README.md.meta +6 -0
- package/drscript/UIAdapter.ts +324 -0
- package/drscript/UIAdapter.ts.meta +10 -0
- package/drscript/WebBridge.ts +1 -1
- package/drscript/WebBridge.ts.meta +10 -0
- package/drscript/ad-sdk/reporters/superset-lewo.js +6 -0
- package/drscript/ad-sdk/types/enums.d.ts +1 -0
- package/drscript/ad-sdk.meta +13 -0
- package/drscript/ad.meta +13 -0
- package/drscript/component/AlertTip.ts +25 -0
- package/drscript/component/AlertTip.ts.meta +10 -0
- package/drscript/component/BtnExtra.ts +17 -0
- package/drscript/component/BtnExtra.ts.meta +10 -0
- package/drscript/{ExitWin.ts → component/ExitWin.ts} +6 -8
- package/drscript/component/ExitWin.ts.meta +10 -0
- package/drscript/{HelperWin.ts → component/HelperWin.ts} +5 -19
- package/drscript/component/HelperWin.ts.meta +10 -0
- package/drscript/component.meta +13 -0
- package/drscript/config.meta +13 -0
- package/drscript/core.meta +13 -0
- package/drscript/focus/FocusItem.ts +1 -19
- package/drscript/focus/FocusManager.ts +132 -170
- package/drscript/focus/FocusVisualLayer.ts +74 -163
- package/drscript/focus.meta +13 -0
- package/drscript/input/KeyboardMove.ts +40 -11
- package/drscript/input/KeyboardMove.ts.meta +10 -0
- package/drscript/input.meta +13 -0
- package/drscript/interface.meta +13 -0
- package/drscript/pinyin.meta +13 -0
- package/drscript/toast.meta +13 -0
- package/drscript/virtualgamepad.meta +13 -0
- package/package.json +1 -1
- package/drres/config/default.json +0 -108
- package/drres/config/default.json.meta +0 -6
- package/drres/icons/pointer-blue-60.png +0 -0
- package/drres/icons/pointer-pink-60.png +0 -0
- package/drres/icons/pointer-white-60.png +0 -0
- package/drres/icons/pointer-yellow-60.png +0 -0
- package/drscript/Info.ts +0 -78
- package/drscript/InternalUitl.ts +0 -65
- package/drscript/ad/AdManager.ts +0 -174
- package/drscript/ad/AdSlot.ts +0 -44
- package/drscript/ad/AggregateAdProvider.ts +0 -149
- package/drscript/ad/IAdProvider.ts +0 -39
- package/drscript/ad/MockAdProvider.ts +0 -36
- package/drscript/ad/MockAdProvider.ts.meta +0 -10
- package/drscript/ad/SelfAdProvider.ts +0 -41
- package/drscript/ad/SelfAdProvider.ts.meta +0 -10
- package/drscript/config/TvUiConfig.ts +0 -155
- package/drscript/config/TvUiConfig.ts.meta +0 -10
- package/drscript/config/TvUiConfigManager.ts +0 -133
- package/drscript/config/TvUiConfigManager.ts.meta +0 -10
- package/drscript/core/BackManager.ts +0 -38
- package/drscript/core/BackManager.ts.meta +0 -10
- package/drscript/core/NativeBridge.ts +0 -137
- package/drscript/core/NativeBridge.ts.meta +0 -10
- package/drscript/core/TvUi.ts +0 -69
- package/drscript/core/TvUi.ts.meta +0 -10
- package/drscript/core/TvUiRoot.ts +0 -137
- package/drscript/core/TvUiRoot.ts.meta +0 -10
- package/drscript/icon/IconConfig.ts +0 -7
- package/drscript/icon/IconConfig.ts.meta +0 -10
- package/drscript/icon/IconManager.ts +0 -97
- package/drscript/icon/IconManager.ts.meta +0 -10
- package/drscript/input/KeyCodeAdapter.ts +0 -23
- package/drscript/input/RemoteInputManager.ts +0 -105
- package/drscript/interface/ILobbyBridge.ts +0 -5
- package/drscript/toast/ToastComponent.ts +0 -35
- package/drscript/toast/ToastComponent.ts.meta +0 -10
- package/drscript/toast/ToastManager.ts +0 -66
- package/drscript/toast/ToastManager.ts.meta +0 -10
- package/drscript/toast/TvExitConfirmDialog.ts +0 -334
- package/drscript/toast/TvExitConfirmDialog.ts.meta +0 -10
- package/drscript/toast/UIFunctions.ts +0 -150
- package/drscript/toast/UIFunctions.ts.meta +0 -10
package/drscript/README.md
CHANGED
|
@@ -1,814 +1,100 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
## 目录结构
|
|
23
|
-
|
|
24
|
-
复制框架时至少带上两部分:
|
|
25
|
-
|
|
26
|
-
```text
|
|
27
|
-
assets/scripts/drres/
|
|
28
|
-
config/
|
|
29
|
-
focus/
|
|
30
|
-
icon/
|
|
31
|
-
ad/
|
|
32
|
-
input/
|
|
33
|
-
core/
|
|
34
|
-
vendor/ad-sdk/
|
|
35
|
-
|
|
36
|
-
assets/resources/drres/
|
|
37
|
-
config/default.json
|
|
38
|
-
icons/pointer-yellow-60.png
|
|
39
|
-
icons/pointer-blue-60.png
|
|
40
|
-
icons/pointer-pink-60.png
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
模块职责:
|
|
44
|
-
|
|
45
|
-
- `core/TvUi.ts`:唯一公共入口,导出 `root/config/focus/icon/ads/input/api/back`。
|
|
46
|
-
- `core/TvUiRoot.ts`:创建全局常驻节点,初始化配置、焦点视觉、广告和遥控输入。
|
|
47
|
-
- `focus/`:焦点注册、移动、确认、scope、全局视觉层。
|
|
48
|
-
- `icon/`:根据配置加载本地或远程图标并缓存。
|
|
49
|
-
- `ad/`:slot 广告、多渠道 provider、mock fallback。
|
|
50
|
-
- `vendor/ad-sdk/`:聚合广告 SDK 和小米 adapter。
|
|
51
|
-
- `input/`:遥控器 keyCode 适配和输入分发。
|
|
52
|
-
- `config/`:默认配置、项目覆盖配置、本地配置合并。
|
|
53
|
-
|
|
54
|
-
## 接入顺序
|
|
55
|
-
|
|
56
|
-
### 1. 复制框架目录
|
|
57
|
-
|
|
58
|
-
把 `assets/scripts/drres` 和 `assets/resources/drres` 复制到目标项目,并确保 `.meta` 文件一起提交。Cocos 项目中 `.meta` 不可缺,否则资源 UUID 会变化。
|
|
59
|
-
|
|
60
|
-
### 2. 初始化 TvUi
|
|
61
|
-
|
|
62
|
-
在项目入口或平台初始化位置引入:
|
|
63
|
-
|
|
64
|
-
```ts
|
|
65
|
-
import TvUi from "../scripts/drres/core/TvUi";
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
推荐封装一个项目级初始化方法,避免重复初始化:
|
|
69
|
-
|
|
70
|
-
```ts
|
|
71
|
-
static tvUiInited = false;
|
|
72
|
-
|
|
73
|
-
static initTvUi() {
|
|
74
|
-
if (Platform.tvUiInited) return;
|
|
75
|
-
Platform.tvUiInited = true;
|
|
76
|
-
|
|
77
|
-
TvUi.init({
|
|
78
|
-
cpId: "ppl",
|
|
79
|
-
version: Consts.GAME_VERSION,
|
|
80
|
-
designWidth: 1920,
|
|
81
|
-
designHeight: 1080,
|
|
82
|
-
enableCursor: true,
|
|
83
|
-
configPath: "drres/config/default",
|
|
84
|
-
focus: {
|
|
85
|
-
enabled: true,
|
|
86
|
-
defaultIconKey: "default"
|
|
87
|
-
},
|
|
88
|
-
adSdk: {
|
|
89
|
-
platform: "xiaomi"
|
|
90
|
-
},
|
|
91
|
-
ads: {
|
|
92
|
-
reward: {
|
|
93
|
-
enabled: true,
|
|
94
|
-
mode: "reward",
|
|
95
|
-
channels: [
|
|
96
|
-
{ type: "aggregate", priority: 1, reward_type: "reward" },
|
|
97
|
-
{ type: "mock", priority: 100 }
|
|
98
|
-
]
|
|
99
|
-
},
|
|
100
|
-
popup: {
|
|
101
|
-
enabled: true,
|
|
102
|
-
mode: "popup",
|
|
103
|
-
channels: [
|
|
104
|
-
{ type: "aggregate", priority: 1 },
|
|
105
|
-
{ type: "mock", priority: 100 }
|
|
106
|
-
]
|
|
107
|
-
},
|
|
108
|
-
game: {
|
|
109
|
-
enabled: true,
|
|
110
|
-
mode: "popup",
|
|
111
|
-
channels: [
|
|
112
|
-
{ type: "aggregate", priority: 1 },
|
|
113
|
-
{ type: "mock", priority: 100 }
|
|
114
|
-
]
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
`ppl` 项目参考:`ppl/assets/framework/Platform.ts` 的 `Platform.initTvUi()`。
|
|
122
|
-
|
|
123
|
-
`TvUi.init()` 会自动:
|
|
124
|
-
|
|
125
|
-
- 创建并常驻 `TvUiRoot`。
|
|
126
|
-
- 加载 `resources/drres/config/default.json`。
|
|
127
|
-
- 初始化焦点层、图标、广告、遥控输入。
|
|
128
|
-
- 暴露 `window.TvUi` 和 `window.drres`。
|
|
129
|
-
- 注册生命周期回调到原生 bridge。
|
|
130
|
-
|
|
131
|
-
### 3. 准备默认配置
|
|
132
|
-
|
|
133
|
-
默认配置位于:
|
|
134
|
-
|
|
135
|
-
```text
|
|
136
|
-
assets/resources/drres/config/default.json
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
项目可以在 `TvUi.init()` 里覆盖配置,也可以修改默认配置。推荐把公共默认值放在 `default.json`,项目差异放在初始化参数里。
|
|
140
|
-
|
|
141
|
-
## 焦点接入
|
|
142
|
-
|
|
143
|
-
焦点接入分三种场景:普通页面、复杂页面、弹窗。
|
|
144
|
-
|
|
145
|
-
### 普通页面:自动注册按钮
|
|
146
|
-
|
|
147
|
-
如果页面上的可操作元素都是 Cocos `cc.Button`,直接注册整个页面根节点:
|
|
148
|
-
|
|
149
|
-
```ts
|
|
150
|
-
onShown() {
|
|
151
|
-
Platform.initTvUi();
|
|
152
|
-
TvUi.focus.reset();
|
|
153
|
-
TvUi.focus.pushScope("main", this.node);
|
|
154
|
-
TvUi.focus.registerButtons(this.node);
|
|
155
|
-
TvUi.focus.focusNode(this.findButtonByHandler("click_play"));
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
onHidden() {
|
|
159
|
-
TvUi.focus.unregisterByRoot(this.node);
|
|
160
|
-
TvUi.focus.popScope("main");
|
|
161
|
-
}
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
注册后:
|
|
165
|
-
|
|
166
|
-
- 方向键会按节点位置自动寻找下一个焦点。
|
|
167
|
-
- 确认键会触发按钮 `clickEvents`。
|
|
168
|
-
- 焦点节点会按默认 `focusScale` 放大。
|
|
169
|
-
- 全局图标会跟随当前焦点。
|
|
170
|
-
|
|
171
|
-
`ppl` 主界面参考:
|
|
172
|
-
|
|
173
|
-
```ts
|
|
174
|
-
setupTvControls() {
|
|
175
|
-
Platform.initTvUi();
|
|
176
|
-
TvUi.focus.reset();
|
|
177
|
-
TvUi.focus.pushScope("main", this.node);
|
|
178
|
-
TvUi.focus.registerButtons(this.node);
|
|
179
|
-
this.focusPlayButton();
|
|
180
|
-
TvUi.back.setFallback(() => {
|
|
181
|
-
TvGlobalExit.showConfirm();
|
|
182
|
-
return true;
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### 复杂页面:手动注册焦点
|
|
188
|
-
|
|
189
|
-
如果页面布局复杂,或者要指定方向关系、图标、点击逻辑,用 `register` 手动注册:
|
|
190
|
-
|
|
191
|
-
```ts
|
|
192
|
-
TvUi.focus.register(startButton, {
|
|
193
|
-
root: this.node,
|
|
194
|
-
focusId: "main_start",
|
|
195
|
-
iconKey: "yellow",
|
|
196
|
-
up: "main_rank",
|
|
197
|
-
down: "main_sign",
|
|
198
|
-
left: "main_lottery",
|
|
199
|
-
right: "main_shop",
|
|
200
|
-
focusScale: 1.08,
|
|
201
|
-
onClick: () => {
|
|
202
|
-
this.click_play();
|
|
203
|
-
},
|
|
204
|
-
onFocus: () => {
|
|
205
|
-
// 可选:业务高亮
|
|
206
|
-
},
|
|
207
|
-
onBlur: () => {
|
|
208
|
-
// 可选:取消业务高亮
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
指定焦点:
|
|
214
|
-
|
|
215
|
-
```ts
|
|
216
|
-
TvUi.focus.focusNode(startButton);
|
|
217
|
-
TvUi.focus.focus("main_start");
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
清理页面焦点:
|
|
221
|
-
|
|
222
|
-
```ts
|
|
223
|
-
TvUi.focus.unregisterByRoot(this.node);
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
复杂 TV 页面推荐显式配置 `up/down/left/right`,减少自动坐标推断跳错。
|
|
227
|
-
|
|
228
|
-
### FocusItem 组件
|
|
229
|
-
|
|
230
|
-
需要在编辑器里声明方向关系时,可以给节点挂 `FocusItem`:
|
|
231
|
-
|
|
232
|
-
```ts
|
|
233
|
-
@property
|
|
234
|
-
focusId: string = "";
|
|
235
|
-
|
|
236
|
-
@property
|
|
237
|
-
iconKey: string = "";
|
|
238
|
-
|
|
239
|
-
@property
|
|
240
|
-
up: string = "";
|
|
241
|
-
@property
|
|
242
|
-
down: string = "";
|
|
243
|
-
@property
|
|
244
|
-
left: string = "";
|
|
245
|
-
@property
|
|
246
|
-
right: string = "";
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
`FocusItem` 只声明焦点关系和图标 key,不负责画焦点框,也不负责画图标。
|
|
250
|
-
|
|
251
|
-
### 弹窗:独立 scope
|
|
252
|
-
|
|
253
|
-
弹窗打开时要把焦点限制在弹窗内,关闭后恢复上一层焦点:
|
|
254
|
-
|
|
255
|
-
```ts
|
|
256
|
-
onShown() {
|
|
257
|
-
TvUi.focus.pushScope("dialog:shop", this.node);
|
|
258
|
-
TvUi.focus.registerButtons(this.node);
|
|
259
|
-
TvUi.focus.focusNode(this.closeButton.node);
|
|
260
|
-
TvUi.back.push(this.onBack);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
onHidden() {
|
|
264
|
-
TvUi.focus.unregisterByRoot(this.node);
|
|
265
|
-
TvUi.focus.popScope("dialog:shop");
|
|
266
|
-
TvUi.back.remove(this.onBack);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
private onBack = () => {
|
|
270
|
-
this.click_close();
|
|
1
|
+
# PlatformAdapter & KeyAdapter 使用说明
|
|
2
|
+
## 一、PlatformAdapter API
|
|
3
|
+
### 1.1 初始化
|
|
4
|
+
```typescript
|
|
5
|
+
// 在游戏入口处调用一次
|
|
6
|
+
await PlatformAdapter.init(
|
|
7
|
+
"游戏中文名", // cnName: string
|
|
8
|
+
123456, // minigameID: number
|
|
9
|
+
FingerStyle.Normal // focusIcon: 焦点图标样式
|
|
10
|
+
);
|
|
11
|
+
```
|
|
12
|
+
### 1.2 场景 / 窗口栈
|
|
13
|
+
```typescript
|
|
14
|
+
PlatformAdapter.showScene(mainMenuNode);
|
|
15
|
+
```
|
|
16
|
+
// 关闭一个预制体场景(从栈中移除,不销毁节点)
|
|
17
|
+
PlatformAdapter.hideScene(sceneNode);
|
|
18
|
+
### 4.2 弹窗页面
|
|
19
|
+
```typescript
|
|
20
|
+
PlatformAdapter.showWindow(popupNode, () => {
|
|
21
|
+
popupNode.destroy();
|
|
271
22
|
return true;
|
|
272
|
-
};
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
`ppl` 已封装弹窗焦点和返回键:
|
|
276
|
-
|
|
277
|
-
```ts
|
|
278
|
-
this._tvCleanup = bindTvDialogControls(this, this.click_close, {
|
|
279
|
-
firstFocusNode: this.closeButton.node
|
|
280
23
|
});
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
TvUi.back.setFallback(() => {
|
|
303
|
-
TvGlobalExit.showConfirm();
|
|
304
|
-
return true;
|
|
305
|
-
});
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
弹窗返回:
|
|
309
|
-
|
|
310
|
-
```ts
|
|
311
|
-
const backHandler = () => {
|
|
312
|
-
this.click_close();
|
|
313
|
-
return true;
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
TvUi.back.push(backHandler);
|
|
317
|
-
TvUi.back.remove(backHandler);
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
`return true` 表示已处理返回键;`return false` 表示继续交给下一层 handler 或 fallback。
|
|
321
|
-
|
|
322
|
-
## 图标配置
|
|
323
|
-
|
|
324
|
-
默认图标位于:
|
|
325
|
-
|
|
326
|
-
```text
|
|
327
|
-
assets/resources/drres/icons/
|
|
328
|
-
pointer-yellow-60.png
|
|
329
|
-
pointer-blue-60.png
|
|
330
|
-
pointer-pink-60.png
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
默认配置在 `assets/resources/drres/config/default.json`:
|
|
334
|
-
|
|
335
|
-
```json
|
|
336
|
-
{
|
|
337
|
-
"focus": {
|
|
338
|
-
"enabled": true,
|
|
339
|
-
"frameEnabled": false,
|
|
340
|
-
"defaultIconKey": "default",
|
|
341
|
-
"iconPlacement": "bottomRight",
|
|
342
|
-
"iconOffsetX": -20,
|
|
343
|
-
"iconOffsetY": 20
|
|
344
|
-
},
|
|
345
|
-
"icons": {
|
|
346
|
-
"default": {
|
|
347
|
-
"path": "drres/icons/pointer-yellow-60",
|
|
348
|
-
"width": 60,
|
|
349
|
-
"height": 60,
|
|
350
|
-
"offsetX": -20,
|
|
351
|
-
"offsetY": 20
|
|
24
|
+
// 刷新导航
|
|
25
|
+
PlatformAdapter.refreshFocus(popupNode);
|
|
26
|
+
// 关闭界面窗口
|
|
27
|
+
PlatformAdapter.hideWindow(popupNode);
|
|
28
|
+
```
|
|
29
|
+
**场景 vs 窗口:**
|
|
30
|
+
| 特性 | showScene | showWindow |
|
|
31
|
+
|------|-----------|------------|
|
|
32
|
+
| 返回键处理 | 回溯到上一个场景,或退出确认 | 直接 `destroy()` 关闭 |
|
|
33
|
+
| 场景切换 | 自动隐藏上一个场景 | 不涉及场景切换 |
|
|
34
|
+
### 1.4 Toast
|
|
35
|
+
```typescript
|
|
36
|
+
PlatformAdapter.showTip("提示文本"); // 第二个参数:显示时长(ms),默认1500
|
|
37
|
+
```
|
|
38
|
+
### 1.5 广告
|
|
39
|
+
```typescript
|
|
40
|
+
const success = await PlatformAdapter.showRewardVideo(
|
|
41
|
+
EVideoScene.GameOver, // 场景枚举
|
|
42
|
+
"coin_double", // 奖励类型
|
|
43
|
+
() => {
|
|
44
|
+
console.log("广告看完给奖励,未看完或者报错会自动提示,不需要自己处理");
|
|
352
45
|
}
|
|
353
|
-
|
|
354
|
-
}
|
|
46
|
+
);
|
|
355
47
|
```
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
- `width/height`:图标显示尺寸。
|
|
362
|
-
- `offsetX/offsetY`:当前图标自己的偏移,优先级高于 `focus.iconOffsetX/Y`。
|
|
363
|
-
- `iconPlacement`:支持 `topRight`、`bottomRight`。
|
|
364
|
-
- `frameEnabled`:是否绘制全局焦点框。当前默认 `false`,只显示图标和按钮自身缩放。
|
|
365
|
-
|
|
366
|
-
切换默认图标:
|
|
367
|
-
|
|
368
|
-
```ts
|
|
369
|
-
TvUi.icon.setIconTheme("blue");
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
运行时更新配置并保存到本地:
|
|
373
|
-
|
|
374
|
-
```ts
|
|
375
|
-
TvUi.config.updateConfig({
|
|
376
|
-
focus: {
|
|
377
|
-
defaultIconKey: "pink"
|
|
378
|
-
}
|
|
379
|
-
}, true);
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
## 广告接入
|
|
383
|
-
|
|
384
|
-
### 调用原则
|
|
385
|
-
|
|
386
|
-
业务代码不要直接调原生广告,也不要直接调具体平台 adapter。推荐优先级:
|
|
387
|
-
|
|
388
|
-
1. 项目已有封装:`showRewardVideo()`、`showTvDialogAd()`、`hideTvDialogAd()`。
|
|
389
|
-
2. 框架 API:`TvUi.ads.showReward()`、`TvUi.ads.showPopup()`、`TvUi.ads.showSlot()`。
|
|
390
|
-
3. 新平台能力:扩展 `vendor/ad-sdk/adapters/`。
|
|
391
|
-
|
|
392
|
-
当前真实广告由 `AggregateAdProvider` 接入 `vendor/ad-sdk`,默认渠道链路:
|
|
393
|
-
|
|
394
|
-
```text
|
|
395
|
-
aggregate(1) -> mock(100)
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
规则:
|
|
399
|
-
|
|
400
|
-
- `enabled === false` 的渠道会跳过。
|
|
401
|
-
- provider 不存在或不可用会尝试下一渠道。
|
|
402
|
-
- provider 返回 `failed` 或 Promise reject 会尝试下一渠道。
|
|
403
|
-
- 奖励广告用户关闭返回 `closed`,触发 `onClose`,不发奖励,不切到下一渠道。
|
|
404
|
-
- 全部真实渠道失败后进入 `mock`。
|
|
405
|
-
|
|
406
|
-
### Reward 广告
|
|
407
|
-
|
|
408
|
-
直接调用框架:
|
|
409
|
-
|
|
410
|
-
```ts
|
|
411
|
-
TvUi.ads.showReward({
|
|
412
|
-
trigger_scene: "shop",
|
|
413
|
-
reward_type: "shop",
|
|
414
|
-
onSuccess: data => {
|
|
415
|
-
giveCoin();
|
|
416
|
-
},
|
|
417
|
-
onClose: data => {
|
|
418
|
-
Toast.make("必须看完广告才能获得奖励");
|
|
419
|
-
},
|
|
420
|
-
onFail: error => {
|
|
421
|
-
Toast.make("广告暂不可用,请稍后再试");
|
|
422
|
-
}
|
|
48
|
+
### 1.6 帮助窗口(首次引导)
|
|
49
|
+
```typescript
|
|
50
|
+
// 首次启动时显示帮助窗口,按确认键或返回键关闭,触发回调
|
|
51
|
+
PlatformAdapter.showHelperWin('skeleton', () => {
|
|
52
|
+
this.startGamePrepare();
|
|
423
53
|
});
|
|
424
54
|
```
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
奖励成功后执行业务复活:
|
|
449
|
-
|
|
450
|
-
```ts
|
|
451
|
-
revive() {
|
|
452
|
-
this.refreshReviveRound();
|
|
453
|
-
if (this.revive_count >= this.max_revive_count) {
|
|
454
|
-
return;
|
|
55
|
+
### 1.7 数据上报
|
|
56
|
+
```typescript
|
|
57
|
+
// 单次上报
|
|
58
|
+
PlatformAdapter.report(AnalyticsEvent.StartGame, AnalyticsAction.Click);
|
|
59
|
+
// 批量上报
|
|
60
|
+
PlatformAdapter.reportBatch([AnalyticsEvent.StartGame, AnalyticsEvent.LevelComplete]);
|
|
61
|
+
```
|
|
62
|
+
### 1.8 属性
|
|
63
|
+
```typescript
|
|
64
|
+
PlatformAdapter.isCocos // 是否 Cocos 环境
|
|
65
|
+
PlatformAdapter.isWebBridge // 是否基座环境
|
|
66
|
+
PlatformAdapter.canWatchVideo // 是否可以观看视频(小米 TV)
|
|
67
|
+
PlatformAdapter.isVIP // 是否 VIP 用户
|
|
68
|
+
```
|
|
69
|
+
## 二、KeyAdapter 按键适配
|
|
70
|
+
### 2.1 外部回调
|
|
71
|
+
```typescript
|
|
72
|
+
// 监听所有按键按下(在默认处理前执行)
|
|
73
|
+
KeyAdapter.onKeyDown = (key: KeyCode) => {
|
|
74
|
+
if (key === KeyCode.Enter) {
|
|
75
|
+
// 自定义处理
|
|
455
76
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
完整链路:
|
|
464
|
-
|
|
465
|
-
```text
|
|
466
|
-
按钮 click_revive
|
|
467
|
-
-> showRewardVideo("revive_pop", "extra_life", this.revive, this)
|
|
468
|
-
-> TvUi.ads.showReward
|
|
469
|
-
-> AggregateAdProvider
|
|
470
|
-
-> vendor/ad-sdk
|
|
471
|
-
-> 小米 adapter
|
|
472
|
-
-> 原生 requestAd
|
|
473
|
-
-> onReward 后调用 revive
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
`ppl` 参考:`ppl/assets/Game/Scripts/ui/LoseDialog.ts`。
|
|
477
|
-
|
|
478
|
-
### Popup 广告
|
|
479
|
-
|
|
480
|
-
直接调用框架:
|
|
481
|
-
|
|
482
|
-
```ts
|
|
483
|
-
TvUi.ads.showPopup({
|
|
484
|
-
scene: "home_popup",
|
|
485
|
-
onLoad: data => {
|
|
486
|
-
console.log("popup loaded", data);
|
|
487
|
-
},
|
|
488
|
-
onFail: error => {
|
|
489
|
-
console.log("popup failed", error);
|
|
490
|
-
}
|
|
491
|
-
});
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
隐藏 popup:
|
|
495
|
-
|
|
496
|
-
```ts
|
|
497
|
-
TvUi.ads.hidePopup("home_popup");
|
|
498
|
-
```
|
|
499
|
-
|
|
500
|
-
项目内推荐封装:
|
|
501
|
-
|
|
502
|
-
```ts
|
|
503
|
-
showTvDialogAd("lose");
|
|
504
|
-
hideTvDialogAd("lose");
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
`ppl` 参考:
|
|
508
|
-
|
|
509
|
-
- `LoseDialog.onShown()` 调 `showTvDialogAd("lose")`。
|
|
510
|
-
- `ShopDialog.onShown()` 调 `showTvDialogAd("shop")`。
|
|
511
|
-
- `WinDialog.onShown()` 调 `showTvDialogAd("win")`。
|
|
512
|
-
|
|
513
|
-
### 自定义 slot
|
|
514
|
-
|
|
515
|
-
配置:
|
|
516
|
-
|
|
517
|
-
```json
|
|
518
|
-
{
|
|
519
|
-
"ads": {
|
|
520
|
-
"home_popup": {
|
|
521
|
-
"enabled": true,
|
|
522
|
-
"mode": "popup",
|
|
523
|
-
"channels": [
|
|
524
|
-
{ "type": "aggregate", "priority": 1, "placementId": "home_popup" },
|
|
525
|
-
{ "type": "mock", "priority": 100 }
|
|
526
|
-
]
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
调用:
|
|
533
|
-
|
|
534
|
-
```ts
|
|
535
|
-
TvUi.ads.showSlot("home_popup", {
|
|
536
|
-
scene: "home_popup",
|
|
537
|
-
onLoad: data => {},
|
|
538
|
-
onFail: error => {}
|
|
539
|
-
});
|
|
540
|
-
```
|
|
541
|
-
|
|
542
|
-
### 聚合 SDK 配置
|
|
543
|
-
|
|
544
|
-
`AggregateAdProvider` 通过 `vendor/ad-sdk` 统一接入真实广告。当前 SDK 内置小米 adapter。
|
|
545
|
-
|
|
546
|
-
SDK 默认原生 action:
|
|
547
|
-
|
|
548
|
-
```text
|
|
549
|
-
requestAd
|
|
550
|
-
requestPopupAd
|
|
551
|
-
hidePopupAd
|
|
552
|
-
```
|
|
553
|
-
|
|
554
|
-
SDK 配置:
|
|
555
|
-
|
|
556
|
-
```json
|
|
557
|
-
{
|
|
558
|
-
"adSdk": {
|
|
559
|
-
"platform": "xiaomi",
|
|
560
|
-
"adapterConfig": {
|
|
561
|
-
"cpId": "ppl"
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
```
|
|
566
|
-
|
|
567
|
-
channel 配置:
|
|
568
|
-
|
|
569
|
-
```json
|
|
570
|
-
{
|
|
571
|
-
"type": "aggregate",
|
|
572
|
-
"priority": 1,
|
|
573
|
-
"placementId": "home_popup"
|
|
574
|
-
}
|
|
575
|
-
```
|
|
576
|
-
|
|
577
|
-
支持回调:
|
|
578
|
-
|
|
579
|
-
```text
|
|
580
|
-
onReward
|
|
581
|
-
onAdClosed
|
|
582
|
-
onAdFailed
|
|
583
|
-
onPopupAdLoaded
|
|
584
|
-
onPopupAdClosed
|
|
585
|
-
onPopupAdFailed
|
|
586
|
-
```
|
|
587
|
-
|
|
588
|
-
后续新增平台时优先扩展:
|
|
589
|
-
|
|
590
|
-
```text
|
|
591
|
-
assets/scripts/drres/vendor/ad-sdk/adapters/
|
|
592
|
-
```
|
|
593
|
-
|
|
594
|
-
业务和 TV UI slot 调用保持不变。
|
|
595
|
-
|
|
596
|
-
### 自营 Provider
|
|
597
|
-
|
|
598
|
-
`SelfAdProvider` 适合本地兜底图片:
|
|
599
|
-
|
|
600
|
-
```json
|
|
601
|
-
{
|
|
602
|
-
"type": "self",
|
|
603
|
-
"priority": 50,
|
|
604
|
-
"imagePath": "drres/ads/home-popup"
|
|
605
|
-
}
|
|
606
|
-
```
|
|
607
|
-
|
|
608
|
-
调用时传入 `container`:
|
|
609
|
-
|
|
610
|
-
```ts
|
|
611
|
-
TvUi.ads.showSlot("home_popup", {
|
|
612
|
-
container: adNode,
|
|
613
|
-
scene: "home_popup"
|
|
614
|
-
});
|
|
615
|
-
```
|
|
616
|
-
|
|
617
|
-
说明:当前自营广告主要支持本地 `imagePath`。远程 `imageUrl` 是后续增强项。
|
|
618
|
-
|
|
619
|
-
### 自定义 Provider
|
|
620
|
-
|
|
621
|
-
新增 provider:
|
|
622
|
-
|
|
623
|
-
```ts
|
|
624
|
-
import IAdProvider, { AdRuntimeData, AdShowResult } from "./IAdProvider";
|
|
625
|
-
|
|
626
|
-
export default class CustomAdProvider implements IAdProvider {
|
|
627
|
-
public type: string = "custom";
|
|
628
|
-
|
|
629
|
-
public isAvailable(): boolean {
|
|
630
|
-
return true;
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
public load(data: AdRuntimeData): Promise<AdRuntimeData> {
|
|
634
|
-
return Promise.resolve(data);
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
public show(data: AdRuntimeData): Promise<AdShowResult> {
|
|
638
|
-
return Promise.resolve({
|
|
639
|
-
status: "loaded",
|
|
640
|
-
data: {}
|
|
641
|
-
});
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
public hide(slotId: string): void {
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
```
|
|
648
|
-
|
|
649
|
-
在 `AdManager.init()` 注册:
|
|
650
|
-
|
|
651
|
-
```ts
|
|
652
|
-
this.registerProvider(new CustomAdProvider());
|
|
653
|
-
```
|
|
654
|
-
|
|
655
|
-
配置:
|
|
656
|
-
|
|
657
|
-
```json
|
|
658
|
-
{ "type": "custom", "priority": 3, "placementId": "custom_slot" }
|
|
659
|
-
```
|
|
660
|
-
|
|
661
|
-
## ppl 接入实例
|
|
662
|
-
|
|
663
|
-
`ppl` 项目的接入方式可以直接作为新项目模板:
|
|
664
|
-
|
|
665
|
-
1. `Platform.login()` 或项目入口调用 `Platform.initTvUi()`。
|
|
666
|
-
2. 主界面 `Main.setupTvControls()`:
|
|
667
|
-
- 隐藏分享入口。
|
|
668
|
-
- `TvUi.focus.reset()`。
|
|
669
|
-
- `TvUi.focus.pushScope("main", this.node)`。
|
|
670
|
-
- `TvUi.focus.registerButtons(this.node)`。
|
|
671
|
-
- 默认聚焦开始按钮。
|
|
672
|
-
- `TvUi.back.setFallback()` 打开退出确认。
|
|
673
|
-
3. 打开子弹窗前调用 `suspendTvControlsForChildDialog()`,避免主界面焦点抢回。
|
|
674
|
-
4. 弹窗内调用 `bindTvDialogControls()` 注册按钮焦点和返回键。
|
|
675
|
-
5. 弹窗关闭后调用 cleanup,并恢复主界面焦点。
|
|
676
|
-
6. 奖励广告统一调用 `showRewardVideo(trigger_scene, reward_type, callback, target)`。
|
|
677
|
-
7. 插屏/浮层广告统一调用 `showTvDialogAd(scene)` 和 `hideTvDialogAd(scene)`。
|
|
678
|
-
|
|
679
|
-
主界面最小示例:
|
|
680
|
-
|
|
681
|
-
```ts
|
|
682
|
-
setupTvControls() {
|
|
683
|
-
Platform.initTvUi();
|
|
684
|
-
TvUi.focus.reset();
|
|
685
|
-
TvUi.focus.pushScope("main", this.node);
|
|
686
|
-
TvUi.focus.registerButtons(this.node);
|
|
687
|
-
this.focusPlayButton();
|
|
688
|
-
TvUi.back.setFallback(() => {
|
|
689
|
-
TvGlobalExit.showConfirm();
|
|
690
|
-
return true;
|
|
691
|
-
});
|
|
692
|
-
}
|
|
693
|
-
```
|
|
694
|
-
|
|
695
|
-
弹窗最小示例:
|
|
696
|
-
|
|
697
|
-
```ts
|
|
698
|
-
onShown() {
|
|
699
|
-
showTvDialogAd("shop");
|
|
700
|
-
this._tvCleanup = bindTvDialogControls(this, this.click_close, {
|
|
701
|
-
firstFocusNode: this.closeButton.node
|
|
702
|
-
});
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
onHidden() {
|
|
706
|
-
hideTvDialogAd("shop");
|
|
707
|
-
if (this._tvCleanup) {
|
|
708
|
-
this._tvCleanup();
|
|
709
|
-
this._tvCleanup = null;
|
|
77
|
+
};
|
|
78
|
+
// 监听所有按键抬起
|
|
79
|
+
KeyAdapter.onKeyUp = (key: KeyCode) => {
|
|
80
|
+
if (key === KeyCode.Up) {
|
|
81
|
+
// 自定义处理
|
|
710
82
|
}
|
|
711
|
-
}
|
|
712
|
-
```
|
|
713
|
-
|
|
714
|
-
奖励按钮最小示例:
|
|
715
|
-
|
|
716
|
-
```ts
|
|
717
|
-
click_free() {
|
|
718
|
-
showRewardVideo("shop", "shop", this.share_succ, this);
|
|
719
|
-
}
|
|
720
|
-
```
|
|
721
|
-
|
|
722
|
-
## 项目迁移规则
|
|
723
|
-
|
|
724
|
-
新项目和后续项目只允许使用:
|
|
725
|
-
|
|
726
|
-
```ts
|
|
727
|
-
import TvUi from "../scripts/drres/core/TvUi";
|
|
728
|
-
```
|
|
729
|
-
|
|
730
|
-
禁止新代码使用:
|
|
731
|
-
|
|
732
|
-
```text
|
|
733
|
-
TvKit
|
|
734
|
-
tvKit
|
|
735
|
-
code/tvkit
|
|
736
|
-
MiAPI
|
|
737
|
-
```
|
|
738
|
-
|
|
739
|
-
迁移检查:
|
|
740
|
-
|
|
741
|
-
```bash
|
|
742
|
-
rg "code/tvkit|TvKit|tvKit|MiAPI" ppl/assets
|
|
743
|
-
rg "scripts/drres/core/TvUi" ppl/assets -g "*.ts"
|
|
744
|
-
```
|
|
745
|
-
|
|
746
|
-
`ppl/assets/code` 应不存在。所有 TV UI 能力都从 `TvUi` facade 进入。
|
|
747
|
-
|
|
748
|
-
## 验收清单
|
|
749
|
-
|
|
750
|
-
基础焦点:
|
|
751
|
-
|
|
752
|
-
- 方向键可以在主界面按钮之间移动。
|
|
753
|
-
- 确认键触发当前焦点按钮点击。
|
|
754
|
-
- 当前焦点图标跟随按钮移动。
|
|
755
|
-
- 图标靠近屏幕边缘时不会超出屏幕。
|
|
756
|
-
- 不显示黄色全局焦点框时,按钮自身缩放/高亮仍正常。
|
|
757
|
-
|
|
758
|
-
弹窗和返回:
|
|
759
|
-
|
|
760
|
-
- 打开弹窗后焦点限制在弹窗 scope 内。
|
|
761
|
-
- 关闭弹窗后恢复主界面焦点。
|
|
762
|
-
- 返回键在弹窗内关闭弹窗。
|
|
763
|
-
- 主界面返回键打开退出确认或执行项目 fallback。
|
|
764
|
-
|
|
765
|
-
广告:
|
|
766
|
-
|
|
767
|
-
- 无 `AppBridge` 时真实渠道不可用,最终进入 `mock`。
|
|
768
|
-
- 聚合 SDK 成功时不进入 mock。
|
|
769
|
-
- 聚合 SDK 失败时进入 mock/fallback。
|
|
770
|
-
- 奖励广告用户关闭时触发 `onClose`,不发奖励,不切下一渠道。
|
|
771
|
-
|
|
772
|
-
静态检查:
|
|
773
|
-
|
|
774
|
-
```bash
|
|
775
|
-
rg "code/tvkit|TvKit|tvKit|MiAPI" ppl/assets
|
|
776
|
-
rg "XiaomiAdProvide[r]|type: \"xiaom[i]\"|requestAggregateA[d]|requestAggregatePopupA[d]" ppl/assets/scripts/drres ppl/assets/resources/drres/config/default.json ppl/assets/framework/Platform.ts
|
|
777
|
-
git diff --check
|
|
83
|
+
};
|
|
778
84
|
```
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
确认业务奖励只写在 `onSuccess` 或 `showRewardVideo` 的成功回调里。用户关闭广告只会触发 `onClose`,不会发奖励。
|
|
797
|
-
|
|
798
|
-
### 真实广告不可用
|
|
799
|
-
|
|
800
|
-
检查:
|
|
801
|
-
|
|
802
|
-
- `TvUi.api.hasBridge()` 是否为 `true`。
|
|
803
|
-
- 原生是否支持 `requestAd`、`requestPopupAd`、`hidePopupAd`。
|
|
804
|
-
- `adSdk.platform` 是否配置为当前 adapter 支持的平台。
|
|
805
|
-
- 渠道失败后是否已经进入 `mock` fallback。
|
|
806
|
-
|
|
807
|
-
## 后续增强
|
|
808
|
-
|
|
809
|
-
当前框架已覆盖 v1 接入主流程,以下能力可按项目需要继续补:
|
|
810
|
-
|
|
811
|
-
- 远程配置拉取和合并。
|
|
812
|
-
- 正式设置页,用于切换图标、调整偏移、开关广告渠道。
|
|
813
|
-
- 远程自营广告图片。
|
|
814
|
-
- 广告曝光、点击、关闭统一埋点上报。
|
|
85
|
+
## 三、KeyCode / KeyAction 枚举
|
|
86
|
+
```typescript
|
|
87
|
+
enum KeyCode {
|
|
88
|
+
Up = 'up',
|
|
89
|
+
Down = 'down',
|
|
90
|
+
Left = 'left',
|
|
91
|
+
Right = 'right',
|
|
92
|
+
Enter = 'enter',
|
|
93
|
+
Back = 'back',
|
|
94
|
+
Menu = 'menu',
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
> 注意:`KeyCode` 枚举值是字符串(`'up'`、`'down'` 等),比较时用 `KeyCode.Up` 形式,不要直接写字符串字面量。
|
|
98
|
+
---
|
|
99
|
+
## 四、注意事项
|
|
100
|
+
1. **防重复机制**:`KeyAdapter` 内部有 150ms 防重复窗口,避免 AdSdk 和 `cc.systemEvent` 双路输入导致重复响应
|