import 'dart:collection'; import 'dart:math'; import 'package:flutter/material.dart'; import 'package:maplibre/maplibre.dart'; import 'package:maplibre_gl/maplibre_gl.dart' as gl; import '../screens/map_screen.dart'; import 'entity.dart'; import 'component.dart'; /// 系统基类 - 用于处理特定类型的组件 abstract class System { void update(List entities, Duration deltaTime); } /// 地图系统 - 处理地图相关的实体和组件 class MapSystem implements System { gl.MapLibreMapController? mapController; MapUiBodyState? mapUiBodyState; final List _plotIds = []; final List _trailIds = []; final List _iconIds = []; // 单例实例 static MapSystem? _instance; // 工厂构造函数,实现单例 factory MapSystem({gl.MapLibreMapController? mapController, MapUiBodyState? mapUiBodyState}) { _instance ??= MapSystem._internal(mapController: mapController, mapUiBodyState: mapUiBodyState); if (mapController != null) _instance!.mapController = mapController; if (mapUiBodyState != null) _instance!.mapUiBodyState = mapUiBodyState; return _instance!; } // 私有构造函数 MapSystem._internal({this.mapController, this.mapUiBodyState}); /// 获取单例实例 static MapSystem get instance { _instance ??= MapSystem._internal(); return _instance!; } @override void update(List entities, Duration deltaTime) { // 更新地图上的标绘 for (var entity in entities) { if (entity.hasComponent()) { _updatePlot(entity.getComponent()!); } if (entity.hasComponent()) { _updateIcon(entity.getComponent()!); } if (entity.hasComponent()) { _updateTrail(entity.getComponent()!); } if (entity.hasComponent()) { _updateMovement(entity); } } } void _updatePlot(PlotComponent plot) { // 实现标绘更新逻辑 // 这里可以根据plotType绘制不同类型的图形 if (plot.coordinates.length >= 2) { // 示例:绘制线段 // mapController?.addLine() // 这里需要根据实际API实现 } } void _updateIcon(IconComponent icon) { // 实现图标更新逻辑 // mapController?.addMarker() // 这里需要根据实际API实现 } void _updateTrail(TrailComponent trail) { // 实现拖尾更新逻辑 // 绘制轨迹线 } void _updateMovement(Entity entity) { var movement = entity.getComponent(); var plot = entity.getComponent(); var icon = entity.getComponent(); if (movement != null && (plot != null || icon != null)) { if (movement.target != null) { // 简单的移动逻辑 - 向目标点移动 double dx = movement.target!.longitude - movement.position.longitude; double dy = movement.target!.latitude - movement.position.latitude; double distance = sqrt(dx * dx + dy * dy); if (distance > 0.0001) { // 如果距离目标足够近就停止 double ratio = movement.speed * 0.0001 / distance; movement.position = gl.LatLng( movement.position.latitude + dy * ratio, movement.position.longitude + dx * ratio, ); // 更新图标位置 if (icon != null) { icon.position = movement.position; } // 如果有拖尾组件,添加新点 var trail = entity.getComponent(); if (trail != null) { trail.addPoint(movement.position); } } else { movement.target = null; // 到达目标 } } } } // ==================== 便捷方法:通过 mapUiBodyState 调用地图接口 ==================== /// 添加自定义图片标记 void addCustomMarker(Geographic position, {Map? properties}) { mapUiBodyState?.addCustomMarker(position, properties: properties); } /// 添加圆形 void addCircle( Geographic position, { double radius = 20, Color color = Colors.orange, Color strokeColor = Colors.red, double strokeWidth = 2, }) { mapUiBodyState?.addCircle( position, radius: radius, color: color, strokeWidth: strokeWidth, ); } /// 添加扇形 /// [center] 扇形中心的地理位置 /// [radius] 扇形的半径(单位:米) /// [startAngle] 起始角度(单位:度,0度表示正东方向) /// [endAngle] 结束角度(单位:度) /// [segments] 扇形的分段数,值越大越平滑 /// [color] 填充颜色 /// [outlineColor] 边框颜色 void addSector( Geographic center, { required double radius, required double startAngle, required double endAngle, int segments = 36, Color color = Colors.lightBlueAccent, Color outlineColor = Colors.blue, }) { mapUiBodyState?.addSector( center, radius: radius, startAngle: startAngle, endAngle: endAngle, segments: segments, color: color, outlineColor: outlineColor, ); } /// 添加长方形 /// [center] 长方形中心的地理位置 /// [width] 长方形的宽度(单位:米) /// [height] 长方形的高度(单位:米) /// [color] 填充颜色 /// [outlineColor] 边框颜色 void addRectangle( Geographic center, { required double width, required double height, Color color = Colors.lightBlueAccent, Color outlineColor = Colors.blue, }) { mapUiBodyState?.addRectangle( center, width: width, height: height, color: color, outlineColor: outlineColor, ); } /// 清除所有自定义标记 void clearCustomMarkers() { mapUiBodyState?.clearCustomMarkers(); } /// 清除所有圆形 void clearCircles() { mapUiBodyState?.clearCircles(); } /// 清除所有多边形(包括扇形和长方形) void clearPolygons() { mapUiBodyState?.clearPolygons(); } /// 清除所有自定义图层 void clearAllCustomLayers() { mapUiBodyState?.clearAllCustomLayers(); } /// 添加固定大小的圆形(不随地图缩放) void addFixedCircle( Geographic position, { double radius = 20, Color color = Colors.orange, Color strokeColor = Colors.red, double strokeWidth = 2, }) { mapUiBodyState?.addFixedCircle( position, radius: radius, color: color, outlineColor: strokeColor, ); } } /// 音频系统 - 处理音频相关的实体和组件 class AudioSystem implements System { @override void update(List entities, Duration deltaTime) { for (var entity in entities) { if (entity.hasComponent()) { var audioComponent = entity.getComponent()!; _playAudio(audioComponent); } } } void _playAudio(AudioComponent audio) { // 实现音频播放逻辑 // 这里可以使用Flutter的音频插件如audioplayers print("Playing audio: ${audio.audioPath}"); } } /// 组件系统 - 管理各种组件的交互 class ComponentSystem implements System { @override void update(List entities, Duration deltaTime) { // 处理组件间的交互 for (var entity in entities) { // 可以根据需要实现组件交互逻辑 if (entity.hasComponent() && entity.hasComponent()) { // 当一个实体同时有标绘和图标组件时的特殊处理 } } } } /// ECS管理器 - 管理实体、系统和整个ECS框架 class ECSManager { static ECSManager? _instance; factory ECSManager() { _instance ??= ECSManager._internal(); return _instance!; } ECSManager._internal(); /// 获取单例实例 static ECSManager get instance { _instance ??= ECSManager._internal(); return _instance!; } final List _entities = []; final List _systems = []; final Queue _entitiesToAdd = Queue(); final Queue _entitiesToRemove = Queue(); void addEntity(Entity entity) { _entitiesToAdd.add(entity); } void removeEntity(Entity entity) { _entitiesToRemove.add(entity); } void addSystem(System system) { _systems.add(system); } void removeSystem(System system) { _systems.remove(system); } void update(Duration deltaTime) { // 添加新实体 while (_entitiesToAdd.isNotEmpty) { _entities.add(_entitiesToAdd.removeFirst()); } // 更新所有系统 for (var system in _systems) { system.update(_entities, deltaTime); } // 移除实体 while (_entitiesToRemove.isNotEmpty) { var entity = _entitiesToRemove.removeFirst(); _entities.remove(entity); } } List get entities => _entities; /// 工厂方法:创建一个带位置的实体 Entity createEntityAtPosition({ required String name, required gl.LatLng position, String? plotType, Color plotColor = Colors.red, double strokeWidth = 2.0, String? iconPath, double iconSize = 30.0, bool hasTrail = false, Color trailColor = Colors.blue, double trailMaxLength = 20.0, bool hasMovement = false, gl.LatLng? movementTarget, double movementSpeed = 1.0, String? audioPath, bool audioLoop = false, double audioVolume = 1.0, }) { // 创建实体 final entity = Entity(name: name); // 添加位置相关的组件 if (plotType != null) { entity.addComponent(PlotComponent( plotType: plotType, coordinates: [position], color: plotColor, strokeWidth: strokeWidth, )); } if (iconPath != null) { entity.addComponent(IconComponent( iconPath: iconPath, position: position, size: iconSize, )); } if (hasTrail) { entity.addComponent(TrailComponent( trailColor: trailColor, maxLength: trailMaxLength, )); } if (hasMovement) { entity.addComponent(MovementComponent( position: position, target: movementTarget, speed: movementSpeed, )); } if (audioPath != null) { entity.addComponent(AudioComponent( audioPath: audioPath, loop: audioLoop, volume: audioVolume, )); } // 添加到管理器 addEntity(entity); return entity; } }