// 关卡清单:从 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 TYPE_LABEL = { 'jump': '跳刺', 'endur': '耐久', 'boss': 'BOSS', 'troll': '坑向', 'custom': '自制', }; const Map TYPE_CLASS = { 'jump': 't-jump', 'endur': 't-endur', 'boss': 't-boss', 'troll': 't-troll', 'custom': 't-custom', }; List> _builtin = >[]; bool _loaded = false; /// 加载内置关卡(assets/levels.json)。重复调用安全。 Future loadLevels() async { if (_loaded) return; final s = await rootBundle.loadString('assets/levels.json'); final m = (jsonDecode(s) as Map).cast(); final list = ((m['levels'] as List?) ?? []) .cast>() .toList(); for (int i = 0; i < list.length; i++) { list[i] = {...list[i], 'index': i, 'builtin': true}; } _builtin = list; _loaded = true; } /// 内置关卡清单(已标注 index / builtin)。 List> get LEVELS => _builtin; /// 合成一张自制关卡数据对象(与 web makeCustomLevel 一致)。 Map makeCustomLevel(Map data) { return { ...data, 'id': 'u' + (DateTime.now().millisecondsSinceEpoch % 100000).toString() + (_uid++).toString(), 'type': 'custom', 'builtin': false, 'index': -1, }; } int _uid = 0; /// 按 id 查找关卡(内置优先,其次自制)。 Map? 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; } return null; }