67 lines
1.9 KiB
Dart
67 lines
1.9 KiB
Dart
// 关卡清单:从 assets/levels.json 加载内置关卡,并提供与 web 版
|
|
// levels/index.js 一致的 TYPE_LABEL / TYPE_CLASS / makeCustomLevel / findLevel。
|
|
import 'dart:convert';
|
|
import 'package:flutter/services.dart' show rootBundle;
|
|
import 'package:iwbtc/src/core/save.dart';
|
|
|
|
const Map<String, String> TYPE_LABEL = {
|
|
'jump': '跳刺',
|
|
'endur': '耐久',
|
|
'boss': 'BOSS',
|
|
'troll': '坑向',
|
|
'custom': '自制',
|
|
};
|
|
|
|
const Map<String, String> TYPE_CLASS = {
|
|
'jump': 't-jump',
|
|
'endur': 't-endur',
|
|
'boss': 't-boss',
|
|
'troll': 't-troll',
|
|
'custom': 't-custom',
|
|
};
|
|
|
|
List<Map<String, dynamic>> _builtin = <Map<String, dynamic>>[];
|
|
bool _loaded = false;
|
|
|
|
/// 加载内置关卡(assets/levels.json)。重复调用安全。
|
|
Future<void> loadLevels() async {
|
|
if (_loaded) return;
|
|
final s = await rootBundle.loadString('assets/levels.json');
|
|
final m = (jsonDecode(s) as Map).cast<String, dynamic>();
|
|
final list = ((m['levels'] as List?) ?? <dynamic>[])
|
|
.cast<Map<String, dynamic>>()
|
|
.toList();
|
|
for (int i = 0; i < list.length; i++) {
|
|
list[i] = <String, dynamic>{...list[i], 'index': i, 'builtin': true};
|
|
}
|
|
_builtin = list;
|
|
_loaded = true;
|
|
}
|
|
|
|
/// 内置关卡清单(已标注 index / builtin)。
|
|
List<Map<String, dynamic>> get LEVELS => _builtin;
|
|
|
|
/// 合成一张自制关卡数据对象(与 web makeCustomLevel 一致)。
|
|
Map<String, dynamic> makeCustomLevel(Map<String, dynamic> data) {
|
|
return <String, dynamic>{
|
|
...data,
|
|
'id': 'u' + (DateTime.now().millisecondsSinceEpoch % 100000).toString() + (_uid++).toString(),
|
|
'type': 'custom',
|
|
'builtin': false,
|
|
'index': -1,
|
|
};
|
|
}
|
|
|
|
int _uid = 0;
|
|
|
|
/// 按 id 查找关卡(内置优先,其次自制)。
|
|
Map<String, dynamic>? findLevel(String id) {
|
|
for (final l in _builtin) {
|
|
if (l['id'] == id) return l;
|
|
}
|
|
for (final l in Save.customs()) {
|
|
if (l['id'] == id) return l as Map<String, dynamic>;
|
|
}
|
|
return null;
|
|
}
|