import 'dart:ui'; import 'package:flame/components.dart'; // --- Level Data Models --- enum BlockShapeType { rectangle, triangle, circle } class BlockShape { final BlockShapeType type; final Vector2 position; final double width; final double height; final double? radius; // 用于圆形 final double rotation; // 旋转角度(弧度) BlockShape.rectangle( this.position, this.width, this.height, { this.rotation = 0, }) : type = BlockShapeType.rectangle, radius = null; BlockShape.triangle( this.position, this.width, this.height, { this.rotation = 0, }) : type = BlockShapeType.triangle, radius = null; BlockShape.circle(this.position, double radiusValue) : type = BlockShapeType.circle, radius = radiusValue, width = radiusValue * 2, height = radiusValue * 2, rotation = 0; // 兼容旧的 Rect 格式 BlockShape.fromRect(Rect rect) : type = BlockShapeType.rectangle, position = Vector2(rect.center.dx, rect.center.dy), width = rect.width, height = rect.height, radius = null, rotation = 0; } class LevelConfig { final int id; final Vector2 ballPos; final List stars; final Vector2 goalPos; final double ink; final List blocks; LevelConfig({ required this.id, required this.ballPos, required this.stars, required this.goalPos, required this.ink, this.blocks = const [], }); // 兼容旧的 Rect 列表 LevelConfig.fromRects({ required this.id, required this.ballPos, required this.stars, required this.goalPos, required this.ink, List blocks = const [], }) : blocks = blocks.map((r) => BlockShape.fromRect(r)).toList(); } // --- Level Definitions --- // Hand-crafted themed levels // 1–3: slope-style levels // 4–6: bounce-focused layouts // 7–9: multi-layer maze platforms // 10–12: narrow-gap precision levels final List levels = [ // 1-6: 基础阶段 LevelConfig( id: 1, ballPos: Vector2(3, 5), stars: [Vector2(9, 18)], goalPos: Vector2(10, 38), ink: 650, blocks: [], ), LevelConfig( id: 2, ballPos: Vector2(4, 10), stars: [Vector2(9, 18), Vector2(13, 24)], goalPos: Vector2(16, 38), ink: 700, blocks: [ BlockShape.triangle(Vector2(4.5, 22), 5, 1.2), BlockShape.triangle(Vector2(11.5, 26), 5, 1.2), ], ), LevelConfig( id: 3, ballPos: Vector2(3, 8), stars: [Vector2(5, 18), Vector2(11, 24), Vector2(15, 30)], goalPos: Vector2(17, 39), ink: 750, blocks: [ BlockShape.rectangle(Vector2(3, 20), 4, 1.2), BlockShape.circle(Vector2(11, 26), 1), BlockShape.triangle(Vector2(10, 32), 6, 1.2), ], ), LevelConfig( id: 4, ballPos: Vector2(4, 10), stars: [Vector2(6, 17), Vector2(10, 22)], goalPos: Vector2(14, 37), ink: 750, blocks: [ BlockShape.rectangle(Vector2(8, 19), 12, 0.6), BlockShape.rectangle(Vector2(8, 26), 12, 0.6), ], ), LevelConfig( id: 5, ballPos: Vector2(5, 8), stars: [Vector2(6, 16), Vector2(6, 24), Vector2(6, 30)], goalPos: Vector2(14, 37), ink: 800, blocks: [ BlockShape.triangle(Vector2(4, 20), 4, 0.8), BlockShape.triangle(Vector2(4, 28), 4, 0.8), BlockShape.rectangle(Vector2(13, 30), 6, 0.8), ], ), LevelConfig( id: 6, ballPos: Vector2(4, 8), stars: [Vector2(6, 18), Vector2(14, 20)], goalPos: Vector2(10, 38), ink: 820, blocks: [ BlockShape.circle(Vector2(3.25, 24), 1.25), BlockShape.circle(Vector2(16.75, 24), 1.25), BlockShape.rectangle(Vector2(9, 28), 10, 0.8), ], ), // 7-12: 进阶阶段 LevelConfig( id: 7, ballPos: Vector2(3, 8), stars: [Vector2(8, 15), Vector2(12, 24)], goalPos: Vector2(16, 37), ink: 850, blocks: [ BlockShape.rectangle(Vector2(5.5, 17), 7, 0.8), BlockShape.triangle(Vector2(11.5, 22), 7, 0.8), BlockShape.rectangle(Vector2(5.5, 28), 7, 0.8), BlockShape.circle(Vector2(15, 21), 0.75), ], ), LevelConfig( id: 8, ballPos: Vector2(4, 10), stars: [Vector2(6, 20), Vector2(12, 22), Vector2(16, 26)], goalPos: Vector2(10, 39), ink: 900, blocks: [ BlockShape.rectangle(Vector2(8, 18), 12, 0.8), BlockShape.rectangle(Vector2(8, 24), 12, 0.8), BlockShape.triangle(Vector2(11.5, 30), 7, 0.8), BlockShape.circle(Vector2(3.25, 31), 1.25), ], ), LevelConfig( id: 9, ballPos: Vector2(3, 8), stars: [Vector2(6, 17), Vector2(14, 20)], goalPos: Vector2(10, 39), ink: 900, blocks: [ BlockShape.triangle(Vector2(5, 19), 6, 0.8), BlockShape.triangle(Vector2(13, 22), 6, 0.8), BlockShape.rectangle(Vector2(8, 28), 12, 0.8), BlockShape.circle(Vector2(9.4, 21), 0.4), ], ), LevelConfig( id: 10, ballPos: Vector2(4, 8), stars: [Vector2(10, 20)], goalPos: Vector2(16, 37), ink: 850, blocks: [ BlockShape.circle(Vector2(7.6, 22), 0.6), BlockShape.circle(Vector2(12.6, 22), 0.6), BlockShape.rectangle(Vector2(8, 28), 12, 0.8), ], ), LevelConfig( id: 11, ballPos: Vector2(3, 8), stars: [Vector2(9, 18), Vector2(9, 26)], goalPos: Vector2(9, 37), ink: 900, blocks: [ BlockShape.circle(Vector2(6.6, 24), 0.6), BlockShape.circle(Vector2(12.6, 24), 0.6), BlockShape.triangle(Vector2(3.5, 24), 3, 0.8), BlockShape.triangle(Vector2(16.5, 24), 3, 0.8), ], ), LevelConfig( id: 12, ballPos: Vector2(3, 8), stars: [Vector2(7.5, 20), Vector2(10, 28)], goalPos: Vector2(10, 39), ink: 950, blocks: [ BlockShape.circle(Vector2(9, 21), 0.5), BlockShape.circle(Vector2(11.5, 21), 0.5), BlockShape.triangle(Vector2(9, 28), 8, 0.8), ], ), // 13-18: 高级阶段 - 复杂组合与精准跳跃 LevelConfig( id: 13, ballPos: Vector2(2, 8), stars: [Vector2(5, 16), Vector2(12, 24), Vector2(16, 32)], goalPos: Vector2(18, 38), ink: 1000, blocks: [ BlockShape.rectangle(Vector2(6, 19), 8, 0.6), BlockShape.circle(Vector2(13, 22), 0.8), BlockShape.rectangle(Vector2(8, 30), 10, 0.6), BlockShape.triangle(Vector2(16, 35), 6, 0.8), ], ), LevelConfig( id: 14, ballPos: Vector2(5, 8), stars: [Vector2(8, 18), Vector2(8, 26), Vector2(8, 34)], goalPos: Vector2(14, 39), ink: 1050, blocks: [ BlockShape.circle(Vector2(3, 20), 1), BlockShape.triangle(Vector2(13, 22), 6, 0.8), BlockShape.circle(Vector2(3, 30), 1), BlockShape.rectangle(Vector2(10, 35), 8, 0.6), ], ), LevelConfig( id: 15, ballPos: Vector2(2, 10), stars: [Vector2(6, 18), Vector2(14, 22), Vector2(10, 30)], goalPos: Vector2(16, 38), ink: 1100, blocks: [ BlockShape.triangle(Vector2(4, 19), 5, 0.8), BlockShape.rectangle(Vector2(12, 21), 10, 0.6), BlockShape.circle(Vector2(9, 26), 0.9), BlockShape.triangle(Vector2(14, 31), 6, 0.8), BlockShape.circle(Vector2(5, 34), 0.7), ], ), LevelConfig( id: 16, ballPos: Vector2(3, 8), stars: [Vector2(10, 17), Vector2(16, 24)], goalPos: Vector2(10, 38), ink: 1050, blocks: [ BlockShape.circle(Vector2(6, 18), 0.8), BlockShape.circle(Vector2(14, 18), 0.8), BlockShape.rectangle(Vector2(10, 23), 14, 0.6), BlockShape.triangle(Vector2(6, 30), 5, 0.8), BlockShape.triangle(Vector2(14, 30), 5, 0.8), ], ), LevelConfig( id: 17, ballPos: Vector2(4, 8), stars: [Vector2(7, 20), Vector2(13, 26), Vector2(10, 34)], goalPos: Vector2(10, 39), ink: 1150, blocks: [ BlockShape.rectangle(Vector2(5, 19), 6, 0.6), BlockShape.circle(Vector2(10, 22), 0.7), BlockShape.rectangle(Vector2(15, 25), 6, 0.6), BlockShape.triangle(Vector2(8, 31), 7, 0.8), BlockShape.circle(Vector2(12, 31), 0.8), ], ), LevelConfig( id: 18, ballPos: Vector2(2, 10), stars: [Vector2(4, 18), Vector2(16, 24), Vector2(10, 32)], goalPos: Vector2(15, 39), ink: 1200, blocks: [ BlockShape.triangle(Vector2(3, 17), 4, 0.8), BlockShape.circle(Vector2(10, 20), 0.9), BlockShape.triangle(Vector2(17, 23), 5, 0.8), BlockShape.rectangle(Vector2(8, 29), 12, 0.6), BlockShape.circle(Vector2(6, 35), 0.8), ], ), // 19-24: 专家阶段 - 密集障碍与多重跳跃 LevelConfig( id: 19, ballPos: Vector2(3, 8), stars: [Vector2(6, 17), Vector2(14, 20), Vector2(9, 28), Vector2(16, 34)], goalPos: Vector2(10, 39), ink: 1250, blocks: [ BlockShape.circle(Vector2(5, 18), 0.7), BlockShape.circle(Vector2(13, 18), 0.7), BlockShape.rectangle(Vector2(9, 23), 12, 0.6), BlockShape.triangle(Vector2(4, 29), 5, 0.8), BlockShape.circle(Vector2(14, 29), 0.9), BlockShape.rectangle(Vector2(9, 35), 10, 0.6), ], ), LevelConfig( id: 20, ballPos: Vector2(5, 8), stars: [Vector2(8, 16), Vector2(8, 24), Vector2(8, 32)], goalPos: Vector2(8, 39), ink: 1300, blocks: [ BlockShape.circle(Vector2(4, 19), 0.6), BlockShape.circle(Vector2(12, 19), 0.6), BlockShape.triangle(Vector2(8, 22), 6, 0.8), BlockShape.circle(Vector2(4, 27), 0.6), BlockShape.circle(Vector2(12, 27), 0.6), BlockShape.rectangle(Vector2(8, 31), 8, 0.6), BlockShape.triangle(Vector2(8, 36), 4, 0.6), ], ), LevelConfig( id: 21, ballPos: Vector2(2, 10), stars: [Vector2(5, 18), Vector2(15, 22), Vector2(6, 30), Vector2(14, 36)], goalPos: Vector2(10, 39), ink: 1350, blocks: [ BlockShape.rectangle(Vector2(4, 17), 6, 0.6), BlockShape.circle(Vector2(10, 19), 0.8), BlockShape.rectangle(Vector2(16, 21), 6, 0.6), BlockShape.triangle(Vector2(3, 26), 5, 0.8), BlockShape.circle(Vector2(10, 28), 0.9), BlockShape.triangle(Vector2(17, 32), 5, 0.8), BlockShape.rectangle(Vector2(10, 35), 12, 0.6), ], ), LevelConfig( id: 22, ballPos: Vector2(4, 8), stars: [Vector2(7, 18), Vector2(13, 20), Vector2(10, 28), Vector2(7, 34)], goalPos: Vector2(16, 38), ink: 1400, blocks: [ BlockShape.triangle(Vector2(5, 16), 6, 0.8), BlockShape.circle(Vector2(15, 18), 0.8), BlockShape.rectangle(Vector2(9, 23), 14, 0.6), BlockShape.circle(Vector2(5, 28), 0.7), BlockShape.circle(Vector2(15, 28), 0.7), BlockShape.triangle(Vector2(10, 32), 7, 0.8), BlockShape.circle(Vector2(16, 35), 0.8), ], ), LevelConfig( id: 23, ballPos: Vector2(3, 8), stars: [ Vector2(4, 17), Vector2(16, 19), Vector2(8, 26), Vector2(12, 32), Vector2(6, 36), ], goalPos: Vector2(14, 39), ink: 1450, blocks: [ BlockShape.circle(Vector2(3, 18), 0.7), BlockShape.rectangle(Vector2(10, 20), 12, 0.6), BlockShape.circle(Vector2(17, 18), 0.7), BlockShape.triangle(Vector2(6, 25), 5, 0.8), BlockShape.circle(Vector2(12, 28), 0.8), BlockShape.rectangle(Vector2(9, 31), 10, 0.6), BlockShape.triangle(Vector2(4, 34), 6, 0.8), BlockShape.circle(Vector2(14, 36), 0.9), ], ), LevelConfig( id: 24, ballPos: Vector2(2, 10), stars: [ Vector2(6, 17), Vector2(14, 20), Vector2(4, 26), Vector2(16, 30), Vector2(10, 36), ], goalPos: Vector2(10, 39), ink: 1500, blocks: [ BlockShape.rectangle(Vector2(3, 18), 8, 0.6), BlockShape.circle(Vector2(14, 19), 0.8), BlockShape.triangle(Vector2(9, 23), 6, 0.8), BlockShape.circle(Vector2(4, 27), 0.7), BlockShape.circle(Vector2(16, 27), 0.7), BlockShape.rectangle(Vector2(10, 30), 12, 0.6), BlockShape.triangle(Vector2(7, 34), 5, 0.8), BlockShape.triangle(Vector2(13, 34), 5, 0.8), ], ), // 25-30: 大师阶段 - 极限挑战 LevelConfig( id: 25, ballPos: Vector2(3, 8), stars: [ Vector2(5, 16), Vector2(15, 19), Vector2(8, 24), Vector2(12, 29), Vector2(6, 34), Vector2(16, 37), ], goalPos: Vector2(10, 39), ink: 1550, blocks: [ BlockShape.circle(Vector2(4, 17), 0.6), BlockShape.circle(Vector2(16, 17), 0.6), BlockShape.rectangle(Vector2(9, 21), 12, 0.6), BlockShape.triangle(Vector2(5, 26), 5, 0.8), BlockShape.circle(Vector2(13, 27), 0.8), BlockShape.rectangle(Vector2(8, 31), 10, 0.6), BlockShape.triangle(Vector2(14, 31), 4, 0.8), BlockShape.circle(Vector2(4, 35), 0.7), BlockShape.circle(Vector2(16, 35), 0.7), ], ), LevelConfig( id: 26, ballPos: Vector2(5, 8), stars: [ Vector2(8, 15), Vector2(8, 21), Vector2(8, 27), Vector2(8, 33), Vector2(8, 37), ], goalPos: Vector2(8, 39), ink: 1600, blocks: [ BlockShape.circle(Vector2(4, 18), 0.65), BlockShape.circle(Vector2(12, 18), 0.65), BlockShape.triangle(Vector2(8, 22), 7, 0.8), BlockShape.circle(Vector2(3, 25), 0.7), BlockShape.circle(Vector2(13, 25), 0.7), BlockShape.rectangle(Vector2(8, 29), 10, 0.6), BlockShape.triangle(Vector2(5, 31), 4, 0.8), BlockShape.triangle(Vector2(11, 31), 4, 0.8), BlockShape.circle(Vector2(8, 35), 0.8), ], ), LevelConfig( id: 27, ballPos: Vector2(2, 10), stars: [ Vector2(4, 16), Vector2(16, 18), Vector2(6, 24), Vector2(14, 26), Vector2(8, 32), Vector2(12, 35), ], goalPos: Vector2(10, 39), ink: 1650, blocks: [ BlockShape.rectangle(Vector2(3, 17), 8, 0.6), BlockShape.circle(Vector2(16, 19), 0.75), BlockShape.triangle(Vector2(6, 22), 6, 0.8), BlockShape.rectangle(Vector2(14, 25), 8, 0.6), BlockShape.circle(Vector2(5, 28), 0.8), BlockShape.circle(Vector2(15, 28), 0.8), BlockShape.triangle(Vector2(10, 30), 8, 0.8), BlockShape.rectangle(Vector2(8, 34), 12, 0.6), BlockShape.circle(Vector2(3, 36), 0.8), BlockShape.circle(Vector2(17, 36), 0.8), ], ), LevelConfig( id: 28, ballPos: Vector2(4, 8), stars: [ Vector2(6, 16), Vector2(14, 18), Vector2(4, 24), Vector2(16, 26), Vector2(10, 31), Vector2(8, 36), Vector2(12, 37), ], goalPos: Vector2(10, 39), ink: 1700, blocks: [ BlockShape.circle(Vector2(5, 17), 0.6), BlockShape.circle(Vector2(15, 17), 0.6), BlockShape.rectangle(Vector2(9, 20), 12, 0.6), BlockShape.triangle(Vector2(3, 25), 5, 0.8), BlockShape.triangle(Vector2(17, 25), 5, 0.8), BlockShape.circle(Vector2(10, 27), 0.9), BlockShape.rectangle(Vector2(6, 30), 8, 0.6), BlockShape.rectangle(Vector2(14, 30), 8, 0.6), BlockShape.triangle(Vector2(10, 33), 6, 0.8), ], ), LevelConfig( id: 29, ballPos: Vector2(3, 10), stars: [ Vector2(5, 15), Vector2(15, 17), Vector2(8, 21), Vector2(12, 23), Vector2(4, 28), Vector2(16, 31), Vector2(10, 35), ], goalPos: Vector2(10, 39), ink: 1750, blocks: [ BlockShape.triangle(Vector2(4, 16), 5, 0.8), BlockShape.rectangle(Vector2(14, 18), 8, 0.6), BlockShape.circle(Vector2(8, 20), 0.75), BlockShape.circle(Vector2(12, 20), 0.75), BlockShape.triangle(Vector2(3, 26), 6, 0.8), BlockShape.circle(Vector2(16, 29), 0.85), BlockShape.rectangle(Vector2(8, 32), 12, 0.6), BlockShape.circle(Vector2(5, 34), 0.75), BlockShape.circle(Vector2(15, 34), 0.75), BlockShape.triangle(Vector2(10, 36), 5, 0.6), ], ), LevelConfig( id: 30, ballPos: Vector2(2, 8), stars: [ Vector2(4, 15), Vector2(16, 16), Vector2(7, 20), Vector2(13, 22), Vector2(6, 27), Vector2(14, 29), Vector2(9, 34), Vector2(11, 35), ], goalPos: Vector2(10, 39), ink: 1800, blocks: [ BlockShape.circle(Vector2(3, 17), 0.65), BlockShape.circle(Vector2(17, 17), 0.65), BlockShape.rectangle(Vector2(9, 19), 14, 0.6), BlockShape.triangle(Vector2(5, 23), 6, 0.8), BlockShape.circle(Vector2(13, 24), 0.8), BlockShape.circle(Vector2(4, 28), 0.7), BlockShape.circle(Vector2(16, 28), 0.7), BlockShape.triangle(Vector2(10, 30), 8, 0.8), BlockShape.rectangle(Vector2(7, 33), 6, 0.6), BlockShape.rectangle(Vector2(13, 33), 6, 0.6), BlockShape.circle(Vector2(10, 36), 0.9), ], ), ];