drgame-cc 1.0.52 → 1.0.55
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/drscript/Define.ts +91 -5
- package/drscript/KeyAdapter.ts +11 -0
- package/drscript/PlatformAdapter.ts +6 -6
- package/drscript/README.md +1 -7
- package/drscript/component/ExitWin.ts +0 -4
- package/drscript/virtualgamepad/VirtualGamepad.ts +638 -0
- package/drscript/virtualgamepad/VirtualGamepadView.ts +311 -280
- package/package.json +1 -1
- package/drscript/virtualgamepad/VirtualGamepadClient.ts +0 -214
- package/drscript/virtualgamepad/VirtualGamepadConfig.ts +0 -70
- package/drscript/virtualgamepad/VirtualGamepadManager.ts +0 -809
|
@@ -1,346 +1,377 @@
|
|
|
1
|
-
import VirtualGamepadManager, { VirtualGamepadControlInput, VirtualGamepadMoveInput
|
|
1
|
+
import VirtualGamepadManager, { VirtualGamepadControlInput, VirtualGamepadMoveInput } from "./VirtualGamepad";
|
|
2
|
+
import FocusManager from "../focus/FocusManager";
|
|
3
|
+
import { KeyAdapter } from "../KeyAdapter";
|
|
4
|
+
import { KeyCode } from "../ad-sdk/ad-sdk";
|
|
5
|
+
|
|
6
|
+
/** 虚拟手柄按键枚举 */
|
|
7
|
+
export enum GamepadKey {
|
|
8
|
+
Up = "up",
|
|
9
|
+
Down = "down",
|
|
10
|
+
Left = "left",
|
|
11
|
+
Right = "right",
|
|
12
|
+
A = "a",
|
|
13
|
+
B = "b",
|
|
14
|
+
X = "x",
|
|
15
|
+
Y = "y",
|
|
16
|
+
LB = "lb",
|
|
17
|
+
RB = "rb",
|
|
18
|
+
LT = "lt",
|
|
19
|
+
RT = "rt",
|
|
20
|
+
Back = "back",
|
|
21
|
+
Menu = "menu",
|
|
22
|
+
}
|
|
2
23
|
|
|
3
|
-
const FIGHT_UI_OK_LONG_PRESS_SECONDS = 1.25;
|
|
4
24
|
const VIRTUAL_GAMEPAD_TOP_Z_INDEX = cc.macro.MAX_ZINDEX;
|
|
5
|
-
const VIRTUAL_GAMEPAD_PANEL_WIDTH = 420;
|
|
6
|
-
const VIRTUAL_GAMEPAD_PANEL_HEIGHT = 450;
|
|
7
25
|
const VIRTUAL_GAMEPAD_SUN_CODE_SIZE = 230;
|
|
8
26
|
const VIRTUAL_GAMEPAD_BADGE_WIDTH = 230;
|
|
9
27
|
const VIRTUAL_GAMEPAD_BADGE_HEIGHT = 48;
|
|
10
28
|
|
|
29
|
+
const JOYSTICK_DEAD_ZONE = 0.3;
|
|
30
|
+
|
|
31
|
+
/** 标准按键 → KeyCode 映射 */
|
|
32
|
+
const KEY_MAP: Record<string, KeyCode> = {
|
|
33
|
+
[GamepadKey.Up]: KeyCode.Up, [GamepadKey.Down]: KeyCode.Down,
|
|
34
|
+
[GamepadKey.Left]: KeyCode.Left, [GamepadKey.Right]: KeyCode.Right,
|
|
35
|
+
[GamepadKey.A]: KeyCode.Enter, [GamepadKey.B]: KeyCode.Back,
|
|
36
|
+
[GamepadKey.Back]: KeyCode.Back, [GamepadKey.Menu]: KeyCode.Menu,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/** 扩展按键列表(无 KeyCode 对应,通过 onExtendedKey 回调暴露) */
|
|
40
|
+
const EXTENDED_KEYS: Record<string, true> = {
|
|
41
|
+
[GamepadKey.X]: true, [GamepadKey.Y]: true,
|
|
42
|
+
[GamepadKey.LB]: true, [GamepadKey.RB]: true,
|
|
43
|
+
[GamepadKey.LT]: true, [GamepadKey.RT]: true,
|
|
44
|
+
};
|
|
45
|
+
|
|
11
46
|
export class VirtualGamepadView extends cc.Component {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
47
|
+
/**
|
|
48
|
+
* 扩展按键回调 — X/Y/LB/RB/LT/RT 等无 KeyCode 对应的按键
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* VirtualGamepadView.onExtendedKey = (key, pressed) => {
|
|
52
|
+
* if (!pressed) return;
|
|
53
|
+
* switch (key) {
|
|
54
|
+
* case GamepadKey.X: this.openMap(); break;
|
|
55
|
+
* case GamepadKey.Y: this.openBag(); break;
|
|
56
|
+
* case GamepadKey.LB: this.switchWeapon(-1); break;
|
|
57
|
+
* case GamepadKey.RB: this.switchWeapon(1); break;
|
|
58
|
+
* case GamepadKey.LT: this.aim(); break;
|
|
59
|
+
* case GamepadKey.RT: this.fire(); break;
|
|
60
|
+
* }
|
|
61
|
+
* };
|
|
62
|
+
*/
|
|
63
|
+
public static onExtendedKey: ((key: GamepadKey, pressed: boolean) => void) | null = null;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 摇杆回调 — 返回方向向量 (x, y),范围 [-1, 1]
|
|
67
|
+
* 摇杆回中时回调 (0, 0) 表示停止
|
|
68
|
+
*/
|
|
69
|
+
public static onJoystick: ((x: number, y: number) => void) | null = null;
|
|
70
|
+
|
|
71
|
+
// ---- 内部状态 ----
|
|
72
|
+
private _panel: cc.Node | null = null;
|
|
73
|
+
private _badge: cc.Node | null = null;
|
|
74
|
+
private _sunCodeSprite: cc.Sprite | null = null;
|
|
75
|
+
private _sunCodeLoadingLabel: cc.Label | null = null;
|
|
76
|
+
private _sunCodeSource: string = "";
|
|
77
|
+
private _sunCodeLoading: string = "";
|
|
78
|
+
private _sunCodeLoadSerial: number = 0;
|
|
79
|
+
private _statusLabel: cc.Label | null = null;
|
|
80
|
+
private _roomLabel: cc.Label | null = null;
|
|
81
|
+
private _identityLabel: cc.Label | null = null;
|
|
82
|
+
private _badgeLabel: cc.Label | null = null;
|
|
83
|
+
private _statusHandler: ((status: any) => void) | null = null;
|
|
84
|
+
private _moveHandler: ((input: VirtualGamepadMoveInput) => void) | null = null;
|
|
85
|
+
private _controlHandler: ((input: VirtualGamepadControlInput) => void) | null = null;
|
|
86
|
+
private _moving: boolean = false;
|
|
30
87
|
|
|
31
88
|
protected onEnable(): void {
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
89
|
+
this.registerView();
|
|
90
|
+
this.registerInput();
|
|
34
91
|
}
|
|
35
92
|
|
|
36
93
|
protected onDisable(): void {
|
|
37
|
-
this.
|
|
38
|
-
this.
|
|
94
|
+
this.unregisterView();
|
|
95
|
+
this.unregisterInput();
|
|
39
96
|
}
|
|
40
97
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
98
|
+
// ====================================================================
|
|
99
|
+
// 输入处理
|
|
100
|
+
// ====================================================================
|
|
101
|
+
|
|
102
|
+
/** 摇杆 → 方向向量 (x, y) + 焦点导航近似 */
|
|
103
|
+
private _onMove = (input: VirtualGamepadMoveInput) => {
|
|
104
|
+
// 始终回调向量给外部
|
|
105
|
+
VirtualGamepadView.onJoystick?.(input.x, input.y);
|
|
106
|
+
|
|
107
|
+
// 摇杆回中,重置状态
|
|
108
|
+
if (input.x === 0 && input.y === 0) {
|
|
109
|
+
this._moving = false;
|
|
110
|
+
return;
|
|
46
111
|
}
|
|
47
|
-
VirtualGamepadManager.getInstance().start();
|
|
48
|
-
this.refreshVirtualGamepadView(VirtualGamepadManager.getInstance().getStatus());
|
|
49
|
-
}
|
|
50
112
|
|
|
51
|
-
|
|
52
|
-
if (this.
|
|
53
|
-
|
|
54
|
-
|
|
113
|
+
// 超出死区时近似方向键,驱动焦点导航
|
|
114
|
+
if (!this._moving && (Math.abs(input.x) > JOYSTICK_DEAD_ZONE || Math.abs(input.y) > JOYSTICK_DEAD_ZONE)) {
|
|
115
|
+
this._moving = true;
|
|
116
|
+
let dir: KeyCode | null = null;
|
|
117
|
+
if (Math.abs(input.x) > Math.abs(input.y)) {
|
|
118
|
+
dir = input.x > 0 ? KeyCode.Right : KeyCode.Left;
|
|
119
|
+
} else {
|
|
120
|
+
dir = input.y > 0 ? KeyCode.Up : KeyCode.Down;
|
|
121
|
+
}
|
|
122
|
+
if (dir) FocusManager.move(dir);
|
|
55
123
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/** 按键 → 标准键走 KeyAdapter,扩展键走 onExtendedKey */
|
|
127
|
+
private _onControl = (input: VirtualGamepadControlInput) => {
|
|
128
|
+
let key = (input.key || "").toLowerCase();
|
|
129
|
+
|
|
130
|
+
// 标准按键 → 对齐 KeyCode
|
|
131
|
+
let kc = KEY_MAP[key];
|
|
132
|
+
if (kc) {
|
|
133
|
+
if (input.pressed) {
|
|
134
|
+
KeyAdapter.onKeyDown?.(kc);
|
|
135
|
+
switch (kc) {
|
|
136
|
+
case KeyCode.Enter: FocusManager.confirm(); break;
|
|
137
|
+
case KeyCode.Left: case KeyCode.Right: case KeyCode.Up: case KeyCode.Down: FocusManager.move(kc); break;
|
|
138
|
+
case KeyCode.Back: KeyAdapter.onBack?.(); break;
|
|
139
|
+
}
|
|
140
|
+
} else {
|
|
141
|
+
KeyAdapter.onKeyUp?.(kc);
|
|
142
|
+
}
|
|
143
|
+
return;
|
|
60
144
|
}
|
|
61
|
-
|
|
62
|
-
|
|
145
|
+
|
|
146
|
+
// 扩展按键 → 通过 onExtendedKey 回调暴露
|
|
147
|
+
if (EXTENDED_KEYS[key]) {
|
|
148
|
+
VirtualGamepadView.onExtendedKey?.(key as GamepadKey, input.pressed);
|
|
63
149
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
this.
|
|
69
|
-
|
|
70
|
-
this.
|
|
71
|
-
this.
|
|
72
|
-
this.
|
|
73
|
-
this.
|
|
74
|
-
this.
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
private registerInput() {
|
|
153
|
+
let mgr = VirtualGamepadManager.getInstance();
|
|
154
|
+
this._moveHandler = this._moveHandler || ((i) => this._onMove(i));
|
|
155
|
+
mgr.on("move", this._moveHandler);
|
|
156
|
+
this._controlHandler = this._controlHandler || ((i) => this._onControl(i));
|
|
157
|
+
mgr.on("button", this._controlHandler);
|
|
158
|
+
mgr.on("shoulder", this._controlHandler);
|
|
159
|
+
mgr.on("trigger", this._controlHandler);
|
|
160
|
+
mgr.on("back", this._controlHandler);
|
|
75
161
|
}
|
|
76
162
|
|
|
77
|
-
private
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
// }
|
|
82
|
-
// if (!this._virtualGamepadConfirmHandler) {
|
|
83
|
-
// this._virtualGamepadConfirmHandler = (pressed: boolean, raw?: any) => this.applyVirtualGamepadConfirm(pressed, raw);
|
|
84
|
-
// VirtualGamepadManager.getInstance().onConfirm(this._virtualGamepadConfirmHandler);
|
|
85
|
-
// }
|
|
86
|
-
// if (!this._virtualGamepadControlHandler) {
|
|
87
|
-
// this._virtualGamepadControlHandler = (input: VirtualGamepadControlInput) => this.logVirtualGamepadControlInput(input);
|
|
88
|
-
// VirtualGamepadManager.getInstance().onControl(this._virtualGamepadControlHandler);
|
|
89
|
-
// }
|
|
90
|
-
// if (!this._virtualGamepadButtonHandler) {
|
|
91
|
-
// this._virtualGamepadButtonHandler = (input: VirtualGamepadControlInput) => this.applyVirtualGamepadButton(input);
|
|
92
|
-
// VirtualGamepadManager.getInstance().onButton(this._virtualGamepadButtonHandler);
|
|
93
|
-
// }
|
|
94
|
-
// if (!this._virtualGamepadBackHandler) {
|
|
95
|
-
// this._virtualGamepadBackHandler = (input: VirtualGamepadControlInput) => this.applyVirtualGamepadBack(input);
|
|
96
|
-
// VirtualGamepadManager.getInstance().onBack(this._virtualGamepadBackHandler);
|
|
97
|
-
// }
|
|
163
|
+
private unregisterInput() {
|
|
164
|
+
let mgr = VirtualGamepadManager.getInstance();
|
|
165
|
+
if (this._moveHandler) { mgr.off("move", this._moveHandler); this._moveHandler = null; }
|
|
166
|
+
if (this._controlHandler) { mgr.off("button", this._controlHandler); mgr.off("shoulder", this._controlHandler); mgr.off("trigger", this._controlHandler); mgr.off("back", this._controlHandler); this._controlHandler = null; }
|
|
98
167
|
}
|
|
99
168
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
this.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if (this._virtualGamepadButtonHandler) {
|
|
114
|
-
VirtualGamepadManager.getInstance().offButton(this._virtualGamepadButtonHandler);
|
|
115
|
-
this._virtualGamepadButtonHandler = null;
|
|
116
|
-
}
|
|
117
|
-
if (this._virtualGamepadBackHandler) {
|
|
118
|
-
VirtualGamepadManager.getInstance().offBack(this._virtualGamepadBackHandler);
|
|
119
|
-
this._virtualGamepadBackHandler = null;
|
|
169
|
+
// ====================================================================
|
|
170
|
+
// View 生命周期
|
|
171
|
+
// ====================================================================
|
|
172
|
+
|
|
173
|
+
private registerView() {
|
|
174
|
+
this.ensureNodes();
|
|
175
|
+
if (!this._statusHandler) {
|
|
176
|
+
this._statusHandler = (s: any) => {
|
|
177
|
+
// 手柄连接/断开时自动切换 KeyAdapter 模式
|
|
178
|
+
KeyAdapter.setVirtualGamepadMode(!!s.controllerConnected);
|
|
179
|
+
this.refreshView(s);
|
|
180
|
+
};
|
|
181
|
+
VirtualGamepadManager.getInstance().on("status", this._statusHandler);
|
|
120
182
|
}
|
|
183
|
+
VirtualGamepadManager.getInstance().start();
|
|
184
|
+
this.refreshView(VirtualGamepadManager.getInstance().getStatus());
|
|
121
185
|
}
|
|
122
186
|
|
|
123
|
-
private
|
|
124
|
-
if (this.
|
|
125
|
-
|
|
126
|
-
|
|
187
|
+
private unregisterView() {
|
|
188
|
+
if (this._statusHandler) {
|
|
189
|
+
VirtualGamepadManager.getInstance().off("status", this._statusHandler);
|
|
190
|
+
this._statusHandler = null;
|
|
127
191
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
this.
|
|
132
|
-
this.
|
|
192
|
+
KeyAdapter.setVirtualGamepadMode(false); // 恢复键盘/遥控器输入
|
|
193
|
+
VirtualGamepadManager.getInstance().setGameState("ended");
|
|
194
|
+
VirtualGamepadManager.getInstance().stop();
|
|
195
|
+
[this._panel, this._badge].forEach(n => { if (n && n.isValid) n.destroy(); });
|
|
196
|
+
this._panel = this._badge = null;
|
|
197
|
+
this._sunCodeSprite = this._sunCodeLoadingLabel = null;
|
|
198
|
+
this._sunCodeSource = this._sunCodeLoading = "";
|
|
199
|
+
this._sunCodeLoadSerial++;
|
|
200
|
+
this._statusLabel = this._roomLabel = this._identityLabel = this._badgeLabel = null;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private ensureNodes() {
|
|
204
|
+
if (this._panel && this._panel.isValid) { this.refreshLayout(); return; }
|
|
205
|
+
let top = this.getTopParent();
|
|
206
|
+
|
|
207
|
+
this._panel = new cc.Node("virtualGamepadPanel");
|
|
208
|
+
this._panel.setContentSize(420, 450);
|
|
209
|
+
this._panel.zIndex = VIRTUAL_GAMEPAD_TOP_Z_INDEX;
|
|
210
|
+
this._panel.parent = top;
|
|
211
|
+
this.drawBg(this._panel, 420, 450, new cc.Color(12, 20, 32, 242));
|
|
133
212
|
|
|
134
213
|
let accent = new cc.Node("accent");
|
|
135
|
-
accent.parent = this.
|
|
136
|
-
accent.y =
|
|
137
|
-
this.
|
|
214
|
+
accent.parent = this._panel;
|
|
215
|
+
accent.y = 222;
|
|
216
|
+
this.drawBg(accent, 420, 6, new cc.Color(38, 190, 196, 255));
|
|
138
217
|
|
|
139
|
-
let title = this.
|
|
140
|
-
title.node.parent = this.
|
|
218
|
+
let title = this.makeLabel("title", "手机虚拟手柄", 28, cc.Color.WHITE);
|
|
219
|
+
title.node.parent = this._panel;
|
|
141
220
|
title.node.y = 192;
|
|
142
221
|
|
|
143
|
-
let
|
|
144
|
-
|
|
145
|
-
|
|
222
|
+
let sub = this.makeLabel("subtitle", "微信扫码,手机即手柄", 17, new cc.Color(87, 214, 205, 255));
|
|
223
|
+
sub.node.parent = this._panel;
|
|
224
|
+
sub.node.y = 158;
|
|
146
225
|
|
|
147
226
|
let qrFrame = new cc.Node("qrFrame");
|
|
148
|
-
qrFrame.parent = this.
|
|
227
|
+
qrFrame.parent = this._panel;
|
|
149
228
|
qrFrame.y = 18;
|
|
150
|
-
this.
|
|
229
|
+
this.drawQrFrame(qrFrame, 246);
|
|
151
230
|
|
|
152
231
|
let sunCodeNode = new cc.Node("sunCode");
|
|
153
232
|
sunCodeNode.parent = qrFrame;
|
|
154
233
|
sunCodeNode.zIndex = 1;
|
|
155
234
|
sunCodeNode.setContentSize(VIRTUAL_GAMEPAD_SUN_CODE_SIZE, VIRTUAL_GAMEPAD_SUN_CODE_SIZE);
|
|
156
|
-
this.
|
|
157
|
-
this.
|
|
158
|
-
this.
|
|
159
|
-
|
|
160
|
-
this.
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
this.
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
this.
|
|
170
|
-
this.
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
this.
|
|
174
|
-
this.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
this.
|
|
178
|
-
this.
|
|
179
|
-
this.
|
|
180
|
-
|
|
181
|
-
this.
|
|
182
|
-
this.
|
|
183
|
-
this.
|
|
184
|
-
|
|
185
|
-
this.
|
|
186
|
-
this.
|
|
187
|
-
this.
|
|
188
|
-
this._virtualGamepadBadge.active = false;
|
|
189
|
-
|
|
190
|
-
this.refreshVirtualGamepadLayout();
|
|
191
|
-
this.bringVirtualGamepadToTop();
|
|
192
|
-
this.scheduleOnce(() => this.bringVirtualGamepadToTop(), 0);
|
|
235
|
+
this._sunCodeSprite = sunCodeNode.addComponent(cc.Sprite);
|
|
236
|
+
this._sunCodeSprite.sizeMode = cc.Sprite.SizeMode.CUSTOM;
|
|
237
|
+
this._sunCodeSprite.node.active = false;
|
|
238
|
+
|
|
239
|
+
this._sunCodeLoadingLabel = this.makeLabel("sunCodeLoading", "太阳码生成中\n请稍候...", 19, new cc.Color(75, 101, 130, 255));
|
|
240
|
+
this._sunCodeLoadingLabel.node.parent = qrFrame;
|
|
241
|
+
this._sunCodeLoadingLabel.node.setContentSize(210, 72);
|
|
242
|
+
|
|
243
|
+
this._statusLabel = this.makeLabel("status", "等待手柄扫码连接", 20, new cc.Color(255, 210, 82, 255));
|
|
244
|
+
this._statusLabel.node.parent = this._panel;
|
|
245
|
+
this._statusLabel.node.y = -124;
|
|
246
|
+
|
|
247
|
+
this._roomLabel = this.makeLabel("room", "", 16, new cc.Color(193, 207, 226, 255));
|
|
248
|
+
this._roomLabel.node.parent = this._panel;
|
|
249
|
+
this._roomLabel.node.y = -156;
|
|
250
|
+
|
|
251
|
+
this._identityLabel = this.makeLabel("identity", "", 16, new cc.Color(141, 163, 191, 255));
|
|
252
|
+
this._identityLabel.node.parent = this._panel;
|
|
253
|
+
this._identityLabel.node.y = -184;
|
|
254
|
+
|
|
255
|
+
this._badge = new cc.Node("virtualGamepadBadge");
|
|
256
|
+
this._badge.setContentSize(VIRTUAL_GAMEPAD_BADGE_WIDTH, VIRTUAL_GAMEPAD_BADGE_HEIGHT);
|
|
257
|
+
this._badge.zIndex = VIRTUAL_GAMEPAD_TOP_Z_INDEX;
|
|
258
|
+
this._badge.parent = top;
|
|
259
|
+
this.drawBg(this._badge, 230, 48, new cc.Color(24, 160, 91, 238));
|
|
260
|
+
this._badgeLabel = this.makeLabel("badgeText", "手柄已连接", 20, cc.Color.WHITE);
|
|
261
|
+
this._badgeLabel.node.parent = this._badge;
|
|
262
|
+
this._badge.active = false;
|
|
263
|
+
|
|
264
|
+
this.refreshLayout();
|
|
265
|
+
this.bringToTop();
|
|
266
|
+
this.scheduleOnce(() => this.bringToTop(), 0);
|
|
193
267
|
}
|
|
194
268
|
|
|
195
|
-
private
|
|
196
|
-
let size
|
|
197
|
-
if (this.
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
if (this._virtualGamepadBadge) {
|
|
202
|
-
this._virtualGamepadBadge.x = size.width - VIRTUAL_GAMEPAD_BADGE_WIDTH / 2;
|
|
203
|
-
this._virtualGamepadBadge.y = size.height - VIRTUAL_GAMEPAD_BADGE_HEIGHT / 2;
|
|
204
|
-
}
|
|
205
|
-
this.bringVirtualGamepadToTop();
|
|
269
|
+
private refreshLayout() {
|
|
270
|
+
let size = cc.winSize;
|
|
271
|
+
if (this._panel) { this._panel.x = size.width - 210; this._panel.y = size.height - 225; }
|
|
272
|
+
if (this._badge) { this._badge.x = size.width - 115; this._badge.y = size.height - 24; }
|
|
273
|
+
this.bringToTop();
|
|
206
274
|
}
|
|
207
275
|
|
|
208
|
-
private
|
|
209
|
-
this.
|
|
210
|
-
this.
|
|
211
|
-
if (this.
|
|
212
|
-
this.
|
|
213
|
-
this.
|
|
214
|
-
}
|
|
215
|
-
if (this._virtualGamepadRoomLabel) {
|
|
216
|
-
this._virtualGamepadRoomLabel.string = "房间 " + status.roomId;
|
|
217
|
-
}
|
|
218
|
-
if (this._virtualGamepadIdentityLabel) {
|
|
219
|
-
this._virtualGamepadIdentityLabel.string = "身份 " + status.identityText;
|
|
220
|
-
}
|
|
221
|
-
if (this._virtualGamepadBadgeLabel) {
|
|
222
|
-
this._virtualGamepadBadgeLabel.string = status.statusText;
|
|
276
|
+
private refreshView(status: any) {
|
|
277
|
+
this.ensureNodes();
|
|
278
|
+
this.refreshSunCode(status);
|
|
279
|
+
if (this._statusLabel) {
|
|
280
|
+
this._statusLabel.string = status.statusText;
|
|
281
|
+
this._statusLabel.node.color = this.statusColor(status);
|
|
223
282
|
}
|
|
224
|
-
if (this.
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
if (this.
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
this.bringVirtualGamepadToTop();
|
|
283
|
+
if (this._roomLabel) this._roomLabel.string = "房间 " + status.roomId;
|
|
284
|
+
if (this._identityLabel) this._identityLabel.string = "身份 " + status.identityText;
|
|
285
|
+
if (this._badgeLabel) this._badgeLabel.string = status.statusText;
|
|
286
|
+
if (this._panel) this._panel.active = !status.controllerConnected;
|
|
287
|
+
if (this._badge) this._badge.active = status.controllerConnected;
|
|
288
|
+
this.bringToTop();
|
|
231
289
|
}
|
|
232
290
|
|
|
233
|
-
private
|
|
234
|
-
let
|
|
235
|
-
let
|
|
236
|
-
|
|
237
|
-
if (!
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if (loadingLabel && loadingLabel.node && cc.isValid(loadingLabel.node)) {
|
|
241
|
-
loadingLabel.string = "太阳码生成中\n请稍候...";
|
|
242
|
-
loadingLabel.node.active = true;
|
|
243
|
-
}
|
|
291
|
+
private refreshSunCode(status: any) {
|
|
292
|
+
let sp = this._sunCodeSprite, lb = this._sunCodeLoadingLabel;
|
|
293
|
+
let src = status.sunCodeState == "ready" ? status.sunCodeDataUrl : "";
|
|
294
|
+
if (!sp || !sp.node || !cc.isValid(sp.node)) return;
|
|
295
|
+
if (!src) {
|
|
296
|
+
sp.node.active = false;
|
|
297
|
+
if (lb && lb.node && cc.isValid(lb.node)) { lb.string = "太阳码生成中\n请稍候..."; lb.node.active = true; }
|
|
244
298
|
return;
|
|
245
299
|
}
|
|
246
|
-
if (this.
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
if (error || !texture || !currentSprite || !currentSprite.node || !cc.isValid(currentSprite.node)) {
|
|
266
|
-
console.warn("[VirtualGamepad][SunCode] image decode failed", error && (error.message || error));
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
currentSprite.spriteFrame = new cc.SpriteFrame(texture);
|
|
270
|
-
currentSprite.sizeMode = cc.Sprite.SizeMode.CUSTOM;
|
|
271
|
-
currentSprite.node.setContentSize(VIRTUAL_GAMEPAD_SUN_CODE_SIZE, VIRTUAL_GAMEPAD_SUN_CODE_SIZE);
|
|
272
|
-
currentSprite.node.active = true;
|
|
273
|
-
let currentLoadingLabel = this._virtualGamepadSunCodeLoadingLabel;
|
|
274
|
-
if (currentLoadingLabel && currentLoadingLabel.node && cc.isValid(currentLoadingLabel.node)) {
|
|
275
|
-
currentLoadingLabel.node.active = false;
|
|
276
|
-
}
|
|
277
|
-
this._virtualGamepadSunCodeSource = source;
|
|
300
|
+
if (this._sunCodeSource == src && sp.spriteFrame) { sp.node.active = true; if (lb && lb.node) lb.node.active = false; return; }
|
|
301
|
+
if (this._sunCodeLoading == src) return;
|
|
302
|
+
sp.node.active = false;
|
|
303
|
+
if (lb && lb.node && cc.isValid(lb.node)) { lb.string = "太阳码加载中\n请稍候..."; lb.node.active = true; }
|
|
304
|
+
this._sunCodeLoading = src;
|
|
305
|
+
let serial = ++this._sunCodeLoadSerial;
|
|
306
|
+
let imgType = src.indexOf("data:image/png") == 0 ? "png" : "jpg";
|
|
307
|
+
cc.loader.load({ url: src, type: imgType }, (err: Error, tex: cc.Texture2D) => {
|
|
308
|
+
if (serial != this._sunCodeLoadSerial) return;
|
|
309
|
+
this._sunCodeLoading = "";
|
|
310
|
+
let cur = this._sunCodeSprite;
|
|
311
|
+
if (err || !tex || !cur || !cur.node || !cc.isValid(cur.node)) { console.warn("[VirtualGamepad][SunCode] decode failed", err && (err.message || err)); return; }
|
|
312
|
+
cur.spriteFrame = new cc.SpriteFrame(tex);
|
|
313
|
+
cur.sizeMode = cc.Sprite.SizeMode.CUSTOM;
|
|
314
|
+
cur.node.setContentSize(VIRTUAL_GAMEPAD_SUN_CODE_SIZE, VIRTUAL_GAMEPAD_SUN_CODE_SIZE);
|
|
315
|
+
cur.node.active = true;
|
|
316
|
+
let cl = this._sunCodeLoadingLabel;
|
|
317
|
+
if (cl && cl.node && cc.isValid(cl.node)) cl.node.active = false;
|
|
318
|
+
this._sunCodeSource = src;
|
|
278
319
|
});
|
|
279
320
|
}
|
|
280
321
|
|
|
281
|
-
private
|
|
282
|
-
|
|
283
|
-
}
|
|
322
|
+
private getTopParent(): cc.Node { return cc.director.getScene() || this.node.parent || this.node; }
|
|
323
|
+
private bringToTop() { [this._panel, this._badge].forEach(n => this.placeTop(n)); }
|
|
284
324
|
|
|
285
|
-
private
|
|
286
|
-
this.placeVirtualGamepadNodeOnTop(this._virtualGamepadPanel);
|
|
287
|
-
this.placeVirtualGamepadNodeOnTop(this._virtualGamepadBadge);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
private placeVirtualGamepadNodeOnTop(node: cc.Node | null) {
|
|
325
|
+
private placeTop(node: cc.Node | null) {
|
|
291
326
|
if (!node || !cc.isValid(node)) return;
|
|
292
|
-
let
|
|
293
|
-
if (
|
|
294
|
-
let
|
|
295
|
-
node.parent =
|
|
296
|
-
node.setPosition(
|
|
297
|
-
}
|
|
298
|
-
if (node.zIndex != VIRTUAL_GAMEPAD_TOP_Z_INDEX) {
|
|
299
|
-
node.zIndex = VIRTUAL_GAMEPAD_TOP_Z_INDEX;
|
|
300
|
-
}
|
|
301
|
-
if (node.parent && node.getSiblingIndex() != node.parent.childrenCount - 1) {
|
|
302
|
-
node.setSiblingIndex(node.parent.childrenCount - 1);
|
|
327
|
+
let top = this.getTopParent();
|
|
328
|
+
if (top && cc.isValid(top) && node.parent != top) {
|
|
329
|
+
let wp = node.convertToWorldSpaceAR(cc.Vec2.ZERO);
|
|
330
|
+
node.parent = top;
|
|
331
|
+
node.setPosition(top.convertToNodeSpaceAR(wp));
|
|
303
332
|
}
|
|
333
|
+
if (node.zIndex != VIRTUAL_GAMEPAD_TOP_Z_INDEX) node.zIndex = VIRTUAL_GAMEPAD_TOP_Z_INDEX;
|
|
334
|
+
if (node.parent && node.getSiblingIndex() != node.parent.childrenCount - 1) node.setSiblingIndex(node.parent.childrenCount - 1);
|
|
304
335
|
}
|
|
305
336
|
|
|
306
|
-
private
|
|
307
|
-
let
|
|
308
|
-
|
|
309
|
-
let
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
return
|
|
337
|
+
private makeLabel(name: string, text: string, fontSize: number, color: cc.Color): cc.Label {
|
|
338
|
+
let n = new cc.Node(name);
|
|
339
|
+
n.setContentSize(390, fontSize + 10);
|
|
340
|
+
let l = n.addComponent(cc.Label);
|
|
341
|
+
l.string = text;
|
|
342
|
+
l.fontSize = fontSize;
|
|
343
|
+
l.lineHeight = fontSize + 8;
|
|
344
|
+
l.horizontalAlign = cc.Label.HorizontalAlign.CENTER;
|
|
345
|
+
l.verticalAlign = cc.Label.VerticalAlign.CENTER;
|
|
346
|
+
l.overflow = cc.Label.Overflow.SHRINK;
|
|
347
|
+
l.node.color = color;
|
|
348
|
+
return l;
|
|
318
349
|
}
|
|
319
350
|
|
|
320
|
-
private
|
|
321
|
-
if (
|
|
322
|
-
if (
|
|
323
|
-
if (
|
|
351
|
+
private statusColor(s: any): cc.Color {
|
|
352
|
+
if (s.controllerConnected) return new cc.Color(83, 218, 141, 255);
|
|
353
|
+
if (s.connectionState == "error") return new cc.Color(255, 112, 112, 255);
|
|
354
|
+
if (s.connectionState == "open" || s.connectionState == "joined") return new cc.Color(87, 214, 205, 255);
|
|
324
355
|
return new cc.Color(255, 210, 82, 255);
|
|
325
356
|
}
|
|
326
357
|
|
|
327
|
-
private
|
|
328
|
-
|
|
329
|
-
let
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
358
|
+
private drawQrFrame(n: cc.Node, size: number) {
|
|
359
|
+
n.setContentSize(size, size);
|
|
360
|
+
let g = n.addComponent(cc.Graphics);
|
|
361
|
+
g.fillColor = cc.Color.WHITE;
|
|
362
|
+
g.rect(-size / 2, -size / 2, size, size);
|
|
363
|
+
g.fill();
|
|
364
|
+
g.lineWidth = 2;
|
|
365
|
+
g.strokeColor = new cc.Color(87, 214, 205, 255);
|
|
366
|
+
g.rect(-size / 2, -size / 2, size, size);
|
|
367
|
+
g.stroke();
|
|
337
368
|
}
|
|
338
369
|
|
|
339
|
-
private
|
|
340
|
-
let
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
370
|
+
private drawBg(n: cc.Node, w: number, h: number, c: cc.Color) {
|
|
371
|
+
let g = n.getComponent(cc.Graphics) || n.addComponent(cc.Graphics);
|
|
372
|
+
g.clear();
|
|
373
|
+
g.fillColor = c;
|
|
374
|
+
g.rect(-w * n.anchorX, -h * n.anchorY, w, h);
|
|
375
|
+
g.fill();
|
|
345
376
|
}
|
|
346
377
|
}
|