105 lines
3.2 KiB
Dart
105 lines
3.2 KiB
Dart
// 触屏手柄按钮定义与默认布局(对应 web 版 settings.js 的 BUTTONS / DEFAULT_TOUCH)。
|
|
// 坐标 cx/cy 为相对舞台中心的百分比,size 为按钮边长(px)。
|
|
import 'package:iwbtc/src/core/save.dart';
|
|
|
|
class TouchBtn {
|
|
final String key;
|
|
final String label;
|
|
final String shape;
|
|
final String? label2;
|
|
final double cx;
|
|
final double cy;
|
|
final double size;
|
|
const TouchBtn(this.key, this.label, this.shape, this.cx, this.cy, this.size,
|
|
[this.label2]);
|
|
}
|
|
|
|
const List<TouchBtn> BUTTONS = <TouchBtn>[
|
|
TouchBtn('left', '◀', 'round', 12, 80, 62),
|
|
TouchBtn('right', '▶', 'round', 24, 80, 62),
|
|
TouchBtn('jump', '跳', 'jump', 88, 84, 94),
|
|
TouchBtn('shoot', '🔫', 'item', 79, 72, 54, '射击'),
|
|
TouchBtn('down', '▼', 'item', 90, 72, 54, '下蹲'),
|
|
TouchBtn('pause', '❚❚', 'sm', 81, 58, 42),
|
|
TouchBtn('suicide', '↺', 'sm', 90, 58, 42),
|
|
];
|
|
|
|
const List<List<String>> KEY_ACTIONS = <List<String>>[
|
|
<String>['left', '左移'],
|
|
<String>['right', '右移'],
|
|
<String>['up', '上(上浮)'],
|
|
<String>['jump', '跳跃'],
|
|
<String>['shoot', '射击'],
|
|
<String>['suicide', '自杀 / 重生'],
|
|
<String>['restart', '整关重来'],
|
|
<String>['pause', '暂停'],
|
|
];
|
|
|
|
Map<String, dynamic> defaultTouch() {
|
|
final m = <String, dynamic>{};
|
|
for (final b in BUTTONS) {
|
|
m[b.key] = <String, dynamic>{
|
|
'cx': b.cx,
|
|
'cy': b.cy,
|
|
'size': b.size,
|
|
};
|
|
}
|
|
return m;
|
|
}
|
|
|
|
Map<String, dynamic> defaultSettings() => <String, dynamic>{
|
|
'username': '',
|
|
'touch': defaultTouch(),
|
|
'keys': defaultBindings(),
|
|
};
|
|
|
|
Map<String, List<String>> defaultBindings() => <String, List<String>>{
|
|
'left': <String>['ArrowLeft', 'KeyA'],
|
|
'right': <String>['ArrowRight', 'KeyD'],
|
|
'up': <String>['ArrowUp', 'KeyW'],
|
|
'down': <String>['ArrowDown', 'KeyS'],
|
|
'jump': <String>['ShiftLeft', 'ShiftRight', 'Space', 'KeyZ', 'KeyN'],
|
|
'shoot': <String>['KeyX', 'KeyJ', 'KeyC', 'KeyM'],
|
|
'suicide': <String>['KeyR'],
|
|
'restart': <String>['Backspace'],
|
|
'pause': <String>['Escape', 'KeyP'],
|
|
};
|
|
|
|
/// 读取/补全存档里的设置对象(保证 touch / keys 字段齐全)。
|
|
Map<String, dynamic> metaSettings() {
|
|
final s = Save.settings();
|
|
if (s['username'] is! String) s['username'] = '';
|
|
if (s['touch'] is! Map) s['touch'] = defaultTouch();
|
|
if (s['keys'] is! Map) s['keys'] = defaultBindings();
|
|
return s;
|
|
}
|
|
|
|
String keyLabel(String code) {
|
|
const Map<String, String> M = <String, String>{
|
|
'Space': '空格',
|
|
'ShiftLeft': 'Shift',
|
|
'ShiftRight': 'Shift',
|
|
'ControlLeft': 'Ctrl',
|
|
'ControlRight': 'Ctrl',
|
|
'AltLeft': 'Alt',
|
|
'AltRight': 'Alt',
|
|
'Tab': 'Tab',
|
|
'Backspace': '⌫',
|
|
'Escape': 'Esc',
|
|
'Enter': 'Enter',
|
|
'ArrowLeft': '←',
|
|
'ArrowRight': '→',
|
|
'ArrowUp': '↑',
|
|
'ArrowDown': '↓',
|
|
'MetaLeft': 'Win',
|
|
'MetaRight': 'Win',
|
|
'ContextMenu': '菜单',
|
|
};
|
|
if (M.containsKey(code)) return M[code]!;
|
|
if (code.startsWith('Key')) return code.substring(3);
|
|
if (code.startsWith('Digit')) return code.substring(5);
|
|
if (code.startsWith('Numpad')) return '小键' + code.substring(6);
|
|
if (RegExp(r'^F\d{1,2}$').hasMatch(code)) return code;
|
|
return code;
|
|
}
|