引言:HarmonyOS 5.0游戏开发的新纪元

2025年,HarmonyOS 5.0正式发布,标志着国产操作系统在游戏开发领域迈入全新阶段。搭载HarmonyOS 5的终端设备数已突破2300万台,游戏应用适配超过500款,其中分布式游戏成为生态亮点。与传统游戏开发相比,HarmonyOS游戏开发具备分布式渲染跨设备协同AI原生游戏引擎三大革命性优势。

HarmonyOS 5.0从内核层全栈自主研发,集成方舟图形引擎3.0,支持Vulkan 1.3和OpenGL ES 3.2双图形API,为高性能游戏渲染提供底层支撑。分布式软总线2.0技术将设备间通信延迟降至20ms以下,为多设备协同游戏体验奠定基础。截至2025年第三季度,鸿蒙游戏生态已覆盖手机、平板、智慧屏、车机等200+设备品类,连接设备数突破10亿,全球游戏开发者超过50万。

在游戏开发领域,HarmonyOS 5.0带来了前所未有的创新机遇。传统的游戏开发往往受限于单一设备性能,而HarmonyOS的分布式能力使得游戏可以无缝跨越多个设备,实现"超级终端"游戏体验。这种多设备协同的游戏模式,正是HarmonyOS游戏开发的最大魅力所在。

本文将带领开发者从零开始,基于HarmonyOS 5.0构建一个完整的分布式太空射击游戏。通过这个实战项目,您将掌握HarmonyOS游戏开发的核心技术,包括分布式游戏状态同步、AI对手系统、高性能图形渲染、跨设备输入处理等关键技能。游戏将支持手机、平板、PC多设备协同作战,实现真正的分布式游戏体验。

一、开发环境搭建与项目初始化

1.1 游戏开发专用环境配置

HarmonyOS游戏开发需要专门的开发环境配置,以下是详细步骤:

系统环境要求(游戏开发专用):

  • 操作系统:Windows 11 64位专业版/企业版(22H2及以上)

  • 处理器:Intel Core i9-13900K或AMD Ryzen 9 7950X(推荐)

  • 内存:32GB DDR5(最低16GB,推荐64GB)

  • 显卡:NVIDIA RTX 4070 Ti或AMD RX 7900 XT(支持硬件光线追踪)

  • 硬盘:NVMe SSD 1TB(游戏资源占用较大)

  • 网络:千兆以太网或Wi-Fi 6E

DevEco Studio 5.0.4游戏开发版安装:

  1. 访问华为开发者联盟游戏中心(https://developer.huawei.com/consumer/cn/games/),下载DevEco Studio 5.0.4 Game Development Edition

  2. 运行安装程序,选择游戏开发专用组件:

    • HarmonyOS Game SDK 5.0.4(API Version 16)

    • Ark Game Engine 2.0(新增分布式渲染支持)

    • 3D模型导入工具链

    • 物理引擎插件(Bullet Physics 3.24)

    • 音频处理引擎(OpenAL Soft 1.23)

    • AI游戏对手训练工具包

  3. 安装路径必须为纯英文,建议:D:\DevEcoStudio\GameDev

  4. 安装完成后,首次启动选择"Game Development"工作空间

游戏项目依赖配置:

// game-project/oh-package.json5
{
  "license": "GPL-3.0",
  "devDependencies": {
    "@ohos/hypium": "5.0.4.15",
    "@ohos/game-test": "5.0.4.8"
  },
  "dependencies": {
    "@ohos/arkui": "5.0.4.15",
    "@ohos/graphics": "5.0.4.15",
    "@ohos/audio": "5.0.4.15",
    "@ohos/input": "5.0.4.15",
    "@ohos/distributed": "5.0.4.15",
    "@ohos/ai": "5.0.4.15",
    "@ohos/physics": "5.0.4.15",
    "@ohos/network": "5.0.4.15",
    "@ohos/game-engine": "2.0.4.15"
  }
}

1.2 创建分布式太空射击游戏项目

使用DevEco Studio创建HarmonyOS游戏项目:

  1. 点击"File" → "New" → "Create Game Project"

  2. 选择"3D Space Shooter"模板

  3. 配置项目信息:

    • Project Name: DistributedSpaceShooter

    • Project Type: Game Application

    • Bundle Name: com.example.space.shooter

    • Save Location: D:\HarmonyOSGames\

    • Compatible SDK: HarmonyOS 5.0.4 (API 16)

    • Game Engine: Ark Game Engine 2.0

    • Language: ArkTS

    • Supported Devices: Phone, Tablet, PC

    • Multiplayer Support: Enabled

    • AI Opponent: Enabled

  4. 点击"Finish"创建项目

游戏项目结构解析:

DistributedSpaceShooter/
├── entry/                          # 游戏主模块
│   ├── src/main/ets/
│   │   ├── gameability/           # 游戏Ability入口
│   │   ├── scenes/                # 游戏场景
│   │   │   ├── MainMenu.ets      # 主菜单场景
│   │   │   ├── GameScene.ets     # 游戏主场景
│   │   │   └── GameOver.ets      # 游戏结束场景
│   │   ├── entities/              # 游戏实体
│   │   │   ├── PlayerShip.ets    # 玩家飞船
│   │   │   ├── Enemy.ets         # 敌人实体
│   │   │   ├── Bullet.ets        # 子弹实体
│   │   │   └── PowerUp.ets       # 能量道具
│   │   ├── systems/               # 游戏系统
│   │   │   ├── RenderSystem.ets  # 渲染系统
│   │   │   ├── InputSystem.ets   # 输入系统
│   │   │   ├── PhysicsSystem.ets # 物理系统
│   │   │   ├── AISystem.ets      # AI系统
│   │   │   └── NetworkSystem.ets # 网络系统
│   │   ├── components/            # 游戏组件
│   │   ├── managers/              # 游戏管理器
│   │   └── utils/                 # 游戏工具类
│   ├── src/main/resources/        # 游戏资源
│   │   ├── media/                 # 媒体资源
│   │   │   ├── textures/         # 纹理贴图
│   │   │   ├── models/           # 3D模型
│   │   │   ├── sounds/           # 音效
│   │   │   └── shaders/          # 着色器
│   │   └── config/                # 配置文件
├── feature/                        # 特性模块
│   ├── multiplayer/               # 多人游戏模块
│   ├── distributed/               # 分布式模块
│   └── ai-training/               # AI训练模块
└── oh-package.json5               # 依赖管理

二、HarmonyOS 5.0游戏开发核心技术

2.1 方舟游戏引擎架构

Ark Game Engine 2.0是HarmonyOS 5.0专为游戏开发优化的引擎,支持实体组件系统(ECS)架构和分布式渲染。

游戏引擎核心初始化:

// systems/GameEngine.ets
import { GameEngine, SceneManager, EntityManager, SystemManager } from '@ohos/game-engine';
import { BusinessError } from '@ohos.base';

export class SpaceShooterEngine {
  private gameEngine: GameEngine | null = null;
  private sceneManager: SceneManager | null = null;
  private entityManager: EntityManager | null = null;
  private systemManager: SystemManager | null = null;
  
  // 初始化游戏引擎
  async initialize(canvasId: string): Promise<void> {
    try {
      // 创建游戏引擎实例
      const engineConfig = {
        canvasId: canvasId,
        renderer: {
          type: 'webgl2',
          antialias: true,
          alpha: false,
          depth: true,
          stencil: true,
          preserveDrawingBuffer: false
        },
        physics: {
          enabled: true,
          gravity: { x: 0, y: -9.8, z: 0 },
          worldScale: 1.0
        },
        audio: {
          enabled: true,
          spatialAudio: true,
          maxChannels: 32
        },
        network: {
          enabled: true,
          syncRate: 60, // 60Hz同步频率
          prediction: true
        }
      };
      
      this.gameEngine = await GameEngine.create(engineConfig);
      
      // 获取管理器实例
      this.sceneManager = this.gameEngine.getSceneManager();
      this.entityManager = this.gameEngine.getEntityManager();
      this.systemManager = this.gameEngine.getSystemManager();
      
      // 注册游戏系统
      await this.registerGameSystems();
      
      // 加载初始场景
      await this.loadInitialScene();
      
      console.log('Game engine initialized successfully');
    } catch (error) {
      console.error('Failed to initialize game engine:', (error as BusinessError).message);
    }
  }
  
  // 注册游戏系统
  private async registerGameSystems(): Promise<void> {
    if (!this.systemManager) return;
    
    // 渲染系统
    await this.systemManager.registerSystem('render', {
      priority: 1000,
      components: ['Transform', 'MeshRenderer'],
      update: (deltaTime: number, entities: number[]) => {
        this.updateRenderSystem(deltaTime, entities);
      }
    });
    
    // 输入系统
    await this.systemManager.registerSystem('input', {
      priority: 900,
      components: ['PlayerController'],
      update: (deltaTime: number, entities: number[]) => {
        this.updateInputSystem(deltaTime, entities);
      }
    });
    
    // 物理系统
    await this.systemManager.registerSystem('physics', {
      priority: 800,
      components: ['Transform', 'Rigidbody'],
      update: (deltaTime: number, entities: number[]) => {
        this.updatePhysicsSystem(deltaTime, entities);
      }
    });
    
    // AI系统
    await this.systemManager.registerSystem('ai', {
      priority: 700,
      components: ['AIBehavior', 'Transform'],
      update: (deltaTime: number, entities: number[]) => {
        this.updateAISystem(deltaTime, entities);
      }
    });
    
    // 网络同步系统
    await this.systemManager.registerSystem('network', {
      priority: 600,
      components: ['NetworkSync'],
      update: (deltaTime: number, entities: number[]) => {
        this.updateNetworkSystem(deltaTime, entities);
      }
    });
    
    // 碰撞检测系统
    await this.systemManager.registerSystem('collision', {
      priority: 500,
      components: ['Collider', 'Transform'],
      update: (deltaTime: number, entities: number[]) => {
        this.updateCollisionSystem(deltaTime, entities);
      }
    });
  }
  
  // 开始游戏循环
  startGameLoop(): void {
    if (!this.gameEngine) return;
    
    let lastTime = 0;
    
    const gameLoop = (currentTime: number) => {
      const deltaTime = (currentTime - lastTime) / 1000;
      lastTime = currentTime;
      
      // 限制最大帧时间
      const clampedDeltaTime = Math.min(deltaTime, 0.1);
      
      // 更新所有系统
      this.updateGameSystems(clampedDeltaTime);
      
      // 请求下一帧
      requestAnimationFrame(gameLoop);
    };
    
    requestAnimationFrame(gameLoop);
  }
  
  // 更新游戏系统
  private updateGameSystems(deltaTime: number): void {
    if (!this.systemManager) return;
    
    // 按优先级顺序更新系统
    this.systemManager.updateSystem('input', deltaTime);
    this.systemManager.updateSystem('physics', deltaTime);
    this.systemManager.updateSystem('ai', deltaTime);
    this.systemManager.updateSystem('collision', deltaTime);
    this.systemManager.updateSystem('network', deltaTime);
    this.systemManager.updateSystem('render', deltaTime);
  }
}

2.2 分布式游戏状态同步

HarmonyOS 5.0的分布式数据同步技术为多设备游戏提供了底层支持。

分布式游戏状态管理:

// systems/NetworkSystem.ets
import distributedData from '@ohos.data.distributedData';
import { BusinessError } from '@ohos.base';

export class NetworkSystem {
  private kvManager: distributedData.KVManager | null = null;
  private kvStore: distributedData.KVStore | null = null;
  private connectedPlayers: Map<string, PlayerInfo> = new Map();
  private localPlayerId: string = '';
  private gameState: GameState = GameState.WAITING;
  
  // 初始化网络系统
  async initialize(): Promise<void> {
    try {
      const config: distributedData.KVManagerConfig = {
        bundleName: 'com.example.space.shooter',
        context: getContext(this)
      };
      
      // 创建KV管理器
      this.kvManager = await distributedData.createKVManager(config);
      
      // 创建游戏专用的KV存储
      const options: distributedData.Options = {
        createIfMissing: true,
        encrypt: true,
        backup: false,
        autoSync: true,
        kvStoreType: distributedData.KVStoreType.SINGLE_VERSION,
        securityLevel: distributedData.SecurityLevel.S2,
        syncMode: distributedData.SyncMode.PUSH_PULL
      };
      
      this.kvStore = await this.kvManager.getKVStore<distributedData.KVStore>('game_session', options);
      
      // 生成本地玩家ID
      this.localPlayerId = this.generatePlayerId();
      
      // 注册数据变更监听
      await this.registerDataChangeListener();
      
      // 加入游戏会话
      await this.joinGameSession();
      
      console.log('Network system initialized, player ID:', this.localPlayerId);
    } catch (error) {
      console.error('Failed to initialize network system:', (error as BusinessError).message);
    }
  }
  
  // 生成玩家ID
  private generatePlayerId(): string {
    const timestamp = Date.now();
    const random = Math.floor(Math.random() * 10000);
    return `player_${timestamp}_${random}`;
  }
  
  // 注册数据变更监听
  private async registerDataChangeListener(): Promise<void> {
    if (!this.kvStore) return;
    
    try {
      await this.kvStore.on('dataChange', distributedData.SubscribeType.SUBSCRIBE_TYPE_ALL, 
        (data: distributedData.ChangeData[]) => {
          this.handleGameDataChange(data);
        }
      );
    } catch (error) {
      console.error('Failed to register data change listener:', (error as BusinessError).message);
    }
  }
  
  // 处理游戏数据变更
  private handleGameDataChange(data: distributedData.ChangeData[]): void {
    data.forEach((change: distributedData.ChangeData) => {
      const key = change.key;
      const value = change.value;
      const deviceId = change.deviceId;
      
      // 忽略本地设备发送的数据
      if (deviceId === this.getLocalDeviceId()) return;
      
      try {
        const dataStr = new TextDecoder().decode(value);
        const gameData = JSON.parse(dataStr);
        
        // 根据数据类型处理
        switch (key) {
          case 'player_join':
            this.handlePlayerJoin(gameData, deviceId);
            break;
          case 'player_leave':
            this.handlePlayerLeave(gameData, deviceId);
            break;
          case 'game_state':
            this.handleGameStateUpdate(gameData, deviceId);
            break;
          case 'entity_update':
            this.handleEntityUpdate(gameData, deviceId);
            break;
          case 'input_command':
            this.handleInputCommand(gameData, deviceId);
            break;
          case 'collision_event':
            this.handleCollisionEvent(gameData, deviceId);
            break;
        }
      } catch (error) {
        console.error('Failed to parse game data:', error);
      }
    });
  }
  
  // 加入游戏会话
  private async joinGameSession(): Promise<void> {
    if (!this.kvStore) return;
    
    try {
      const playerInfo: PlayerInfo = {
        playerId: this.localPlayerId,
        deviceId: this.getLocalDeviceId(),
        playerName: this.getPlayerName(),
        joinTime: Date.now(),
        ready: false,
        score: 0,
        lives: 3
      };
      
      const key = `player_${this.localPlayerId}`;
      const value = new TextEncoder().encode(JSON.stringify(playerInfo));
      
      // 保存玩家信息
      await this.kvStore.put(key, value);
      
      // 广播玩家加入事件
      await this.broadcastPlayerJoin(playerInfo);
      
      // 添加到本地玩家列表
      this.connectedPlayers.set(this.localPlayerId, playerInfo);
      
      console.log('Player joined game session:', playerInfo.playerName);
    } catch (error) {
      console.error('Failed to join game session:', (error as BusinessError).message);
    }
  }
  
  // 广播玩家加入事件
  private async broadcastPlayerJoin(playerInfo: PlayerInfo): Promise<void> {
    if (!this.kvStore) return;
    
    try {
      const eventData = {
        type: 'player_join',
        playerId: playerInfo.playerId,
        playerName: playerInfo.playerName,
        timestamp: Date.now()
      };
      
      const key = `event_player_join_${Date.now()}`;
      const value = new TextEncoder().encode(JSON.stringify(eventData));
      
      await this.kvStore.put(key, value);
    } catch (error) {
      console.error('Failed to broadcast player join:', (error as BusinessError).message);
    }
  }
  
  // 发送实体状态更新
  async sendEntityUpdate(entityId: string, entityData: EntityData): Promise<void> {
    if (!this.kvStore) return;
    
    try {
      const updateData = {
        type: 'entity_update',
        entityId: entityId,
        data: entityData,
        playerId: this.localPlayerId,
        timestamp: Date.now()
      };
      
      const key = `entity_${entityId}_${Date.now()}`;
      const value = new TextEncoder().encode(JSON.stringify(updateData));
      
      await this.kvStore.put(key, value);
    } catch (error) {
      console.error('Failed to send entity update:', (error as BusinessError).message);
    }
  }
  
  // 发送输入命令
  async sendInputCommand(command: InputCommand): Promise<void> {
    if (!this.kvStore) return;
    
    try {
      const commandData = {
        type: 'input_command',
        command: command,
        playerId: this.localPlayerId,
        timestamp: Date.now(),
        sequence: this.getNextSequenceNumber()
      };
      
      const key = `input_${this.localPlayerId}_${commandData.sequence}`;
      const value = new TextEncoder().encode(JSON.stringify(commandData));
      
      await this.kvStore.put(key, value);
    } catch (error) {
      console.error('Failed to send input command:', (error as BusinessError).message);
    }
  }
  
  // 开始游戏
  async startGame(): Promise<void> {
    if (!this.kvStore) return;
    
    try {
      this.gameState = GameState.PLAYING;
      
      const gameStateData = {
        type: 'game_state',
        state: GameState.PLAYING,
        startTime: Date.now(),
        level: 1,
        players: Array.from(this.connectedPlayers.values())
      };
      
      const key = 'game_state_current';
      const value = new TextEncoder().encode(JSON.stringify(gameStateData));
      
      await this.kvStore.put(key, value);
      
      console.log('Game started with', this.connectedPlayers.size, 'players');
    } catch (error) {
      console.error('Failed to start game:', (error as BusinessError).message);
    }
  }
  
  // 获取本地设备ID
  private getLocalDeviceId(): string {
    // 实际实现中应从系统获取设备ID
    return 'local_device_' + Math.random().toString(36).substr(2, 9);
  }
  
  // 获取玩家名称
  private getPlayerName(): string {
    const names = ['太空战士', '星际游侠', '银河护卫', '宇宙探索者'];
    return names[Math.floor(Math.random() * names.length)];
  }
  
  // 获取下一个序列号
  private getNextSequenceNumber(): number {
    return Date.now() % 1000000;
  }
}

三、实战项目:分布式太空射击游戏开发

3.1 游戏实体与组件系统

采用ECS架构设计游戏实体,提高代码复用性和性能。

玩家飞船实体实现:

// entities/PlayerShip.ets
import { Entity, Component, System } from '@ohos/game-engine';

@Component
export class TransformComponent {
  @Track position: Vector3 = { x: 0, y: 0, z: 0 };
  @Track rotation: Quaternion = { x: 0, y: 0, z: 0, w: 1 };
  @Track scale: Vector3 = { x: 1, y: 1, z: 1 };
  
  constructor(initialPosition?: Vector3) {
    if (initialPosition) {
      this.position = initialPosition;
    }
  }
  
  move(delta: Vector3): void {
    this.position.x += delta.x;
    this.position.y += delta.y;
    this.position.z += delta.z;
  }
  
  rotate(angle: number, axis: Vector3): void {
    const halfAngle = angle * 0.5;
    const sinHalf = Math.sin(halfAngle);
    
    const rotationDelta: Quaternion = {
      x: axis.x * sinHalf,
      y: axis.y * sinHalf,
      z: axis.z * sinHalf,
      w: Math.cos(halfAngle)
    };
    
    this.rotation = this.multiplyQuaternions(this.rotation, rotationDelta);
  }
  
  private multiplyQuaternions(q1: Quaternion, q2: Quaternion): Quaternion {
    return {
      x: q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y,
      y: q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x,
      z: q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w,
      w: q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z
    };
  }
}

@Component
export class PlayerControllerComponent {
  @Track playerId: string = '';
  @Track moveSpeed: number = 5.0;
  @Track rotationSpeed: number = 2.0;
  @Track fireRate: number = 0.2; // 每秒发射次数
  @Track lastFireTime: number = 0;
  @Track health: number = 100;
  @Track maxHealth: number = 100;
  @Track shields: number = 50;
  @Track maxShields: number = 50;
  @Track score: number = 0;
  @Track lives: number = 3;
  
  // 输入状态
  @Track inputMove: Vector2 = { x: 0, y: 0 };
  @Track inputRotate: Vector2 = { x: 0, y: 0 };
  @Track isFiring: boolean = false;
  @Track specialAbility: boolean = false;
  
  constructor(playerId: string) {
    this.playerId = playerId;
  }
  
  canFire(): boolean {
    const currentTime = Date.now() / 1000;
    return currentTime - this.lastFireTime >= 1.0 / this.fireRate;
  }
  
  fire(): void {
    if (this.canFire()) {
      this.lastFireTime = Date.now() / 1000;
      this.isFiring = true;
    }
  }
  
  takeDamage(amount: number): void {
    // 先扣除护盾
    if (this.shields > 0) {
      const shieldDamage = Math.min(amount, this.shields);
      this.shields -= shieldDamage;
      amount -= shieldDamage;
    }
    
    // 剩余伤害扣除生命值
    if (amount > 0) {
      this.health = Math.max(0, this.health - amount);
    }
  }
  
  heal(amount: number): void {
    this.health = Math.min(this.maxHealth, this.health + amount);
  }
  
  rechargeShields(amount: number): void {
    this.shields = Math.min(this.maxShields, this.shields + amount);
  }
  
  addScore(points: number): void {
    this.score += points;
  }
  
  loseLife(): boolean {
    if (this.lives > 0) {
      this.lives--;
      return true;
    }
    return false;
  }
}

@Component
export class MeshRendererComponent {
  @Track meshId: string = '';
  @Track materialId: string = '';
  @Track visible: boolean = true;
  @Track castShadow: boolean = true;
  @Track receiveShadow: boolean = true;
  @Track layer: number = 0; // 渲染层
  
  constructor(meshId: string, materialId: string) {
    this.meshId = meshId;
    this.materialId = materialId;
  }
}

@Component
export class RigidbodyComponent {
  @Track velocity: Vector3 = { x: 0, y: 0, z: 0 };
  @Track angularVelocity: Vector3 = { x: 0, y: 0, z: 0 };
  @Track mass: number = 1.0;
  @Track drag: number = 0.1;
  @Track angularDrag: number = 0.05;
  @Track useGravity: boolean = false;
  @Track isKinematic: boolean = false;
  @Track constraints: RigidbodyConstraints = RigidbodyConstraints.NONE;
  
  applyForce(force: Vector3): void {
    if (!this.isKinematic) {
      const acceleration = {
        x: force.x / this.mass,
        y: force.y / this.mass,
        z: force.z / this.mass
      };
      
      this.velocity.x += acceleration.x;
      this.velocity.y += acceleration.y;
      this.velocity.z += acceleration.z;
    }
  }
  
  applyTorque(torque: Vector3): void {
    if (!this.isKinematic) {
      // 简化处理,实际应计算转动惯量
      this.angularVelocity.x += torque.x;
      this.angularVelocity.y += torque.y;
      this.angularVelocity.z += torque.z;
    }
  }
}

@Component
export class ColliderComponent {
  @Track colliderType: ColliderType = ColliderType.BOX;
  @Track size: Vector3 = { x: 1, y: 1, z: 1 };
  @Track radius: number = 0.5;
  @Track height: number = 2.0;
  @Track isTrigger: boolean = false;
  @Track layer: number = 0;
  @Track mask: number = 0xFFFFFFFF;
  
  constructor(type: ColliderType, size?: Vector3) {
    this.colliderType = type;
    if (size) {
      this.size = size;
    }
  }
}

// 玩家飞船实体创建
export class PlayerShipEntity {
  static create(playerId: string, initialPosition: Vector3): Entity {
    const entity = EntityManager.createEntity();
    
    // 添加变换组件
    EntityManager.addComponent(entity, new TransformComponent(initialPosition));
    
    // 添加玩家控制器组件
    EntityManager.addComponent(entity, new PlayerControllerComponent(playerId));
    
    // 添加网格渲染组件
    EntityManager.addComponent(entity, new MeshRendererComponent('player_ship', 'player_material'));
    
    // 添加刚体组件
    const rigidbody = new RigidbodyComponent();
    rigidbody.mass = 2.0;
    rigidbody.drag = 0.2;
    EntityManager.addComponent(entity, rigidbody);
    
    // 添加碰撞体组件
    const collider = new ColliderComponent(ColliderType.CAPSULE);
    collider.radius = 0.8;
    collider.height = 2.5;
    EntityManager.addComponent(entity, collider);
    
    // 添加武器组件
    EntityManager.addComponent(entity, new WeaponComponent());
    
    // 添加特效组件
    EntityManager.addComponent(entity, new ParticleEffectComponent('engine_thrust'));
    
    return entity;
  }
}

3.2 游戏输入系统实现

支持多设备输入,包括触屏、键盘、手柄等。

跨设备输入系统:

// systems/InputSystem.ets
import input from '@ohos.input';
import { BusinessError } from '@ohos.base';

export class InputSystem {
  private touchEventListeners: Map<string, TouchEventListener> = new Map();
  private keyEventListeners: Map<string, KeyEventListener> = new Map();
  private gamepadEventListeners: Map<string, GamepadEventListener> = new Map();
  private inputState: InputState = new InputState();
  private networkSystem: NetworkSystem | null = null;
  
  // 初始化输入系统
  async initialize(networkSystem: NetworkSystem): Promise<void> {
    this.networkSystem = networkSystem;
    
    try {
      // 注册触屏输入监听
      await this.registerTouchInput();
      
      // 注册键盘输入监听
      await this.registerKeyboardInput();
      
      // 注册游戏手柄输入监听
      await this.registerGamepadInput();
      
      // 注册分布式输入监听
      await this.registerDistributedInput();
      
      console.log('Input system initialized successfully');
    } catch (error) {
      console.error('Failed to initialize input system:', (error as BusinessError).message);
    }
  }
  
  // 注册触屏输入
  private async registerTouchInput(): Promise<void> {
    try {
      const touchEventListener: input.TouchEventListener = {
        onTouchEvent: (touchEvent: input.TouchEvent) => {
          this.handleTouchEvent(touchEvent);
        }
      };
      
      const listenerId = await input.on('touch', touchEventListener);
      this.touchEventListeners.set('main', { id: listenerId, listener: touchEventListener });
    } catch (error) {
      console.error('Failed to register touch input:', (error as BusinessError).message);
    }
  }
  
  // 处理触屏事件
  private handleTouchEvent(touchEvent: input.TouchEvent): void {
    const touches = touchEvent.touches;
    
    if (touches.length === 0) return;
    
    // 更新输入状态
    this.inputState.touchPosition = {
      x: touches[0].screenX,
      y: touches[0].screenY
    };
    
    this.inputState.isTouching = touchEvent.action !== input.TouchAction.UP;
    
    // 发送输入命令到网络
    if (this.networkSystem) {
      const command: InputCommand = {
        type: 'touch',
        position: this.inputState.touchPosition,
        isActive: this.inputState.isTouching,
        timestamp: Date.now()
      };
      
      this.networkSystem.sendInputCommand(command);
    }
    
    // 触发游戏事件
    this.triggerInputEvents();
  }
  
  // 注册键盘输入
  private async registerKeyboardInput(): Promise<void> {
    try {
      const keyEventListener: input.KeyEventListener = {
        onKeyEvent: (keyEvent: input.KeyEvent) => {
          this.handleKeyEvent(keyEvent);
        }
      };
      
      const listenerId = await input.on('key', keyEventListener);
      this.keyEventListeners.set('main', { id: listenerId, listener: keyEventListener });
    } catch (error) {
      console.error('Failed to register keyboard input:', (error as BusinessError).message);
    }
  }
  
  // 处理键盘事件
  private handleKeyEvent(keyEvent: input.KeyEvent): void {
    const keyCode = keyEvent.keyCode;
    const isPressed = keyEvent.action === input.KeyAction.DOWN;
    
    // 更新输入状态
    switch (keyCode) {
      case input.KeyCode.KEY_W:
      case input.KeyCode.KEY_UP:
        this.inputState.moveUp = isPressed;
        break;
      case input.KeyCode.KEY_S:
      case input.KeyCode.KEY_DOWN:
        this.inputState.moveDown = isPressed;
        break;
      case input.KeyCode.KEY_A:
      case input.KeyCode.KEY_LEFT:
        this.inputState.moveLeft = isPressed;
        break;
      case input.KeyCode.KEY_D:
      case input.KeyCode.KEY_RIGHT:
        this.inputState.moveRight = isPressed;
        break;
      case input.KeyCode.KEY_SPACE:
        this.inputState.fire = isPressed;
        break;
      case input.KeyCode.KEY_SHIFT_LEFT:
      case input.KeyCode.KEY_SHIFT_RIGHT:
        this.inputState.specialAbility = isPressed;
        break;
    }
    
    // 发送输入命令到网络
    if (this.networkSystem) {
      const command: InputCommand = {
        type: 'keyboard',
        keyCode: keyCode,
        isPressed: isPressed,
        timestamp: Date.now()
      };
      
      this.networkSystem.sendInputCommand(command);
    }
    
    // 触发游戏事件
    this.triggerInputEvents();
  }
  
  // 注册游戏手柄输入
  private async registerGamepadInput(): Promise<void> {
    try {
      // 获取已连接的游戏手柄
      const gamepads = await input.getGamepads();
      
      gamepads.forEach((gamepad: input.Gamepad, index: number) => {
        const gamepadEventListener: input.GamepadEventListener = {
          onGamepadEvent: (gamepadEvent: input.GamepadEvent) => {
            this.handleGamepadEvent(gamepadEvent, index);
          }
        };
        
        const listenerId = input.on(`gamepad${index}`, gamepadEventListener);
        this.gamepadEventListeners.set(`gamepad${index}`, { 
          id: listenerId, 
          listener: gamepadEventListener 
        });
      });
    } catch (error) {
      console.error('Failed to register gamepad input:', (error as BusinessError).message);
    }
  }
  
  // 处理游戏手柄事件
  private handleGamepadEvent(gamepadEvent: input.GamepadEvent, gamepadIndex: number): void {
    // 更新输入状态
    this.inputState.gamepadAxes = gamepadEvent.axes;
    this.inputState.gamepadButtons = gamepadEvent.buttons;
    
    // 发送输入命令到网络
    if (this.networkSystem) {
      const command: InputCommand = {
        type: 'gamepad',
        gamepadIndex: gamepadIndex,
        axes: gamepadEvent.axes,
        buttons: gamepadEvent.buttons,
        timestamp: Date.now()
      };
      
      this.networkSystem.sendInputCommand(command);
    }
    
    // 触发游戏事件
    this.triggerInputEvents();
  }
  
  // 注册分布式输入监听
  private async registerDistributedInput(): Promise<void> {
    // 监听来自其他设备的输入命令
    if (this.networkSystem) {
      // 实际实现中应注册网络系统的回调
    }
  }
  
  // 处理远程输入命令
  handleRemoteInput(command: InputCommand): void {
    switch (command.type) {
      case 'touch':
        this.inputState.remoteTouchPosition = command.position;
        this.inputState.remoteIsTouching = command.isActive;
        break;
      case 'keyboard':
        // 更新远程键盘状态
        break;
      case 'gamepad':
        // 更新远程游戏手柄状态
        break;
    }
  }
  
  // 触发输入事件
  private triggerInputEvents(): void {
    // 计算移动向量
    const moveVector = this.calculateMoveVector();
    
    // 计算旋转
    const rotation = this.calculateRotation();
    
    // 触发事件
    this.dispatchInputEvent({
      type: 'player_input',
      move: moveVector,
      rotation: rotation,
      fire: this.inputState.fire,
      specialAbility: this.inputState.specialAbility,
      timestamp: Date.now()
    });
  }
  
  // 计算移动向量
  private calculateMoveVector(): Vector2 {
    let x = 0;
    let y = 0;
    
    if (this.inputState.moveUp) y += 1;
    if (this.inputState.moveDown) y -= 1;
    if (this.inputState.moveLeft) x -= 1;
    if (this.inputState.moveRight) x += 1;
    
    // 归一化
    if (x !== 0 || y !== 0) {
      const length = Math.sqrt(x * x + y * y);
      x /= length;
      y /= length;
    }
    
    return { x, y };
  }
  
  // 计算旋转
  private calculateRotation(): number {
    // 根据输入计算旋转角度
    let rotation = 0;
    
    if (this.inputState.moveLeft) rotation += 1;
    if (this.inputState.moveRight) rotation -= 1;
    
    return rotation;
  }
  
  // 分发输入事件
  private dispatchInputEvent(event: InputEvent): void {
    // 实际实现中应通知所有监听器
    console.log('Input event:', event);
  }
  
  // 获取当前输入状态
  getInputState(): InputState {
    return { ...this.inputState };
  }
  
  // 清理资源
  cleanup(): void {
    // 移除所有监听器
    this.touchEventListeners.forEach((listener) => {
      input.off('touch', listener.id);
    });
    
    this.keyEventListeners.forEach((listener) => {
      input.off('key', listener.id);
    });
    
    this.gamepadEventListeners.forEach((listener) => {
      input.off('gamepad', listener.id);
    });
    
    this.touchEventListeners.clear();
    this.keyEventListeners.clear();
    this.gamepadEventListeners.clear();
  }
}

3.3 AI对手系统实现

集成HarmonyOS 5.0的AI能力,创建智能游戏对手。

AI行为系统:

// systems/AISystem.ets
import ai from '@ohos.ai';
import { BusinessError } from '@ohos.base';

// ======================== 补充缺失的类型定义 ========================
// 向量类型(3D坐标)
declare interface Vector3 {
  x: number;
  y: number;
  z: number;
}

// 敌人类型枚举
export enum EnemyType {
  GRUNT = 'grunt',       // 普通杂兵
  SNIPER = 'sniper',     // 狙击手
  TANK = 'tank',         // 坦克型敌人
  ASSASSIN = 'assassin'  // 刺客型敌人
}

// AI状态枚举
export enum AIState {
  PATROLLING = 'patrolling', // 巡逻
  CHASING = 'chasing',       // 追击
  ATTACKING = 'attacking',   // 攻击
  EVADING = 'evading',       // 躲避
  SEARCHING = 'searching',   // 搜索
  RELOADING = 'reloading'    // 换弹
}

// AI行为数据结构
export interface AIBehavior {
  entityId: number;          // 实体ID
  type: EnemyType;           // 敌人类型
  state: AIState;            // 当前AI状态
  targetPlayerId: number | null; // 目标玩家ID
  lastDecisionTime: number;  // 上次决策时间(秒)
  decisionInterval: number;  // 决策间隔(秒)
  patrolPoints: Vector3[];   // 巡逻点列表
  currentPatrolIndex: number;// 当前巡逻点索引
  aggression: number;        // 攻击性(0-1)
  accuracy: number;          // 攻击精度(0-1)
  reactionTime: number;      // 反应时间(秒)
  health: number;            // 生命值
  speed: number;             // 移动速度
  attackCooldown: number;    // 攻击冷却时间
  lastAttackTime: number;    // 上次攻击时间
  evadeDistance: number;     // 躲避距离阈值
}

// 玩家信息(供AI检测用)
interface PlayerInfo {
  playerId: number;
  position: Vector3;
  health: number;
  isVisible: boolean;
  lastSeenTime: number;
}

// 游戏状态(供AI决策用)
interface GameStateForAI {
  selfPosition: Vector3;
  targetPosition: Vector3 | null;
  distanceToTarget: number;
  selfHealth: number;
  targetHealth: number;
  nearbyEnemies: number;
  coverAvailable: boolean;
  ammoCount: number;
  isReloading: boolean;
}

// 模拟实体管理器(实际项目中替换为真实实现)
export const EntityManager = {
  // 创建实体并返回ID
  createEntity: (): number => {
    return Math.floor(Math.random() * 1000000);
  },
  // 获取实体数据
  getEntity: (entityId: number): {
    position: Vector3;
    rotation: Vector3;
    health: number;
    speed: number;
    setPosition: (pos: Vector3) => void;
    setRotation: (rot: Vector3) => void;
    move: (dir: Vector3, speed: number, deltaTime: number) => void;
    attack: (targetId: number, accuracy: number) => boolean;
    playAnimation: (animName: string) => void;
  } => {
    return {
      position: { x: 0, y: 0, z: 0 },
      rotation: { x: 0, y: 0, z: 0 },
      health: 100,
      speed: 5,
      setPosition: (pos: Vector3) => {},
      setRotation: (rot: Vector3) => {},
      move: (dir: Vector3, speed: number, deltaTime: number) => {},
      attack: (targetId: number, accuracy: number) => true,
      playAnimation: (animName: string) => {}
    };
  },
  // 获取玩家列表
  getPlayers: (): PlayerInfo[] => {
    return [];
  },
  // 计算两点距离
  calculateDistance: (pos1: Vector3, pos2: Vector3): number => {
    const dx = pos2.x - pos1.x;
    const dy = pos2.y - pos1.y;
    const dz = pos2.z - pos1.z;
    return Math.sqrt(dx * dx + dy * dy + dz * dz);
  },
  // 查找最近的掩体
  findNearestCover: (position: Vector3, targetPos: Vector3): Vector3 | null => {
    // 模拟返回掩体位置
    return { x: position.x + 5, y: position.y, z: position.z + 5 };
  }
};

// ======================== AI系统核心实现 ========================
export class AISystem {
  private nlpEngine: ai.nlp.NlpEngine | null = null;
  private reinforcementModel: ai.rl.ReinforcementModel | null = null;
  private enemyEntities: Map<number, AIBehavior> = new Map();
  private difficultyLevel: number = 1; // 1-5级难度
  
  // 初始化AI系统
  async initialize(): Promise<void> {
    try {
      // 初始化NLP引擎用于行为分析
      const nlpConfig: ai.nlp.NlpEngineConfig = {
        modelPath: 'models/ai/enemy_behavior.h5',
        computeUnit: ai.nlp.ComputeUnit.AI_COMPUTE_UNIT_GPU
      };
      
      this.nlpEngine = await ai.nlp.createNlpEngine(nlpConfig);
      
      // 初始化强化学习模型
      const rlConfig: ai.rl.ReinforcementConfig = {
        modelPath: 'models/ai/enemy_rl_model.h5',
        stateSize: 10,
        actionSize: 5,
        learningRate: 0.001,
        discountFactor: 0.95
      };
      
      this.reinforcementModel = await ai.rl.createReinforcementModel(rlConfig);
      
      console.log('AI system initialized successfully');
    } catch (error) {
      console.error('Failed to initialize AI system:', (error as BusinessError).message);
      // 降级策略:禁用强化学习,仅使用规则式AI
      this.reinforcementModel = null;
      console.warn('Falling back to rule-based AI only');
    }
  }
  
  // 设置难度等级
  setDifficulty(level: number): void {
    this.difficultyLevel = Math.max(1, Math.min(5, level));
    console.log(`AI difficulty set to level ${this.difficultyLevel}`);
    
    // 动态调整现有敌人的AI参数
    this.enemyEntities.forEach(behavior => {
      this.adjustAIForDifficulty(behavior);
    });
  }
  
  // 创建AI敌人
  createEnemy(type: EnemyType, position: Vector3): number {
    const entityId = EntityManager.createEntity();
    const baseBehavior = this.getBaseBehaviorByType(type);
    
    const aiBehavior: AIBehavior = {
      entityId: entityId,
      type: type,
      state: AIState.PATROLLING,
      targetPlayerId: null,
      lastDecisionTime: Date.now() / 1000,
      decisionInterval: baseBehavior.decisionInterval,
      patrolPoints: this.generatePatrolPoints(position, baseBehavior.patrolRadius),
      currentPatrolIndex: 0,
      aggression: baseBehavior.aggression,
      accuracy: baseBehavior.accuracy,
      reactionTime: baseBehavior.reactionTime,
      health: baseBehavior.health,
      speed: baseBehavior.speed,
      attackCooldown: baseBehavior.attackCooldown,
      lastAttackTime: 0,
      evadeDistance: baseBehavior.evadeDistance
    };
    
    // 根据难度调整AI参数
    this.adjustAIForDifficulty(aiBehavior);
    
    this.enemyEntities.set(entityId, aiBehavior);
    
    // 创建敌人实体
    this.createEnemyEntity(entityId, type, position);
    
    console.log(`Created ${type} enemy (ID: ${entityId}) at [${position.x}, ${position.y}, ${position.z}]`);
    return entityId;
  }
  
  // 获取不同敌人类型的基础行为参数
  private getBaseBehaviorByType(type: EnemyType): {
    decisionInterval: number;
    patrolRadius: number;
    aggression: number;
    accuracy: number;
    reactionTime: number;
    health: number;
    speed: number;
    attackCooldown: number;
    evadeDistance: number;
  } {
    switch (type) {
      case EnemyType.GRUNT:
        return {
          decisionInterval: 1.0,
          patrolRadius: 5,
          aggression: 0.5,
          accuracy: 0.7,
          reactionTime: 0.3,
          health: 100,
          speed: 5,
          attackCooldown: 1.5,
          evadeDistance: 8
        };
      case EnemyType.SNIPER:
        return {
          decisionInterval: 2.0,
          patrolRadius: 3,
          aggression: 0.7,
          accuracy: 0.95,
          reactionTime: 0.5,
          health: 80,
          speed: 3,
          attackCooldown: 3.0,
          evadeDistance: 15
        };
      case EnemyType.TANK:
        return {
          decisionInterval: 1.5,
          patrolRadius: 4,
          aggression: 0.8,
          accuracy: 0.6,
          reactionTime: 0.2,
          health: 200,
          speed: 2,
          attackCooldown: 2.0,
          evadeDistance: 5
        };
      case EnemyType.ASSASSIN:
        return {
          decisionInterval: 0.8,
          patrolRadius: 6,
          aggression: 0.9,
          accuracy: 0.85,
          reactionTime: 0.1,
          health: 90,
          speed: 7,
          attackCooldown: 1.0,
          evadeDistance: 10
        };
      default:
        return {
          decisionInterval: 1.0,
          patrolRadius: 5,
          aggression: 0.5,
          accuracy: 0.7,
          reactionTime: 0.3,
          health: 100,
          speed: 5,
          attackCooldown: 1.5,
          evadeDistance: 8
        };
    }
  }
  
  // 根据难度调整AI参数
  private adjustAIForDifficulty(behavior: AIBehavior): void {
    // 难度系数(1级=1.0,5级=1.8)
    const difficultyFactor = 1.0 + (this.difficultyLevel - 1) * 0.2;
    
    // 提升攻击性
    behavior.aggression = Math.min(1.0, behavior.aggression * difficultyFactor);
    // 提升精度
    behavior.accuracy = Math.min(1.0, behavior.accuracy * (1.0 + (this.difficultyLevel - 1) * 0.1));
    // 降低反应时间
    behavior.reactionTime = Math.max(0.05, behavior.reactionTime / difficultyFactor);
    // 降低决策间隔(更频繁决策)
    behavior.decisionInterval = Math.max(0.2, behavior.decisionInterval / (1.0 + (this.difficultyLevel - 1) * 0.1));
    // 提升生命值
    behavior.health *= (1.0 + (this.difficultyLevel - 1) * 0.3);
    // 提升移动速度
    behavior.speed *= (1.0 + (this.difficultyLevel - 1) * 0.1);
    // 降低攻击冷却
    behavior.attackCooldown = Math.max(0.5, behavior.attackCooldown / (1.0 + (this.difficultyLevel - 1) * 0.15));
  }
  
  // 创建敌人实体(绑定物理/渲染属性)
  private createEnemyEntity(entityId: number, type: EnemyType, position: Vector3): void {
    const entity = EntityManager.getEntity(entityId);
    entity.setPosition(position);
    
    // 根据敌人类型设置不同的初始动画
    switch (type) {
      case EnemyType.GRUNT:
        entity.playAnimation('grunt_idle');
        break;
      case EnemyType.SNIPER:
        entity.playAnimation('sniper_idle');
        break;
      case EnemyType.TANK:
        entity.playAnimation('tank_idle');
        break;
      case EnemyType.ASSASSIN:
        entity.playAnimation('assassin_idle');
        break;
    }
  }
  
  // 更新AI系统
  update(deltaTime: number): void {
    if (this.enemyEntities.size === 0) return;
    
    this.enemyEntities.forEach((behavior: AIBehavior, entityId: number) => {
      // 跳过已死亡的敌人
      const entity = EntityManager.getEntity(entityId);
      if (entity.health <= 0) {
        this.enemyEntities.delete(entityId);
        return;
      }
      
      this.updateEnemyAI(behavior, deltaTime);
    });
  }
  
  // 更新单个敌人AI
  private updateEnemyAI(behavior: AIBehavior, deltaTime: number): void {
    const currentTime = Date.now() / 1000;
    
    // 检查是否需要做新决策(加入反应时间延迟)
    if (currentTime - behavior.lastDecisionTime >= behavior.decisionInterval) {
      // 模拟反应时间延迟
      setTimeout(() => {
        this.makeAIDecision(behavior);
      }, behavior.reactionTime * 1000);
      
      behavior.lastDecisionTime = currentTime;
    }
    
    // 执行当前行为
    this.executeAIBehavior(behavior, deltaTime);
  }
  
  // AI决策
  private makeAIDecision(behavior: AIBehavior): void {
    // 获取游戏状态
    const gameState = this.getGameStateForAI(behavior);
    
    // 优先使用强化学习模型决策
    if (this.reinforcementModel) {
      try {
        const action = this.reinforcementModel.predict(gameState);
        this.processAIAction(behavior, action);
      } catch (error) {
        console.error('RL model prediction failed:', error);
        // 回退到规则-based AI
        this.ruleBasedDecision(behavior);
      }
    } else {
      // 纯规则式AI决策
      this.ruleBasedDecision(behavior);
    }
  }
  
  // 获取AI决策所需的游戏状态
  private getGameStateForAI(behavior: AIBehavior): GameStateForAI {
    const entity = EntityManager.getEntity(behavior.entityId);
    let targetPosition: Vector3 | null = null;
    let targetHealth = 0;
    let distanceToTarget = 0;
    let nearbyEnemies = 0;
    let coverAvailable = false;
    
    // 获取目标玩家信息
    if (behavior.targetPlayerId) {
      const targetPlayer = EntityManager.getPlayers().find(p => p.playerId === behavior.targetPlayerId);
      if (targetPlayer) {
        targetPosition = targetPlayer.position;
        targetHealth = targetPlayer.health;
        distanceToTarget = EntityManager.calculateDistance(entity.position, targetPosition);
      }
    }
    
    // 检测附近敌人数量
    nearbyEnemies = Array.from(this.enemyEntities.values()).filter(
      b => b.entityId !== behavior.entityId && 
      EntityManager.calculateDistance(entity.position, EntityManager.getEntity(b.entityId).position) < 20
    ).length;
    
    // 检测是否有可用掩体
    if (targetPosition) {
      coverAvailable = !!EntityManager.findNearestCover(entity.position, targetPosition);
    }
    
    return {
      selfPosition: entity.position,
      targetPosition: targetPosition,
      distanceToTarget: distanceToTarget,
      selfHealth: entity.health,
      targetHealth: targetHealth,
      nearbyEnemies: nearbyEnemies,
      coverAvailable: coverAvailable,
      ammoCount: 30, // 模拟弹药数量
      isReloading: behavior.state === AIState.RELOADING
    };
  }
  
  // 处理强化学习模型输出的行为
  private processAIAction(behavior: AIBehavior, action: number): void {
    // action映射:0=巡逻,1=追击,2=攻击,3=躲避,4=换弹
    switch (action) {
      case 0:
        behavior.state = AIState.PATROLLING;
        behavior.targetPlayerId = null;
        break;
      case 1:
        behavior.state = AIState.CHASING;
        break;
      case 2:
        behavior.state = AIState.ATTACKING;
        break;
      case 3:
        behavior.state = AIState.EVADING;
        break;
      case 4:
        behavior.state = AIState.RELOADING;
        break;
    }
  }
  
  // 规则-based决策
  private ruleBasedDecision(behavior: AIBehavior): void {
    const players = this.getNearbyPlayers(behavior);
    const entity = EntityManager.getEntity(behavior.entityId);
    
    // 低血量时优先躲避
    if (entity.health < 30 && behavior.aggression < 0.8) {
      behavior.state = AIState.EVADING;
      return;
    }
    
    if (players.length === 0) {
      // 没有玩家在附近,继续巡逻
      if (behavior.state !== AIState.PATROLLING) {
        behavior.state = AIState.PATROLLING;
        behavior.targetPlayerId = null;
      }
    } else {
      // 有玩家在附近,根据距离和敌人类型决定行为
      const nearestPlayer = players[0];
      const distance = this.calculateDistance(behavior, nearestPlayer);
      
      // 狙击手远距离就攻击,其他类型近距离攻击
      if (behavior.type === EnemyType.SNIPER) {
        if (distance < 50 && distance > 15) {
          // 狙击手最佳射程
          behavior.state = AIState.ATTACKING;
          behavior.targetPlayerId = nearestPlayer.playerId;
        } else if (distance <= 15) {
          // 近距离时躲避
          behavior.state = AIState.EVADING;
          behavior.targetPlayerId = nearestPlayer.playerId;
        } else {
          // 超远距离时追击
          behavior.state = AIState.CHASING;
          behavior.targetPlayerId = nearestPlayer.playerId;
        }
      } else {
        // 普通敌人的距离判断
        if (distance < behavior.evadeDistance * 0.5) {
          // 极近距离,攻击
          behavior.state = AIState.ATTACKING;
          behavior.targetPlayerId = nearestPlayer.playerId;
        } else if (distance < behavior.evadeDistance * 2) {
          // 中距离,追击
          behavior.state = AIState.CHASING;
          behavior.targetPlayerId = nearestPlayer.playerId;
        } else {
          // 远距离,巡逻/搜索
          behavior.state = AIState.SEARCHING;
          behavior.targetPlayerId = null;
        }
      }
    }
  }
  
  // 获取附近的玩家列表(按距离排序)
  private getNearbyPlayers(behavior: AIBehavior): PlayerInfo[] {
    const entity = EntityManager.getEntity(behavior.entityId);
    const players = EntityManager.getPlayers();
    
    // 过滤可见玩家并按距离排序
    return players
      .filter(player => player.isVisible)
      .sort((a, b) => {
        const distA = EntityManager.calculateDistance(entity.position, a.position);
        const distB = EntityManager.calculateDistance(entity.position, b.position);
        return distA - distB;
      });
  }
  
  // 计算敌人到玩家的距离
  private calculateDistance(behavior: AIBehavior, player: PlayerInfo): number {
    const entity = EntityManager.getEntity(behavior.entityId);
    return EntityManager.calculateDistance(entity.position, player.position);
  }
  
  // 执行AI行为
  private executeAIBehavior(behavior: AIBehavior, deltaTime: number): void {
    switch (behavior.state) {
      case AIState.PATROLLING:
        this.executePatrol(behavior, deltaTime);
        break;
      case AIState.CHASING:
        this.executeChase(behavior, deltaTime);
        break;
      case AIState.ATTACKING:
        this.executeAttack(behavior, deltaTime);
        break;
      case AIState.EVADING:
        this.executeEvade(behavior, deltaTime);
        break;
      case AIState.SEARCHING:
        this.executeSearch(behavior, deltaTime);
        break;
      case AIState.RELOADING:
        this.executeReload(behavior, deltaTime);
        break;
    }
  }
  
  // ======================== 完善巡逻行为 ========================
  private executePatrol(behavior: AIBehavior, deltaTime: number): void {
    if (behavior.patrolPoints.length === 0) return;
    
    const entity = EntityManager.getEntity(behavior.entityId);
    const currentPoint = behavior.patrolPoints[behavior.currentPatrolIndex];
    const distanceToPoint = EntityManager.calculateDistance(entity.position, currentPoint);
    
    // 播放巡逻动画
    entity.playAnimation(`${behavior.type}_patrol`);
    
    // 如果到达当前巡逻点,切换到下一个
    if (distanceToPoint < 1.0) {
      // 随机调整巡逻点(增加随机性)
      behavior.currentPatrolIndex = (behavior.currentPatrolIndex + 1) % behavior.patrolPoints.length;
      
      // 偶尔随机重置巡逻路径(模拟更自然的巡逻)
      if (Math.random() < 0.1) {
        behavior.patrolPoints = this.generatePatrolPoints(entity.position, behavior.patrolPoints.length > 0 ? 5 : 3);
        behavior.currentPatrolIndex = 0;
      }
      
      // 到达巡逻点后短暂停留
      setTimeout(() => {
        entity.playAnimation(`${behavior.type}_idle`);
      }, 500);
      return;
    }
    
    // 计算移动方向并移动到巡逻点
    const direction: Vector3 = {
      x: (currentPoint.x - entity.position.x) / distanceToPoint,
      y: (currentPoint.y - entity.position.y) / distanceToPoint,
      z: (currentPoint.z - entity.position.z) / distanceToPoint
    };
    
    // 朝向目标点
    entity.setRotation({
      x: 0,
      y: Math.atan2(direction.x, direction.z),
      z: 0
    });
    
    // 移动到目标点
    entity.move(direction, behavior.speed, deltaTime);
  }
  
  // 生成巡逻点(围绕初始位置的随机点)
  private generatePatrolPoints(center: Vector3, radius: number): Vector3[] {
    const points: Vector3[] = [];
    const pointCount = 3 + Math.floor(Math.random() * 3); // 3-5个巡逻点
    
    for (let i = 0; i < pointCount; i++) {
      // 生成圆形分布的随机点
      const angle = (i / pointCount) * Math.PI * 2 + Math.random() * 0.5;
      const randomRadius = radius * (0.5 + Math.random() * 0.5);
      
      points.push({
        x: center.x + Math.cos(angle) * randomRadius,
        y: center.y, // Y轴保持不变(平面巡逻)
        z: center.z + Math.sin(angle) * randomRadius
      });
    }
    
    return points;
  }
  
  // 执行追击行为
  private executeChase(behavior: AIBehavior, deltaTime: number): void {
    if (!behavior.targetPlayerId) {
      behavior.state = AIState.PATROLLING;
      return;
    }
    
    const entity = EntityManager.getEntity(behavior.entityId);
    const targetPlayer = EntityManager.getPlayers().find(p => p.playerId === behavior.targetPlayerId);
    
    if (!targetPlayer || !targetPlayer.isVisible) {
      // 丢失目标,转为搜索状态
      behavior.state = AIState.SEARCHING;
      return;
    }
    
    // 播放追击动画
    entity.playAnimation(`${behavior.type}_chase`);
    
    const distanceToTarget = EntityManager.calculateDistance(entity.position, targetPlayer.position);
    
    // 计算追击方向
    const direction: Vector3 = {
      x: (targetPlayer.position.x - entity.position.x) / distanceToTarget,
      y: (targetPlayer.position.y - entity.position.y) / distanceToTarget,
      z: (targetPlayer.position.z - entity.position.z) / distanceToTarget
    };
    
    // 朝玩家转向
    entity.setRotation({
      x: 0,
      y: Math.atan2(direction.x, direction.z),
      z: 0
    });
    
    // 刺客类型加速追击
    const chaseSpeed = behavior.type === EnemyType.ASSASSIN 
      ? behavior.speed * 1.3 
      : behavior.speed;
    
    // 移动追击(距离越近速度越慢,模拟瞄准)
    const moveSpeed = distanceToTarget < 10 ? chaseSpeed * 0.7 : chaseSpeed;
    entity.move(direction, moveSpeed, deltaTime);
  }
  
  // 执行攻击行为
  private executeAttack(behavior: AIBehavior, deltaTime: number): void {
    if (!behavior.targetPlayerId) {
      behavior.state = AIState.PATROLLING;
      return;
    }
    
    const currentTime = Date.now() / 1000;
    const entity = EntityManager.getEntity(behavior.entityId);
    const targetPlayer = EntityManager.getPlayers().find(p => p.playerId === behavior.targetPlayerId);
    
    if (!targetPlayer || !targetPlayer.isVisible) {
      behavior.state = AIState.SEARCHING;
      return;
    }
    
    const distanceToTarget = EntityManager.calculateDistance(entity.position, targetPlayer.position);
    const maxAttackDistance = behavior.type === EnemyType.SNIPER ? 50 : 15;
    
    // 超出攻击距离,转为追击
    if (distanceToTarget > maxAttackDistance) {
      behavior.state = AIState.CHASING;
      return;
    }
    
    // 播放攻击动画
    entity.playAnimation(`${behavior.type}_attack`);
    
    // 攻击冷却检查
    if (currentTime - behavior.lastAttackTime < behavior.attackCooldown) {
      return;
    }
    
    // 执行攻击
    const hitSuccess = entity.attack(behavior.targetPlayerId, behavior.accuracy);
    
    // 记录攻击时间
    behavior.lastAttackTime = currentTime;
    
    // 攻击命中反馈
    if (hitSuccess) {
      console.log(`Enemy ${behavior.entityId} hit player ${behavior.targetPlayerId}`);
      // 提升攻击性
      behavior.aggression = Math.min(1.0, behavior.aggression + 0.1);
    } else {
      // 攻击落空,降低精度(模拟紧张)
      behavior.accuracy = Math.max(0.1, behavior.accuracy - 0.05);
    }
  }
  
  // 执行躲避行为
  private executeEvade(behavior: AIBehavior, deltaTime: number): void {
    const entity = EntityManager.getEntity(behavior.entityId);
    let evadeTarget: Vector3 | null = null;
    
    // 播放躲避动画
    entity.playAnimation(`${behavior.type}_evade`);
    
    // 优先找掩体
    if (behavior.targetPlayerId) {
      const targetPlayer = EntityManager.getPlayers().find(p => p.playerId === behavior.targetPlayerId);
      if (targetPlayer) {
        evadeTarget = EntityManager.findNearestCover(entity.position, targetPlayer.position);
      }
    }
    
    // 没有掩体则向随机方向躲避
    if (!evadeTarget) {
      evadeTarget = {
        x: entity.position.x + (Math.random() - 0.5) * 10,
        y: entity.position.y,
        z: entity.position.z + (Math.random() - 0.5) * 10
      };
    }
    
    const distanceToEvade = EntityManager.calculateDistance(entity.position, evadeTarget);
    
    // 到达躲避点后恢复巡逻/搜索
    if (distanceToEvade < 2.0) {
      behavior.state = entity.health < 50 ? AIState.PATROLLING : AIState.SEARCHING;
      return;
    }
    
    // 计算躲避方向
    const direction: Vector3 = {
      x: (evadeTarget.x - entity.position.x) / distanceToEvade,
      y: (evadeTarget.y - entity.position.y) / distanceToEvade,
      z: (evadeTarget.z - entity.position.z) / distanceToEvade
    };
    
    // 躲避时加速
    entity.move(direction, behavior.speed * 1.5, deltaTime);
  }
  
  // 执行搜索行为
  private executeSearch(behavior: AIBehavior, deltaTime: number): void {
    const entity = EntityManager.getEntity(behavior.entityId);
    entity.playAnimation(`${behavior.type}_search`);
    
    // 随机转向和移动(模拟搜索)
    if (Math.random() < 0.1) {
      entity.setRotation({
        x: 0,
        y: Math.random() * Math.PI * 2,
        z: 0
      });
    }
    
    // 缓慢移动搜索
    const randomDir: Vector3 = {
      x: Math.random() - 0.5,
      y: 0,
      z: Math.random() - 0.5
    };
    entity.move(randomDir, behavior.speed * 0.5, deltaTime);
    
    // 搜索一段时间后恢复巡逻
    const searchDuration = 10; // 搜索10秒
    if (Date.now() / 1000 - behavior.lastDecisionTime > searchDuration) {
      behavior.state = AIState.PATROLLING;
    }
  }
  
  // 执行换弹行为
  private executeReload(behavior: AIBehavior, deltaTime: number): void {
    const entity = EntityManager.getEntity(behavior.entityId);
    entity.playAnimation(`${behavior.type}_reload`);
    
    // 换弹持续2秒
    const reloadDuration = 2.0;
    if (Date.now() / 1000 - behavior.lastDecisionTime > reloadDuration) {
      behavior.state = AIState.PATROLLING;
      // 换弹完成后恢复精度
      behavior.accuracy = this.getBaseBehaviorByType(behavior.type).accuracy * 
        (1.0 + (this.difficultyLevel - 1) * 0.1);
    }
  }
  
  // 移除敌人AI
  removeEnemy(entityId: number): void {
    this.enemyEntities.delete(entityId);
    console.log(`Removed enemy AI (ID: ${entityId})`);
  }
  
  // 清理所有AI
  cleanup(): void {
    this.enemyEntities.clear();
    this.nlpEngine = null;
    this.reinforcementModel = null;
    console.log('AI system cleaned up');
  }
}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐