mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-24 04:06:48 +08:00
- 将标题从"架构模式最佳实践"改为"架构设计模式指南" - 添加全面的架构设计模式介绍和概述 - 新增MVC模式详细说明,包括概念、GFramework实现示例和最佳实践 - 新增MVVM模式详细说明,包括概念、GFramework实现示例和最佳实践 - 新增命令模式详细说明,包括概念、实现示例和撤销功能支持 - 新增查询模式详细说明,包括CQRS概念和复杂查询示例 - 新增事件驱动模式详细说明,包括事件定义和监听实现 - 新增依赖注入模式详细说明,包括构造函数注入示例 - 新增服务定位器模式详细说明,包括与依赖注入对比 - 新增对象池模式详细说明,包括通用对象池实现 - 新增状态模式详细说明,包括异步状态和状态机系统 - 补充模式选择与组合建议,针对小型、中型、大型项目提供不同方案 - 更新代码示例中的泛型语法格式,统一使用尖括号表示法
1642 lines
47 KiB
Markdown
1642 lines
47 KiB
Markdown
---
|
|
title: 大型项目组织
|
|
description: 学习如何使用 GFramework 组织和管理大型游戏项目
|
|
---
|
|
|
|
# 大型项目组织
|
|
|
|
## 学习目标
|
|
|
|
完成本教程后,你将能够:
|
|
|
|
- 理解大型游戏项目的组织原则
|
|
- 设计清晰的项目结构和模块划分
|
|
- 实现分层架构和依赖管理
|
|
- 使用模块化设计分离功能
|
|
- 建立代码组织规范和团队协作流程
|
|
- 应用最佳实践提高项目可维护性
|
|
|
|
## 前置条件
|
|
|
|
- 已安装 GFramework.Core 和 GFramework.Game NuGet 包
|
|
- 了解 C# 基础语法和面向对象编程
|
|
- 阅读过[快速开始](/zh-CN/getting-started/quick-start)
|
|
- 了解[架构组件](/zh-CN/core/architecture)和[模块系统](/zh-CN/core/architecture#模块系统)
|
|
|
|
## 步骤 1: 项目结构设计
|
|
|
|
首先,让我们设计一个清晰的项目结构,将代码按功能和层次组织。
|
|
|
|
### 1.1 推荐的目录结构
|
|
|
|
```
|
|
MyLargeGame/
|
|
├── src/
|
|
│ ├── MyGame.Core/ # 核心层
|
|
│ │ ├── Architecture/ # 架构定义
|
|
│ │ │ ├── GameArchitecture.cs
|
|
│ │ │ └── GameContext.cs
|
|
│ │ ├── Constants/ # 常量定义
|
|
│ │ │ ├── GameConstants.cs
|
|
│ │ │ └── LayerConstants.cs
|
|
│ │ └── Extensions/ # 扩展方法
|
|
│ │ └── GameExtensions.cs
|
|
│ │
|
|
│ ├── MyGame.Domain/ # 领域层
|
|
│ │ ├── Models/ # 数据模型
|
|
│ │ │ ├── Player/
|
|
│ │ │ │ ├── PlayerModel.cs
|
|
│ │ │ │ └── PlayerStatsModel.cs
|
|
│ │ │ ├── Inventory/
|
|
│ │ │ │ ├── InventoryModel.cs
|
|
│ │ │ │ └── ItemModel.cs
|
|
│ │ │ └── Combat/
|
|
│ │ │ ├── CombatModel.cs
|
|
│ │ │ └── SkillModel.cs
|
|
│ │ ├── Events/ # 领域事件
|
|
│ │ │ ├── Player/
|
|
│ │ │ │ ├── PlayerLevelUpEvent.cs
|
|
│ │ │ │ └── PlayerHealthChangedEvent.cs
|
|
│ │ │ └── Combat/
|
|
│ │ │ └── DamageDealtEvent.cs
|
|
│ │ └── Enums/ # 枚举定义
|
|
│ │ ├── ItemType.cs
|
|
│ │ └── SkillType.cs
|
|
│ │
|
|
│ ├── MyGame.Application/ # 应用层
|
|
│ │ ├── Systems/ # 业务系统
|
|
│ │ │ ├── Player/
|
|
│ │ │ │ ├── PlayerSystem.cs
|
|
│ │ │ │ └── PlayerLevelSystem.cs
|
|
│ │ │ ├── Inventory/
|
|
│ │ │ │ └── InventorySystem.cs
|
|
│ │ │ └── Combat/
|
|
│ │ │ ├── CombatSystem.cs
|
|
│ │ │ └── SkillSystem.cs
|
|
│ │ ├── Commands/ # 命令
|
|
│ │ │ ├── Player/
|
|
│ │ │ │ └── MovePlayerCommand.cs
|
|
│ │ │ └── Inventory/
|
|
│ │ │ └── AddItemCommand.cs
|
|
│ │ ├── Queries/ # 查询
|
|
│ │ │ ├── Player/
|
|
│ │ │ │ └── GetPlayerStatsQuery.cs
|
|
│ │ │ └── Inventory/
|
|
│ │ │ └── GetItemsQuery.cs
|
|
│ │ └── Utilities/ # 工具类
|
|
│ │ ├── MathUtility.cs
|
|
│ │ └── PathfindingUtility.cs
|
|
│ │
|
|
│ ├── MyGame.Infrastructure/ # 基础设施层
|
|
│ │ ├── Data/ # 数据访问
|
|
│ │ │ ├── Repositories/
|
|
│ │ │ │ ├── PlayerRepository.cs
|
|
│ │ │ │ └── SaveRepository.cs
|
|
│ │ │ └── Serializers/
|
|
│ │ │ └── JsonGameSerializer.cs
|
|
│ │ ├── Resources/ # 资源管理
|
|
│ │ │ ├── AssetLoader.cs
|
|
│ │ │ └── ResourceCache.cs
|
|
│ │ └── Services/ # 外部服务
|
|
│ │ ├── AudioService.cs
|
|
│ │ └── NetworkService.cs
|
|
│ │
|
|
│ ├── MyGame.Presentation/ # 表现层
|
|
│ │ ├── Controllers/ # 控制器
|
|
│ │ │ ├── Player/
|
|
│ │ │ │ └── PlayerController.cs
|
|
│ │ │ └── UI/
|
|
│ │ │ └── UIController.cs
|
|
│ │ ├── Views/ # 视图
|
|
│ │ │ ├── HUD/
|
|
│ │ │ │ ├── HealthBarView.cs
|
|
│ │ │ │ └── MiniMapView.cs
|
|
│ │ │ └── Menus/
|
|
│ │ │ ├── MainMenuView.cs
|
|
│ │ │ └── InventoryView.cs
|
|
│ │ └── ViewModels/ # 视图模型
|
|
│ │ └── InventoryViewModel.cs
|
|
│ │
|
|
│ └── MyGame.Modules/ # 功能模块
|
|
│ ├── PlayerModule/
|
|
│ │ └── PlayerModule.cs
|
|
│ ├── CombatModule/
|
|
│ │ └── CombatModule.cs
|
|
│ ├── InventoryModule/
|
|
│ │ └── InventoryModule.cs
|
|
│ └── QuestModule/
|
|
│ └── QuestModule.cs
|
|
│
|
|
├── tests/
|
|
│ ├── MyGame.Core.Tests/
|
|
│ ├── MyGame.Domain.Tests/
|
|
│ └── MyGame.Application.Tests/
|
|
│
|
|
└── docs/
|
|
├── architecture.md
|
|
├── coding-standards.md
|
|
└── api/
|
|
```
|
|
|
|
**结构说明**:
|
|
|
|
- **Core**: 核心架构和基础设施,不依赖其他层
|
|
- **Domain**: 领域模型和业务规则,纯业务逻辑
|
|
- **Application**: 应用服务和用例,协调领域对象
|
|
- **Infrastructure**: 技术实现,如数据访问、资源加载
|
|
- **Presentation**: 表现层,处理用户交互和显示
|
|
- **Modules**: 功能模块,封装完整的功能单元
|
|
|
|
### 1.2 创建核心架构
|
|
|
|
```csharp
|
|
using GFramework.Core.architecture;
|
|
using GFramework.Core.Abstractions.architecture;
|
|
|
|
namespace MyGame.Core.Architecture
|
|
{
|
|
/// <summary>
|
|
/// 游戏主架构
|
|
/// </summary>
|
|
public class GameArchitecture : Architecture
|
|
{
|
|
public static IArchitecture Interface { get; private set; }
|
|
|
|
protected override void Init()
|
|
{
|
|
Interface = this;
|
|
|
|
Console.WriteLine("初始化游戏架构...");
|
|
}
|
|
|
|
protected override void InstallModules()
|
|
{
|
|
// 模块将在步骤 3 中安装
|
|
Console.WriteLine("安装功能模块...");
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## 步骤 2: 架构分层
|
|
|
|
实现清晰的分层架构,确保各层职责明确,依赖关系单向。
|
|
|
|
### 2.1 领域层 - 玩家模型
|
|
|
|
```csharp
|
|
using GFramework.Core.model;
|
|
using GFramework.Core.property;
|
|
|
|
namespace MyGame.Domain.Models.Player
|
|
{
|
|
/// <summary>
|
|
/// 玩家数据模型
|
|
/// </summary>
|
|
public class PlayerModel : AbstractModel
|
|
{
|
|
// 基础属性
|
|
public BindableProperty<string> Name { get; } = new("Player");
|
|
public BindableProperty<int> Level { get; } = new(1);
|
|
public BindableProperty<int> Experience { get; } = new(0);
|
|
|
|
// 战斗属性
|
|
public BindableProperty<int> Health { get; } = new(100);
|
|
public BindableProperty<int> MaxHealth { get; } = new(100);
|
|
public BindableProperty<int> Mana { get; } = new(50);
|
|
public BindableProperty<int> MaxMana { get; } = new(50);
|
|
|
|
// 位置信息
|
|
public BindableProperty<float> PositionX { get; } = new(0f);
|
|
public BindableProperty<float> PositionY { get; } = new(0f);
|
|
public BindableProperty<float> PositionZ { get; } = new(0f);
|
|
|
|
protected override void OnInit()
|
|
{
|
|
Console.WriteLine($"玩家模型初始化: {Name.Value}");
|
|
|
|
// 监听等级变化
|
|
Level.Register(OnLevelChanged);
|
|
}
|
|
|
|
private void OnLevelChanged(int newLevel)
|
|
{
|
|
Console.WriteLine($"玩家升级到 {newLevel} 级");
|
|
|
|
// 升级时恢复生命值和法力值
|
|
Health.Value = MaxHealth.Value;
|
|
Mana.Value = MaxMana.Value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 受到伤害
|
|
/// </summary>
|
|
public void TakeDamage(int damage)
|
|
{
|
|
Health.Value = Math.Max(0, Health.Value - damage);
|
|
|
|
if (Health.Value == 0)
|
|
{
|
|
Console.WriteLine("玩家死亡");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获得经验
|
|
/// </summary>
|
|
public void GainExperience(int exp)
|
|
{
|
|
Experience.Value += exp;
|
|
|
|
// 检查是否升级
|
|
int expNeeded = GetExperienceForNextLevel();
|
|
if (Experience.Value >= expNeeded)
|
|
{
|
|
LevelUp();
|
|
}
|
|
}
|
|
|
|
private void LevelUp()
|
|
{
|
|
Level.Value++;
|
|
Experience.Value = 0;
|
|
|
|
// 提升属性
|
|
MaxHealth.Value += 10;
|
|
MaxMana.Value += 5;
|
|
}
|
|
|
|
private int GetExperienceForNextLevel()
|
|
{
|
|
return Level.Value * 100;
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2.2 领域层 - 领域事件
|
|
|
|
```csharp
|
|
using GFramework.Core.Abstractions.events;
|
|
|
|
namespace MyGame.Domain.Events.Player
|
|
{
|
|
/// <summary>
|
|
/// 玩家升级事件
|
|
/// </summary>
|
|
public record PlayerLevelUpEvent(int NewLevel, int OldLevel) : IEvent;
|
|
|
|
/// <summary>
|
|
/// 玩家生命值变化事件
|
|
/// </summary>
|
|
public record PlayerHealthChangedEvent(int NewHealth, int OldHealth, int MaxHealth) : IEvent;
|
|
|
|
/// <summary>
|
|
/// 玩家死亡事件
|
|
/// </summary>
|
|
public record PlayerDeathEvent(string Reason) : IEvent;
|
|
|
|
/// <summary>
|
|
/// 玩家位置变化事件
|
|
/// </summary>
|
|
public record PlayerPositionChangedEvent(float X, float Y, float Z) : IEvent;
|
|
}
|
|
```
|
|
|
|
### 2.3 应用层 - 玩家系统
|
|
|
|
```csharp
|
|
using GFramework.Core.system;
|
|
using GFramework.Core.Abstractions.events;
|
|
using MyGame.Domain.Models.Player;
|
|
using MyGame.Domain.Events.Player;
|
|
|
|
namespace MyGame.Application.Systems.Player
|
|
{
|
|
/// <summary>
|
|
/// 玩家管理系统
|
|
/// </summary>
|
|
public class PlayerSystem : AbstractSystem
|
|
{
|
|
private PlayerModel _playerModel;
|
|
private IEventBus _eventBus;
|
|
|
|
protected override void OnInit()
|
|
{
|
|
// 获取依赖
|
|
_playerModel = this.GetModel<PlayerModel>();
|
|
_eventBus = this.GetService<IEventBus>();
|
|
|
|
// 监听玩家属性变化
|
|
_playerModel.Level.Register(OnLevelChanged);
|
|
_playerModel.Health.Register(OnHealthChanged);
|
|
|
|
Console.WriteLine("玩家系统初始化完成");
|
|
}
|
|
|
|
private void OnLevelChanged(int newLevel)
|
|
{
|
|
// 发布升级事件
|
|
_eventBus.Publish(new PlayerLevelUpEvent(newLevel, newLevel - 1));
|
|
}
|
|
|
|
private void OnHealthChanged(int newHealth)
|
|
{
|
|
// 发布生命值变化事件
|
|
_eventBus.Publish(new PlayerHealthChangedEvent(
|
|
newHealth,
|
|
_playerModel.Health.Value,
|
|
_playerModel.MaxHealth.Value
|
|
));
|
|
|
|
// 检查死亡
|
|
if (newHealth == 0)
|
|
{
|
|
_eventBus.Publish(new PlayerDeathEvent("生命值耗尽"));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 移动玩家
|
|
/// </summary>
|
|
public void MovePlayer(float x, float y, float z)
|
|
{
|
|
_playerModel.PositionX.Value = x;
|
|
_playerModel.PositionY.Value = y;
|
|
_playerModel.PositionZ.Value = z;
|
|
|
|
_eventBus.Publish(new PlayerPositionChangedEvent(x, y, z));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 治疗玩家
|
|
/// </summary>
|
|
public void HealPlayer(int amount)
|
|
{
|
|
int newHealth = Math.Min(
|
|
_playerModel.Health.Value + amount,
|
|
_playerModel.MaxHealth.Value
|
|
);
|
|
|
|
_playerModel.Health.Value = newHealth;
|
|
Console.WriteLine($"玩家恢复 {amount} 点生命值");
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2.4 应用层 - 命令模式
|
|
|
|
```csharp
|
|
using GFramework.Core.command;
|
|
using MyGame.Domain.Models.Player;
|
|
|
|
namespace MyGame.Application.Commands.Player
|
|
{
|
|
/// <summary>
|
|
/// 移动玩家命令
|
|
/// </summary>
|
|
public class MovePlayerCommand : AbstractCommand
|
|
{
|
|
private readonly float _x;
|
|
private readonly float _y;
|
|
private readonly float _z;
|
|
private float _oldX;
|
|
private float _oldY;
|
|
private float _oldZ;
|
|
|
|
public MovePlayerCommand(float x, float y, float z)
|
|
{
|
|
_x = x;
|
|
_y = y;
|
|
_z = z;
|
|
}
|
|
|
|
protected override void OnExecute()
|
|
{
|
|
var playerModel = this.GetModel<PlayerModel>();
|
|
|
|
// 保存旧位置(用于撤销)
|
|
_oldX = playerModel.PositionX.Value;
|
|
_oldY = playerModel.PositionY.Value;
|
|
_oldZ = playerModel.PositionZ.Value;
|
|
|
|
// 移动到新位置
|
|
playerModel.PositionX.Value = _x;
|
|
playerModel.PositionY.Value = _y;
|
|
playerModel.PositionZ.Value = _z;
|
|
|
|
Console.WriteLine($"玩家移动到 ({_x}, {_y}, {_z})");
|
|
}
|
|
|
|
protected override void OnUndo()
|
|
{
|
|
var playerModel = this.GetModel<PlayerModel>();
|
|
|
|
// 恢复旧位置
|
|
playerModel.PositionX.Value = _oldX;
|
|
playerModel.PositionY.Value = _oldY;
|
|
playerModel.PositionZ.Value = _oldZ;
|
|
|
|
Console.WriteLine($"撤销移动,返回 ({_oldX}, {_oldY}, {_oldZ})");
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## 步骤 3: 模块化设计
|
|
|
|
使用 IArchitectureModule 将相关功能封装成独立模块。
|
|
|
|
### 3.1 创建玩家模块
|
|
|
|
```csharp
|
|
using GFramework.Core.Abstractions.architecture;
|
|
using MyGame.Domain.Models.Player;
|
|
using MyGame.Application.Systems.Player;
|
|
|
|
namespace MyGame.Modules.PlayerModule
|
|
{
|
|
/// <summary>
|
|
/// 玩家功能模块
|
|
/// </summary>
|
|
public class PlayerModule : IArchitectureModule
|
|
{
|
|
public string Name => "PlayerModule";
|
|
public string Version => "1.0.0";
|
|
|
|
public void Install(IArchitecture architecture)
|
|
{
|
|
Console.WriteLine($"安装模块: {Name} v{Version}");
|
|
|
|
// 注册玩家相关的 Model
|
|
architecture.RegisterModel(new PlayerModel());
|
|
|
|
// 注册玩家相关的 System
|
|
architecture.RegisterSystem(new PlayerSystem());
|
|
architecture.RegisterSystem(new PlayerLevelSystem());
|
|
|
|
Console.WriteLine($"模块 {Name} 安装完成");
|
|
}
|
|
|
|
public void Uninstall(IArchitecture architecture)
|
|
{
|
|
Console.WriteLine($"卸载模块: {Name}");
|
|
|
|
// 清理资源
|
|
// 注意: GFramework 会自动处理组件的清理
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 玩家等级系统
|
|
/// </summary>
|
|
public class PlayerLevelSystem : AbstractSystem
|
|
{
|
|
protected override void OnInit()
|
|
{
|
|
var playerModel = this.GetModel<PlayerModel>();
|
|
|
|
// 监听升级事件
|
|
playerModel.Level.Register(level =>
|
|
{
|
|
Console.WriteLine($"等级系统: 玩家达到 {level} 级");
|
|
CalculateStats(level);
|
|
});
|
|
}
|
|
|
|
private void CalculateStats(int level)
|
|
{
|
|
// 根据等级计算属性
|
|
Console.WriteLine($"重新计算 {level} 级的属性");
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3.2 创建战斗模块
|
|
|
|
```csharp
|
|
using GFramework.Core.Abstractions.architecture;
|
|
using GFramework.Core.system;
|
|
using MyGame.Domain.Models.Player;
|
|
|
|
namespace MyGame.Modules.CombatModule
|
|
{
|
|
/// <summary>
|
|
/// 战斗功能模块
|
|
/// </summary>
|
|
public class CombatModule : IArchitectureModule
|
|
{
|
|
public string Name => "CombatModule";
|
|
public string Version => "1.0.0";
|
|
|
|
public void Install(IArchitecture architecture)
|
|
{
|
|
Console.WriteLine($"安装模块: {Name} v{Version}");
|
|
|
|
// 注册战斗系统
|
|
architecture.RegisterSystem(new CombatSystem());
|
|
architecture.RegisterSystem(new SkillSystem());
|
|
architecture.RegisterSystem(new DamageCalculationSystem());
|
|
|
|
Console.WriteLine($"模块 {Name} 安装完成");
|
|
}
|
|
|
|
public void Uninstall(IArchitecture architecture)
|
|
{
|
|
Console.WriteLine($"卸载模块: {Name}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 战斗系统
|
|
/// </summary>
|
|
public class CombatSystem : AbstractSystem
|
|
{
|
|
private PlayerModel _playerModel;
|
|
|
|
protected override void OnInit()
|
|
{
|
|
_playerModel = this.GetModel<PlayerModel>();
|
|
Console.WriteLine("战斗系统初始化完成");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 攻击目标
|
|
/// </summary>
|
|
public void Attack(string targetName, int damage)
|
|
{
|
|
Console.WriteLine($"玩家攻击 {targetName},造成 {damage} 点伤害");
|
|
|
|
// 获取伤害计算系统
|
|
var damageSystem = this.GetSystem<DamageCalculationSystem>();
|
|
int finalDamage = damageSystem.CalculateDamage(damage);
|
|
|
|
Console.WriteLine($"最终伤害: {finalDamage}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 技能系统
|
|
/// </summary>
|
|
public class SkillSystem : AbstractSystem
|
|
{
|
|
private readonly Dictionary<string, float> _cooldowns = new();
|
|
|
|
protected override void OnInit()
|
|
{
|
|
Console.WriteLine("技能系统初始化完成");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 使用技能
|
|
/// </summary>
|
|
public bool UseSkill(string skillName, int manaCost)
|
|
{
|
|
var playerModel = this.GetModel<PlayerModel>();
|
|
|
|
// 检查法力值
|
|
if (playerModel.Mana.Value < manaCost)
|
|
{
|
|
Console.WriteLine($"法力值不足,无法使用 {skillName}");
|
|
return false;
|
|
}
|
|
|
|
// 检查冷却
|
|
if (_cooldowns.ContainsKey(skillName))
|
|
{
|
|
Console.WriteLine($"技能 {skillName} 冷却中");
|
|
return false;
|
|
}
|
|
|
|
// 消耗法力值
|
|
playerModel.Mana.Value -= manaCost;
|
|
|
|
Console.WriteLine($"使用技能: {skillName}");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 伤害计算系统
|
|
/// </summary>
|
|
public class DamageCalculationSystem : AbstractSystem
|
|
{
|
|
protected override void OnInit()
|
|
{
|
|
Console.WriteLine("伤害计算系统初始化完成");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 计算最终伤害
|
|
/// </summary>
|
|
public int CalculateDamage(int baseDamage)
|
|
{
|
|
var playerModel = this.GetModel<PlayerModel>();
|
|
|
|
// 根据等级增加伤害
|
|
float levelBonus = 1.0f + (playerModel.Level.Value * 0.1f);
|
|
int finalDamage = (int)(baseDamage * levelBonus);
|
|
|
|
return finalDamage;
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3.3 创建库存模块
|
|
|
|
```csharp
|
|
using GFramework.Core.Abstractions.architecture;
|
|
using GFramework.Core.model;
|
|
using GFramework.Core.system;
|
|
using GFramework.Core.property;
|
|
|
|
namespace MyGame.Modules.InventoryModule
|
|
{
|
|
/// <summary>
|
|
/// 库存功能模块
|
|
/// </summary>
|
|
public class InventoryModule : IArchitectureModule
|
|
{
|
|
public string Name => "InventoryModule";
|
|
public string Version => "1.0.0";
|
|
|
|
public void Install(IArchitecture architecture)
|
|
{
|
|
Console.WriteLine($"安装模块: {Name} v{Version}");
|
|
|
|
// 注册库存模型和系统
|
|
architecture.RegisterModel(new InventoryModel());
|
|
architecture.RegisterSystem(new InventorySystem());
|
|
|
|
Console.WriteLine($"模块 {Name} 安装完成");
|
|
}
|
|
|
|
public void Uninstall(IArchitecture architecture)
|
|
{
|
|
Console.WriteLine($"卸载模块: {Name}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 物品数据
|
|
/// </summary>
|
|
public class Item
|
|
{
|
|
public string Id { get; set; }
|
|
public string Name { get; set; }
|
|
public string Description { get; set; }
|
|
public int Quantity { get; set; }
|
|
public ItemType Type { get; set; }
|
|
}
|
|
|
|
public enum ItemType
|
|
{
|
|
Weapon,
|
|
Armor,
|
|
Consumable,
|
|
Material,
|
|
Quest
|
|
}
|
|
|
|
/// <summary>
|
|
/// 库存模型
|
|
/// </summary>
|
|
public class InventoryModel : AbstractModel
|
|
{
|
|
public BindableProperty<int> MaxSlots { get; } = new(50);
|
|
public BindableProperty<int> Gold { get; } = new(0);
|
|
|
|
private readonly List<Item> _items = new();
|
|
|
|
protected override void OnInit()
|
|
{
|
|
Console.WriteLine("库存模型初始化完成");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 添加物品
|
|
/// </summary>
|
|
public bool AddItem(Item item)
|
|
{
|
|
if (_items.Count >= MaxSlots.Value)
|
|
{
|
|
Console.WriteLine("库存已满");
|
|
return false;
|
|
}
|
|
|
|
// 检查是否已有相同物品
|
|
var existingItem = _items.FirstOrDefault(i => i.Id == item.Id);
|
|
if (existingItem != null)
|
|
{
|
|
existingItem.Quantity += item.Quantity;
|
|
}
|
|
else
|
|
{
|
|
_items.Add(item);
|
|
}
|
|
|
|
Console.WriteLine($"添加物品: {item.Name} x{item.Quantity}");
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 移除物品
|
|
/// </summary>
|
|
public bool RemoveItem(string itemId, int quantity)
|
|
{
|
|
var item = _items.FirstOrDefault(i => i.Id == itemId);
|
|
if (item == null)
|
|
{
|
|
Console.WriteLine($"物品不存在: {itemId}");
|
|
return false;
|
|
}
|
|
|
|
if (item.Quantity < quantity)
|
|
{
|
|
Console.WriteLine($"物品数量不足: {item.Name}");
|
|
return false;
|
|
}
|
|
|
|
item.Quantity -= quantity;
|
|
if (item.Quantity == 0)
|
|
{
|
|
_items.Remove(item);
|
|
}
|
|
|
|
Console.WriteLine($"移除物品: {item.Name} x{quantity}");
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取所有物品
|
|
/// </summary>
|
|
public IReadOnlyList<Item> GetAllItems() => _items.AsReadOnly();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 库存系统
|
|
/// </summary>
|
|
public class InventorySystem : AbstractSystem
|
|
{
|
|
private InventoryModel _inventoryModel;
|
|
|
|
protected override void OnInit()
|
|
{
|
|
_inventoryModel = this.GetModel<InventoryModel>();
|
|
Console.WriteLine("库存系统初始化完成");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 使用物品
|
|
/// </summary>
|
|
public void UseItem(string itemId)
|
|
{
|
|
var items = _inventoryModel.GetAllItems();
|
|
var item = items.FirstOrDefault(i => i.Id == itemId);
|
|
|
|
if (item == null)
|
|
{
|
|
Console.WriteLine($"物品不存在: {itemId}");
|
|
return;
|
|
}
|
|
|
|
Console.WriteLine($"使用物品: {item.Name}");
|
|
|
|
// 根据物品类型执行不同逻辑
|
|
switch (item.Type)
|
|
{
|
|
case ItemType.Consumable:
|
|
UseConsumable(item);
|
|
break;
|
|
case ItemType.Weapon:
|
|
EquipWeapon(item);
|
|
break;
|
|
default:
|
|
Console.WriteLine($"无法使用该类型的物品: {item.Type}");
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void UseConsumable(Item item)
|
|
{
|
|
Console.WriteLine($"消耗物品: {item.Name}");
|
|
_inventoryModel.RemoveItem(item.Id, 1);
|
|
}
|
|
|
|
private void EquipWeapon(Item item)
|
|
{
|
|
Console.WriteLine($"装备武器: {item.Name}");
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## 步骤 4: 依赖管理
|
|
|
|
使用 IoC 容器管理依赖关系,实现松耦合设计。
|
|
|
|
### 4.1 注册服务
|
|
|
|
```csharp
|
|
using GFramework.Core.architecture;
|
|
using GFramework.Core.Abstractions.architecture;
|
|
using GFramework.Core.ioc;
|
|
using MyGame.Modules.PlayerModule;
|
|
using MyGame.Modules.CombatModule;
|
|
using MyGame.Modules.InventoryModule;
|
|
|
|
namespace MyGame.Core.Architecture
|
|
{
|
|
/// <summary>
|
|
/// 游戏主架构(完整版)
|
|
/// </summary>
|
|
public class GameArchitecture : Architecture
|
|
{
|
|
public static IArchitecture Interface { get; private set; }
|
|
|
|
protected override void Init()
|
|
{
|
|
Interface = this;
|
|
|
|
Console.WriteLine("=== 初始化游戏架构 ===");
|
|
|
|
// 注册核心服务
|
|
RegisterCoreServices();
|
|
}
|
|
|
|
protected override void InstallModules()
|
|
{
|
|
Console.WriteLine("\n=== 安装功能模块 ===");
|
|
|
|
// 按依赖顺序安装模块
|
|
InstallModule(new PlayerModule()); // 基础模块
|
|
InstallModule(new InventoryModule()); // 依赖玩家模块
|
|
InstallModule(new CombatModule()); // 依赖玩家模块
|
|
InstallModule(new QuestModule()); // 依赖多个模块
|
|
|
|
Console.WriteLine("\n=== 所有模块安装完成 ===");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 注册核心服务
|
|
/// </summary>
|
|
private void RegisterCoreServices()
|
|
{
|
|
// 注册日志服务
|
|
var loggerFactory = new ConsoleLoggerFactory();
|
|
RegisterService<ILoggerFactory>(loggerFactory);
|
|
|
|
// 注册配置服务
|
|
var configManager = new ConfigurationManager();
|
|
RegisterService<IConfigurationManager>(configManager);
|
|
|
|
// 注册资源管理器
|
|
var resourceManager = new ResourceManager();
|
|
RegisterService<IResourceManager>(resourceManager);
|
|
|
|
Console.WriteLine("核心服务注册完成");
|
|
}
|
|
}
|
|
|
|
// 简化的服务实现示例
|
|
public interface ILoggerFactory { }
|
|
public class ConsoleLoggerFactory : ILoggerFactory { }
|
|
|
|
public interface IConfigurationManager { }
|
|
public class ConfigurationManager : IConfigurationManager { }
|
|
|
|
public interface IResourceManager { }
|
|
public class ResourceManager : IResourceManager { }
|
|
}
|
|
```
|
|
|
|
### 4.2 创建任务模块(展示模块间依赖)
|
|
|
|
```csharp
|
|
using GFramework.Core.Abstractions.architecture;
|
|
using GFramework.Core.model;
|
|
using GFramework.Core.system;
|
|
using MyGame.Domain.Models.Player;
|
|
using MyGame.Modules.InventoryModule;
|
|
|
|
namespace MyGame.Modules.QuestModule
|
|
{
|
|
/// <summary>
|
|
/// 任务功能模块
|
|
/// </summary>
|
|
public class QuestModule : IArchitectureModule
|
|
{
|
|
public string Name => "QuestModule";
|
|
public string Version => "1.0.0";
|
|
|
|
public void Install(IArchitecture architecture)
|
|
{
|
|
Console.WriteLine($"安装模块: {Name} v{Version}");
|
|
|
|
// 注册任务模型和系统
|
|
architecture.RegisterModel(new QuestModel());
|
|
architecture.RegisterSystem(new QuestSystem());
|
|
|
|
Console.WriteLine($"模块 {Name} 安装完成");
|
|
}
|
|
|
|
public void Uninstall(IArchitecture architecture)
|
|
{
|
|
Console.WriteLine($"卸载模块: {Name}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 任务数据
|
|
/// </summary>
|
|
public class Quest
|
|
{
|
|
public int Id { get; set; }
|
|
public string Name { get; set; }
|
|
public string Description { get; set; }
|
|
public bool IsCompleted { get; set; }
|
|
public int RewardExp { get; set; }
|
|
public int RewardGold { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// 任务模型
|
|
/// </summary>
|
|
public class QuestModel : AbstractModel
|
|
{
|
|
private readonly List<Quest> _activeQuests = new();
|
|
private readonly List<Quest> _completedQuests = new();
|
|
|
|
protected override void OnInit()
|
|
{
|
|
Console.WriteLine("任务模型初始化完成");
|
|
}
|
|
|
|
public void AddQuest(Quest quest)
|
|
{
|
|
_activeQuests.Add(quest);
|
|
Console.WriteLine($"接受任务: {quest.Name}");
|
|
}
|
|
|
|
public void CompleteQuest(int questId)
|
|
{
|
|
var quest = _activeQuests.FirstOrDefault(q => q.Id == questId);
|
|
if (quest != null)
|
|
{
|
|
quest.IsCompleted = true;
|
|
_activeQuests.Remove(quest);
|
|
_completedQuests.Add(quest);
|
|
Console.WriteLine($"完成任务: {quest.Name}");
|
|
}
|
|
}
|
|
|
|
public IReadOnlyList<Quest> GetActiveQuests() => _activeQuests.AsReadOnly();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 任务系统(依赖多个模块)
|
|
/// </summary>
|
|
public class QuestSystem : AbstractSystem
|
|
{
|
|
private QuestModel _questModel;
|
|
private PlayerModel _playerModel;
|
|
private InventoryModel _inventoryModel;
|
|
|
|
protected override void OnInit()
|
|
{
|
|
// 获取依赖的模型
|
|
_questModel = this.GetModel<QuestModel>();
|
|
_playerModel = this.GetModel<PlayerModel>();
|
|
_inventoryModel = this.GetModel<InventoryModel>();
|
|
|
|
Console.WriteLine("任务系统初始化完成");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 完成任务并发放奖励
|
|
/// </summary>
|
|
public void CompleteQuest(int questId)
|
|
{
|
|
var quest = _questModel.GetActiveQuests()
|
|
.FirstOrDefault(q => q.Id == questId);
|
|
|
|
if (quest == null)
|
|
{
|
|
Console.WriteLine($"任务不存在: {questId}");
|
|
return;
|
|
}
|
|
|
|
// 标记任务完成
|
|
_questModel.CompleteQuest(questId);
|
|
|
|
// 发放奖励
|
|
GiveRewards(quest);
|
|
}
|
|
|
|
private void GiveRewards(Quest quest)
|
|
{
|
|
Console.WriteLine($"\n=== 任务奖励 ===");
|
|
|
|
// 经验奖励
|
|
if (quest.RewardExp > 0)
|
|
{
|
|
_playerModel.GainExperience(quest.RewardExp);
|
|
Console.WriteLine($"获得经验: {quest.RewardExp}");
|
|
}
|
|
|
|
// 金币奖励
|
|
if (quest.RewardGold > 0)
|
|
{
|
|
_inventoryModel.Gold.Value += quest.RewardGold;
|
|
Console.WriteLine($"获得金币: {quest.RewardGold}");
|
|
}
|
|
|
|
Console.WriteLine("=================\n");
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## 步骤 5: 代码组织
|
|
|
|
建立清晰的代码组织规范,提高代码可读性和可维护性。
|
|
|
|
### 5.1 命名规范
|
|
|
|
```csharp
|
|
namespace MyGame.Core.Constants
|
|
{
|
|
/// <summary>
|
|
/// 游戏常量定义
|
|
/// </summary>
|
|
public static class GameConstants
|
|
{
|
|
// 游戏配置
|
|
public const string GameName = "MyLargeGame";
|
|
public const string GameVersion = "1.0.0";
|
|
|
|
// 玩家配置
|
|
public const int DefaultPlayerLevel = 1;
|
|
public const int MaxPlayerLevel = 100;
|
|
public const int DefaultHealth = 100;
|
|
public const int DefaultMana = 50;
|
|
|
|
// 库存配置
|
|
public const int DefaultInventorySlots = 50;
|
|
public const int MaxInventorySlots = 200;
|
|
|
|
// 战斗配置
|
|
public const float BaseDamageMultiplier = 1.0f;
|
|
public const float CriticalDamageMultiplier = 2.0f;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 层级常量
|
|
/// </summary>
|
|
public static class LayerConstants
|
|
{
|
|
public const string PlayerLayer = "Player";
|
|
public const string EnemyLayer = "Enemy";
|
|
public const string EnvironmentLayer = "Environment";
|
|
public const string UILayer = "UI";
|
|
}
|
|
|
|
/// <summary>
|
|
/// 事件名称常量
|
|
/// </summary>
|
|
public static class EventNames
|
|
{
|
|
public const string PlayerLevelUp = "Player.LevelUp";
|
|
public const string PlayerDeath = "Player.Death";
|
|
public const string QuestCompleted = "Quest.Completed";
|
|
public const string ItemAcquired = "Item.Acquired";
|
|
}
|
|
}
|
|
```
|
|
|
|
### 5.2 文件组织规范
|
|
|
|
```csharp
|
|
// 文件: PlayerModel.cs
|
|
// 位置: MyGame.Domain/Models/Player/PlayerModel.cs
|
|
|
|
using GFramework.Core.model;
|
|
using GFramework.Core.property;
|
|
|
|
namespace MyGame.Domain.Models.Player
|
|
{
|
|
/// <summary>
|
|
/// 玩家数据模型
|
|
/// 职责: 管理玩家的核心数据和状态
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// 该模型包含:
|
|
/// - 基础属性(名称、等级、经验)
|
|
/// - 战斗属性(生命值、法力值)
|
|
/// - 位置信息
|
|
/// </remarks>
|
|
public class PlayerModel : AbstractModel
|
|
{
|
|
#region Properties
|
|
|
|
// 基础属性
|
|
public BindableProperty<string> Name { get; } = new("Player");
|
|
public BindableProperty<int> Level { get; } = new(1);
|
|
public BindableProperty<int> Experience { get; } = new(0);
|
|
|
|
// 战斗属性
|
|
public BindableProperty<int> Health { get; } = new(100);
|
|
public BindableProperty<int> MaxHealth { get; } = new(100);
|
|
|
|
#endregion
|
|
|
|
#region Lifecycle
|
|
|
|
protected override void OnInit()
|
|
{
|
|
RegisterEventHandlers();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// 受到伤害
|
|
/// </summary>
|
|
/// <param name="damage">伤害值</param>
|
|
public void TakeDamage(int damage)
|
|
{
|
|
Health.Value = Math.Max(0, Health.Value - damage);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private Methods
|
|
|
|
private void RegisterEventHandlers()
|
|
{
|
|
Level.Register(OnLevelChanged);
|
|
}
|
|
|
|
private void OnLevelChanged(int newLevel)
|
|
{
|
|
Console.WriteLine($"玩家升级到 {newLevel} 级");
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
```
|
|
|
|
### 5.3 扩展方法组织
|
|
|
|
```csharp
|
|
using GFramework.Core.Abstractions.architecture;
|
|
using MyGame.Domain.Models.Player;
|
|
|
|
namespace MyGame.Core.Extensions
|
|
{
|
|
/// <summary>
|
|
/// 游戏扩展方法
|
|
/// </summary>
|
|
public static class GameExtensions
|
|
{
|
|
/// <summary>
|
|
/// 获取玩家模型(快捷方法)
|
|
/// </summary>
|
|
public static PlayerModel GetPlayerModel(this IArchitecture architecture)
|
|
{
|
|
return architecture.GetModel<PlayerModel>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查玩家是否存活
|
|
/// </summary>
|
|
public static bool IsPlayerAlive(this IArchitecture architecture)
|
|
{
|
|
var player = architecture.GetPlayerModel();
|
|
return player.Health.Value > 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取玩家位置
|
|
/// </summary>
|
|
public static (float x, float y, float z) GetPlayerPosition(this IArchitecture architecture)
|
|
{
|
|
var player = architecture.GetPlayerModel();
|
|
return (player.PositionX.Value, player.PositionY.Value, player.PositionZ.Value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 玩家模型扩展方法
|
|
/// </summary>
|
|
public static class PlayerModelExtensions
|
|
{
|
|
/// <summary>
|
|
/// 检查是否满血
|
|
/// </summary>
|
|
public static bool IsFullHealth(this PlayerModel player)
|
|
{
|
|
return player.Health.Value == player.MaxHealth.Value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取生命值百分比
|
|
/// </summary>
|
|
public static float GetHealthPercentage(this PlayerModel player)
|
|
{
|
|
return (float)player.Health.Value / player.MaxHealth.Value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查是否低血量
|
|
/// </summary>
|
|
public static bool IsLowHealth(this PlayerModel player, float threshold = 0.3f)
|
|
{
|
|
return player.GetHealthPercentage() < threshold;
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## 步骤 6: 团队协作
|
|
|
|
建立团队协作规范,确保代码质量和开发效率。
|
|
|
|
### 6.1 代码审查清单
|
|
|
|
创建代码审查清单文档:
|
|
|
|
```markdown
|
|
# 代码审查清单
|
|
|
|
## 架构设计
|
|
- [ ] 组件是否放在正确的层级(Core/Domain/Application/Infrastructure/Presentation)
|
|
- [ ] 是否遵循单一职责原则
|
|
- [ ] 依赖关系是否合理(避免循环依赖)
|
|
- [ ] 是否正确使用了模块化设计
|
|
|
|
## 代码质量
|
|
- [ ] 命名是否清晰且符合规范
|
|
- [ ] 是否有适当的注释和文档
|
|
- [ ] 是否有单元测试覆盖
|
|
- [ ] 是否处理了异常情况
|
|
|
|
## GFramework 使用
|
|
- [ ] 是否正确继承了基类(AbstractModel/AbstractSystem等)
|
|
- [ ] 是否正确使用了生命周期方法(OnInit/OnDestroy)
|
|
- [ ] 是否正确使用了依赖注入(GetModel/GetSystem/GetService)
|
|
- [ ] 事件是否正确注册和注销
|
|
|
|
## 性能考虑
|
|
- [ ] 是否避免了不必要的对象创建
|
|
- [ ] 是否正确使用了对象池
|
|
- [ ] 是否避免了频繁的 GC 分配
|
|
- [ ] 协程使用是否合理
|
|
|
|
## 可维护性
|
|
- [ ] 代码是否易于理解和修改
|
|
- [ ] 是否有适当的日志记录
|
|
- [ ] 配置是否可外部化
|
|
- [ ] 是否便于测试
|
|
```
|
|
|
|
### 6.2 Git 工作流
|
|
|
|
```bash
|
|
# 功能分支命名规范
|
|
feature/player-system # 新功能
|
|
bugfix/inventory-crash # Bug 修复
|
|
refactor/combat-module # 重构
|
|
docs/api-documentation # 文档更新
|
|
|
|
# 提交信息规范
|
|
feat: 添加玩家升级系统
|
|
fix: 修复库存物品重复添加的问题
|
|
refactor: 重构战斗系统的伤害计算
|
|
docs: 更新架构设计文档
|
|
test: 添加玩家系统单元测试
|
|
chore: 更新依赖包版本
|
|
```
|
|
|
|
### 6.3 项目配置文件
|
|
|
|
创建 `.editorconfig` 统一代码风格:
|
|
|
|
```ini
|
|
# EditorConfig is awesome: https://EditorConfig.org
|
|
|
|
root = true
|
|
|
|
[*]
|
|
charset = utf-8
|
|
indent_style = space
|
|
indent_size = 4
|
|
insert_final_newline = true
|
|
trim_trailing_whitespace = true
|
|
|
|
[*.cs]
|
|
# 命名规则
|
|
dotnet_naming_rule.interfaces_should_be_prefixed_with_i.severity = warning
|
|
dotnet_naming_rule.interfaces_should_be_prefixed_with_i.symbols = interface
|
|
dotnet_naming_rule.interfaces_should_be_prefixed_with_i.style = begins_with_i
|
|
|
|
# 代码风格
|
|
csharp_new_line_before_open_brace = all
|
|
csharp_new_line_before_else = true
|
|
csharp_new_line_before_catch = true
|
|
csharp_new_line_before_finally = true
|
|
|
|
[*.md]
|
|
trim_trailing_whitespace = false
|
|
```
|
|
|
|
## 完整代码
|
|
|
|
### Program.cs - 主程序
|
|
|
|
```csharp
|
|
using MyGame.Core.Architecture;
|
|
using MyGame.Application.Systems.Player;
|
|
using MyGame.Modules.InventoryModule;
|
|
using MyGame.Modules.QuestModule;
|
|
using MyGame.Core.Extensions;
|
|
|
|
namespace MyGame
|
|
{
|
|
class Program
|
|
{
|
|
static async Task Main(string[] args)
|
|
{
|
|
Console.WriteLine("=== 大型游戏项目示例 ===\n");
|
|
|
|
// 1. 初始化架构
|
|
var architecture = new GameArchitecture();
|
|
architecture.Initialize();
|
|
await architecture.WaitUntilReadyAsync();
|
|
|
|
Console.WriteLine("\n=== 架构初始化完成 ===\n");
|
|
|
|
// 2. 测试玩家系统
|
|
await TestPlayerSystem(architecture);
|
|
|
|
// 3. 测试库存系统
|
|
await TestInventorySystem(architecture);
|
|
|
|
// 4. 测试任务系统
|
|
await TestQuestSystem(architecture);
|
|
|
|
// 5. 测试模块协作
|
|
await TestModuleIntegration(architecture);
|
|
|
|
Console.WriteLine("\n=== 测试完成 ===");
|
|
}
|
|
|
|
static async Task TestPlayerSystem(GameArchitecture architecture)
|
|
{
|
|
Console.WriteLine("\n--- 测试玩家系统 ---");
|
|
|
|
var playerSystem = architecture.GetSystem<PlayerSystem>();
|
|
var playerModel = architecture.GetPlayerModel();
|
|
|
|
// 移动玩家
|
|
playerSystem.MovePlayer(10, 0, 5);
|
|
Console.WriteLine($"玩家位置: {architecture.GetPlayerPosition()}");
|
|
|
|
// 受到伤害
|
|
playerModel.TakeDamage(30);
|
|
Console.WriteLine($"当前生命值: {playerModel.Health.Value}/{playerModel.MaxHealth.Value}");
|
|
|
|
// 治疗
|
|
playerSystem.HealPlayer(20);
|
|
Console.WriteLine($"治疗后生命值: {playerModel.Health.Value}/{playerModel.MaxHealth.Value}");
|
|
|
|
// 获得经验
|
|
playerModel.GainExperience(150);
|
|
|
|
await Task.Delay(500);
|
|
}
|
|
|
|
static async Task TestInventorySystem(GameArchitecture architecture)
|
|
{
|
|
Console.WriteLine("\n--- 测试库存系统 ---");
|
|
|
|
var inventoryModel = architecture.GetModel<InventoryModel>();
|
|
var inventorySystem = architecture.GetSystem<InventorySystem>();
|
|
|
|
// 添加物品
|
|
inventoryModel.AddItem(new Item
|
|
{
|
|
Id = "potion_health",
|
|
Name = "生命药水",
|
|
Description = "恢复 50 点生命值",
|
|
Quantity = 5,
|
|
Type = ItemType.Consumable
|
|
});
|
|
|
|
inventoryModel.AddItem(new Item
|
|
{
|
|
Id = "sword_iron",
|
|
Name = "铁剑",
|
|
Description = "基础武器",
|
|
Quantity = 1,
|
|
Type = ItemType.Weapon
|
|
});
|
|
|
|
// 显示库存
|
|
var items = inventoryModel.GetAllItems();
|
|
Console.WriteLine($"\n当前库存 ({items.Count}/{inventoryModel.MaxSlots.Value}):");
|
|
foreach (var item in items)
|
|
{
|
|
Console.WriteLine($" - {item.Name} x{item.Quantity} ({item.Type})");
|
|
}
|
|
|
|
// 使用物品
|
|
inventorySystem.UseItem("potion_health");
|
|
|
|
await Task.Delay(500);
|
|
}
|
|
|
|
static async Task TestQuestSystem(GameArchitecture architecture)
|
|
{
|
|
Console.WriteLine("\n--- 测试任务系统 ---");
|
|
|
|
var questModel = architecture.GetModel<QuestModel>();
|
|
var questSystem = architecture.GetSystem<QuestSystem>();
|
|
|
|
// 添加任务
|
|
questModel.AddQuest(new Quest
|
|
{
|
|
Id = 1,
|
|
Name = "击败史莱姆",
|
|
Description = "击败 10 只史莱姆",
|
|
RewardExp = 100,
|
|
RewardGold = 50
|
|
});
|
|
|
|
// 显示活动任务
|
|
var activeQuests = questModel.GetActiveQuests();
|
|
Console.WriteLine($"\n活动任务 ({activeQuests.Count}):");
|
|
foreach (var quest in activeQuests)
|
|
{
|
|
Console.WriteLine($" - {quest.Name}: {quest.Description}");
|
|
}
|
|
|
|
// 完成任务
|
|
await Task.Delay(1000);
|
|
questSystem.CompleteQuest(1);
|
|
|
|
await Task.Delay(500);
|
|
}
|
|
|
|
static async Task TestModuleIntegration(GameArchitecture architecture)
|
|
{
|
|
Console.WriteLine("\n--- 测试模块协作 ---");
|
|
|
|
var playerModel = architecture.GetPlayerModel();
|
|
var inventoryModel = architecture.GetModel<InventoryModel>();
|
|
|
|
Console.WriteLine($"\n玩家状态:");
|
|
Console.WriteLine($" 等级: {playerModel.Level.Value}");
|
|
Console.WriteLine($" 经验: {playerModel.Experience.Value}");
|
|
Console.WriteLine($" 生命值: {playerModel.Health.Value}/{playerModel.MaxHealth.Value}");
|
|
Console.WriteLine($" 金币: {inventoryModel.Gold.Value}");
|
|
Console.WriteLine($" 库存物品: {inventoryModel.GetAllItems().Count}");
|
|
|
|
// 检查玩家状态
|
|
if (architecture.IsPlayerAlive())
|
|
{
|
|
Console.WriteLine("\n玩家状态: 存活");
|
|
|
|
if (playerModel.IsLowHealth())
|
|
{
|
|
Console.WriteLine("警告: 生命值过低!");
|
|
}
|
|
}
|
|
|
|
await Task.Delay(500);
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## 运行结果
|
|
|
|
运行程序后,你将看到类似以下的输出:
|
|
|
|
```
|
|
=== 大型游戏项目示例 ===
|
|
|
|
=== 初始化游戏架构 ===
|
|
初始化游戏架构...
|
|
核心服务注册完成
|
|
|
|
=== 安装功能模块 ===
|
|
安装模块: PlayerModule v1.0.0
|
|
玩家模型初始化: Player
|
|
玩家系统初始化完成
|
|
等级系统: 玩家达到 1 级
|
|
重新计算 1 级的属性
|
|
模块 PlayerModule 安装完成
|
|
|
|
安装模块: InventoryModule v1.0.0
|
|
库存模型初始化完成
|
|
库存系统初始化完成
|
|
模块 InventoryModule 安装完成
|
|
|
|
安装模块: CombatModule v1.0.0
|
|
战斗系统初始化完成
|
|
技能系统初始化完成
|
|
伤害计算系统初始化完成
|
|
模块 CombatModule 安装完成
|
|
|
|
安装模块: QuestModule v1.0.0
|
|
任务模型初始化完成
|
|
任务系统初始化完成
|
|
模块 QuestModule 安装完成
|
|
|
|
=== 所有模块安装完成 ===
|
|
|
|
=== 架构初始化完成 ===
|
|
|
|
--- 测试玩家系统 ---
|
|
玩家移动到 (10, 0, 5)
|
|
玩家位置: (10, 0, 5)
|
|
当前生命值: 70/100
|
|
玩家恢复 20 点生命值
|
|
治疗后生命值: 90/100
|
|
玩家升级到 2 级
|
|
等级系统: 玩家达到 2 级
|
|
重新计算 2 级的属性
|
|
|
|
--- 测试库存系统 ---
|
|
添加物品: 生命药水 x5
|
|
添加物品: 铁剑 x1
|
|
|
|
当前库存 (2/50):
|
|
- 生命药水 x5 (Consumable)
|
|
- 铁剑 x1 (Weapon)
|
|
|
|
使用物品: 生命药水
|
|
消耗物品: 生命药水
|
|
移除物品: 生命药水 x1
|
|
|
|
--- 测试任务系统 ---
|
|
接受任务: 击败史莱姆
|
|
|
|
活动任务 (1):
|
|
- 击败史莱姆: 击败 10 只史莱姆
|
|
|
|
完成任务: 击败史莱姆
|
|
|
|
=== 任务奖励 ===
|
|
玩家升级到 3 级
|
|
等级系统: 玩家达到 3 级
|
|
重新计算 3 级的属性
|
|
获得经验: 100
|
|
获得金币: 50
|
|
=================
|
|
|
|
--- 测试模块协作 ---
|
|
|
|
玩家状态:
|
|
等级: 3
|
|
经验: 50
|
|
生命值: 110/110
|
|
金币: 50
|
|
库存物品: 2
|
|
|
|
玩家状态: 存活
|
|
|
|
=== 测试完成 ===
|
|
```
|
|
|
|
**验证步骤**:
|
|
|
|
1. 架构正确初始化,所有模块按顺序加载
|
|
2. 各模块功能正常工作
|
|
3. 模块间依赖关系正确
|
|
4. 事件系统正常触发
|
|
5. 数据在模块间正确共享
|
|
|
|
## 下一步
|
|
|
|
恭喜!你已经掌握了大型项目的组织方法。接下来可以学习:
|
|
|
|
- [Godot 完整项目](/zh-CN/tutorials/godot-complete-project) - 在 Godot 中应用这些原则
|
|
- [资源管理最佳实践](/zh-CN/tutorials/resource-management) - 管理大型项目的资源
|
|
- [实现存档系统](/zh-CN/tutorials/save-system) - 保存复杂的游戏状态
|
|
- [架构模式最佳实践](/zh-CN/best-practices/architecture-patterns) - 高级架构模式
|
|
|
|
## 相关文档
|
|
|
|
- [架构组件](/zh-CN/core/architecture) - 架构系统详解
|
|
- [模块系统](/zh-CN/core/architecture#模块系统) - 模块化设计
|
|
- [依赖注入](/zh-CN/core/ioc) - IoC 容器使用
|
|
- [最佳实践](/zh-CN/best-practices/) - 开发最佳实践
|