HarmonyOS游戏开发实战:基于5.0版本构建分布式太空射击游戏
摘要:HarmonyOS 5.0为游戏开发带来革命性突破,支持分布式渲染、跨设备协同和AI原生引擎。本文详细介绍了基于HarmonyOS 5.0开发分布式太空射击游戏的完整流程,包括:1) 开发环境配置与项目初始化;2) 方舟游戏引擎架构与分布式状态同步技术实现;3) 游戏ECS架构设计与核心系统实现;4) 跨设备输入系统整合;5) AI对手系统开发。通过实战项目演示了如何利用HarmonyOS
引言: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游戏开发版安装:
-
访问华为开发者联盟游戏中心(https://developer.huawei.com/consumer/cn/games/),下载DevEco Studio 5.0.4 Game Development Edition
-
运行安装程序,选择游戏开发专用组件:
-
HarmonyOS Game SDK 5.0.4(API Version 16)
-
Ark Game Engine 2.0(新增分布式渲染支持)
-
3D模型导入工具链
-
物理引擎插件(Bullet Physics 3.24)
-
音频处理引擎(OpenAL Soft 1.23)
-
AI游戏对手训练工具包
-
-
安装路径必须为纯英文,建议:
D:\DevEcoStudio\GameDev -
安装完成后,首次启动选择"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游戏项目:
-
点击"File" → "New" → "Create Game Project"
-
选择"3D Space Shooter"模板
-
配置项目信息:
-
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
-
-
点击"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');
}
}
更多推荐
所有评论(0)