""" 飞行模式逻辑: - 从坐标 JSON 读取最后一个坐标点作为目的地 - 每帧调用 `CoordinatePatrol.simple_flight_navigate()` 执行: 1) 上马(未上马则先上马,mount_key/mount_hold_sec 从 game_state_config.json 读取) 2) 起飞 3) 飞向目的地坐标 4) 降落 """ import json import logging from coordinate_patrol import CoordinatePatrol logger = logging.getLogger(__name__) def _load_last_waypoint_from_json(path): """读取与巡逻相同的 JSON 格式:[[x,y], ...],返回最后一个有效点 (x, y)。""" if not path: return None try: with open(path, "r", encoding="utf-8") as f: data = json.load(f) except Exception as e: logger.warning("读取航线 JSON 失败: %s", e) return None if not isinstance(data, list): return None last = None for item in data: if isinstance(item, (list, tuple)) and len(item) >= 2: try: last = (float(item[0]), float(item[1])) except (TypeError, ValueError): continue return last class FlightModeBot: """飞行模式控制器:每次执行逻辑只推动状态前进一步。""" def __init__( self, json_path, log_callback=None, *, takeoff_key="space", takeoff_hold_sec=2.0, land_key="p", land_hold_sec=2.0, ): self._log = log_callback or (lambda _m: None) self.destination = _load_last_waypoint_from_json(json_path) self.done = False # 上马按键与时长来自 game_state_config.json try: from game_state import load_layout_config cfg = load_layout_config() mount_key = str(cfg.get("mount_key", "x") or "x") mount_hold_sec = float(cfg.get("mount_hold_sec", 1.6)) mount_retry_after_sec = float(cfg.get("mount_retry_after_sec", 2.0)) except Exception: mount_key, mount_hold_sec, mount_retry_after_sec = "x", 1.6, 2.0 # 只用于 simple_flight_navigate 内部的 _ensure_mounted 与一些公共参数 self._patrol = CoordinatePatrol( waypoints=[(0.0, 0.0)] if self.destination else [], mount_key=mount_key, mount_hold_sec=mount_hold_sec, mount_retry_after_sec=mount_retry_after_sec, ) self.takeoff_key = takeoff_key self.takeoff_hold_sec = float(takeoff_hold_sec) self.land_key = land_key self.land_hold_sec = float(land_hold_sec) if not self.destination: self._log("❌ 飞行模式:JSON 中无有效坐标点") self.done = True def execute_logic(self, state): if self.done: return if state is None: return if not self.destination: self.done = True return arrived = self._patrol.simple_flight_navigate( state, self.destination[0], self.destination[1], takeoff_key=self.takeoff_key, takeoff_hold_sec=self.takeoff_hold_sec, land_key=self.land_key, land_hold_sec=self.land_hold_sec, dismount_key=self._patrol.mount_key, arrival_threshold=self._patrol.arrival_threshold, mount_wait_sec=self._patrol.mount_hold_sec, ) if arrived: self._patrol.stop_all() self.done = True self._log("✅ 飞行模式:已到达目的地并降落完成")