Files
kidgo/app/lib/src/ui/touch_layout.dart
T

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;
}