想要使用太阳编辑器制作魔兽地图,在粗略掌握TS语言基础语法之后,必须了解太阳编辑器的框架有哪些功能。
太阳编辑器框架是一个专门为魔兽地图开发设计的完整解决方案,它通过提供各种标准化的模块和工具,大大简化了地图开发的复杂度,提高了开发效率,同时保证了代码质量和游戏性能。
框架的主要优势
降低开发难度
- 提供高层封装
- 简化复杂操作
- 标准化的接口
提高开发效率
- 丰富的工具类
- 现成的功能模块
- 可复用的组件
代码质量保证
- 统一的编码规范
- 类型安全(TypeScript)
- 模块化设计
游戏性能优化
- 统一的资源管理
- 优化的数据结构
- 性能监控机制
扩展性与维护性
- 松耦合设计
- 插件化架构
- 易于扩展
太阳编辑器框架(Solar Framework)结构介绍
1. Actor(演员)系统
这是框架的核心系统之一,位于 solar/solar-common/actor/
目录下:
- Actor.ts - 基础演员类,是所有演员类型的父类
- ActorAbility.ts - 技能演员
- ActorBuff.ts - Buff演员
- ActorItem.ts - 物品演员
- ActorUnit.ts - 单位演员
演员系统提供了一个统一的数据结构来模拟游戏中的各种对象(单位、物品、技能、buff等)。主要优点是:
- 统一的数据结构和接口
- 方便对象之间的转换(如物品可以转化为buff)
- 提供标准的事件系统
2. 状态(State)系统
位于 solar/solar-common/actor/state/
目录:
- SolarActorState.ts - 演员系统的状态管理
- SolarActorBuffState.ts - Buff状态管理
- SolarActorFrameState.ts - UI框架状态管理
- SolarActorItemState.ts - 物品状态管理
- SolarActorUnitState.ts - 单位状态管理
状态系统负责管理各种游戏对象的状态变化,处理状态之间的转换和同步。
3. 工具(Util)类
位于 solar/solar-common/actor/util/
目录:
- ActorUtil.ts - 通用演员工具类
- ActorAbilityUtil.ts - 技能工具类
- ActorBuffUtil.ts - Buff工具类
- ActorItemUtil.ts - 物品工具类
- ActorUnitUtil.ts - 单位工具类
- ActorFrameUtil.ts - UI框架工具类
提供了各种辅助方法来操作演员对象。
4. 属性(Attribute)系统
位于 solar/solar-common/attribute/
目录:
- BigAttributeCompatibleState.ts - 大数值属性兼容
- BigAttributeUICompatibleState.ts - 大数值UI显示兼容
- ItemAttributeState.ts - 物品属性系统
属性系统负责:
- 管理游戏对象的各种属性(攻击、防御、生命等)
- 处理属性的叠加、消除
- 支持大数值模式
- 处理UI显示
主要特点
- 模块化设计
- 各个系统之间相对独立
- 便于维护和扩展
- 统一的接口
- 使用演员系统统一各种游戏对象
- 提供标准的事件系统
- 完善的工具类
- 提供丰富的工具方法
- 简化开发流程
- 灵活的属性系统
- 支持复杂的属性计算
- 支持大数值模式
这个框架的设计理念是提供一个统一的、易于使用的接口来处理游戏中的各种对象,同时保持足够的灵活性以适应不同的游戏需求。
Actor(演员)系统详细介绍
1. 基本概念
Actor(演员)系统是一个统一的数据结构,用来模拟游戏中的各种对象:
- 单位(ActorUnit)
- 物品(ActorItem)
- 技能(ActorAbility)
- Buff(ActorBuff)
2. 主要类型
// 基础演员类型
interface AppActorType {
id: string; // 演员类型ID
name?: string; // 名称
icon?: string; // 图标
describe?: string; // 描述
class?: string; // 分类
// ... 其他基础属性
}
// 物品演员类型
interface AppActorItemType extends AppActorType {
pawnable?: boolean; // 是否可抵押
droppable?: boolean; // 是否可丢弃
uses?: number; // 使用次数
stackMax?: number; // 最大堆叠数
}
// 技能演员类型
interface AppActorAbilityType extends AppActorType {
lumberCost?: number; // 魔法消耗
// ... 技能相关属性
}
3. 使用示例
3.1 注册演员类型
// 注册一个物品类型
ActorTypeUtil.registerActorType({
id: "神圣剑",
name: "神圣之剑",
icon: "ReplaceableTextures\\CommandButtons\\BTNSword.blp",
describe: "增加100点攻击力",
class: "武器",
// 物品属性
pawnable: true,
droppable: true,
// 事件处理
onCreated: (actor) => {
// 创建时的逻辑
},
onUnitPickupItem: (actor, unit) => {
// 单位拾取时的逻辑
}
});
3.2 创建演员实例
// 创建物品
let sword = ActorItemUtil.createActorItem("神圣剑", x, y);
// 创建单位
let hero = ActorUnitUtil.createActorUnit(player, "英雄", x, y);
// 创建技能
let skill = ActorAbilityUtil.createActorAbility("技能ID", unit);
// 创建Buff
let buff = ActorBuffUtil.addActorBuff(unit, "BuffID");
3.3 事件处理
// 在注册类型时定义事件处理
{
// 创建时触发
onCreated: (actor: Actor) => {
// ...
},
// 单位获得此演员时触发
onUnitAddActor: (actor: Actor, addedActor: Actor) => {
// ...
},
// 单位失去此演员时触发
onUnitRemoveActor: (actor: Actor, removedActor: Actor) => {
// ...
},
// 单位死亡时触发
onUnitDeath: (actor: Actor, killingUnit: unit) => {
// ...
}
}
3.4 属性系统集成
// 设置物品属性
AttributeUtil.setItemTypeAttribute("神圣剑", {
attack: 100,
armor: 10
});
// 获取单位所有演员属性
let attributes = ActorUtil.getUnitAllActorAttributes(unit);
3.5 实际应用示例
以下是一个双击物品交换的示例:
ActorTypeUtil.registerActorType({
id: "可交换物品",
class: "物品",
onLocalClick: (actor, btn) => {
if(actor.tempNum == null) {
actor.tempNum = _g_time;
} else {
// 判断是否双击
if(_g_time - actor.tempNum < 0.5) {
// 交换物品逻辑
let unit = actor.unit;
let targetUnit = GetSpellTargetUnit();
if(IsHandle(targetUnit)) {
UnitAddItem(targetUnit, actor.item);
}
}
actor.tempNum = null;
}
}
});
4. 主要优点
- 统一接口
- 所有游戏对象使用相同的接口
- 方便处理对象之间的转换
- 事件系统
- 提供标准的事件处理机制
- 方便监听和响应游戏事件
- 属性系统集成
- 与属性系统无缝集成
- 方便处理属性的叠加和移除
- 扩展性
- 易于添加新的演员类型
- 易于扩展现有功能
5. 使用建议
- 优先使用 ActorUtil 而不是具体的工具类,保持代码的通用性
- 合理使用事件系统,避免直接修改对象状态
- 注意演员的生命周期管理,及时销毁不需要的演员
- 使用属性系统来处理数值相关的逻辑
通过这个系统,你可以用统一的方式处理游戏中的各种对象,大大简化开发流程。
我来详细介绍状态(State)系统的使用。
状态(State)系统详细介绍
1. 基本概念
状态系统主要负责:
- 管理游戏对象的状态变化
- 处理状态之间的转换
- 同步状态更新
- 响应状态变化的事件
2. 主要状态类
1. SolarActorState - 演员系统总状态管理
2. SolarActorBuffState - Buff状态管理
3. SolarActorFrameState - UI框架状态管理
4. SolarActorItemState - 物品状态管理
5. SolarActorUnitState - 单位状态管理
3. 使用示例
3.1 创建自定义状态
// 创建一个双击物品交换状态
export default class 类双击物品时英雄宝宝交换该物品 {
constructor() {
// 注册状态
ActorTypeUtil.registerActorType({
id: "双击交换物品",
class: "物品",
// 本地点击事件
onLocalClick: (actor, btn) => {
if(actor.tempNum == null) {
// 记录第一次点击时间
actor.tempNum = _g_time;
} else {
// 判断是否双击(间隔小于0.5秒)
if(_g_time - actor.tempNum < 0.5) {
// 执行交换逻辑
let unit = actor.unit;
let targetUnit = GetSpellTargetUnit();
if(IsHandle(targetUnit)) {
UnitAddItem(targetUnit, actor.item);
}
}
actor.tempNum = null;
}
}
});
}
}
3.2 Buff状态管理
// 创建一个持续性Buff状态
ActorTypeUtil.registerActorType({
id: "持续回血Buff",
class: "Buff",
// 创建时触发
onCreated: (actor) => {
// 设置持续时间
actor.set("dur", 10);
// 设置间隔
actor.setTimerInterval(1);
},
// 间隔触发
onInterval: (actor) => {
// 每秒恢复生命值
let unit = actor.unit;
if(IsHandle(unit)) {
SetUnitState(unit, UNIT_STATE_LIFE,
GetUnitState(unit, UNIT_STATE_LIFE) + 100);
}
}
});
3.3 物品状态管理
// 创建一个可升级物品状态
ActorTypeUtil.registerActorType({
id: "升级物品",
class: "物品",
// 物品属性
level: 1,
maxLevel: 5,
// 使用物品时触发
onAction: (actor) => {
if(actor.get("level") < actor.get("maxLevel")) {
// 升级物品
actor.set("level", actor.get("level") + 1);
// 更新属性
actor.attribute = {
attack: 100 * actor.get("level")
};
}
}
});
3.4 单位状态管理
// 创建一个单位状态
ActorTypeUtil.registerActorType({
id: "英雄单位",
class: "单位",
// 单位属性
maxLife: 1000,
maxMana: 500,
// 创建时触发
onCreated: (actor) => {
// 初始化单位属性
SetUnitState(actor.unit, UNIT_STATE_MAX_LIFE, actor.get("maxLife"));
SetUnitState(actor.unit, UNIT_STATE_MAX_MANA, actor.get("maxMana"));
},
// 单位升级时触发
onUnitLevelUp: (actor) => {
// 升级时增加属性
actor.set("maxLife", actor.get("maxLife") + 100);
actor.set("maxMana", actor.get("maxMana") + 50);
}
});
3.5 UI状态管理
// 创建一个UI状态
ActorTypeUtil.registerActorType({
id: "物品UI",
class: "物品",
// UI相关属性
icon: "xxx.blp",
// 创建时触发
onCreated: (actor) => {
// 创建UI框架
let frame = actor.getRootFrameControl();
frame.setIcon(actor.get("icon"));
},
// 状态改变时触发
onUpdate: (actor) => {
// 更新UI显示
let frame = actor.getRootFrameControl();
frame.setText(actor.getName());
}
});
4. 状态系统的特点
- 状态隔离
- 每个状态独立管理
- 避免状态之间的相互干扰
- 事件驱动
- 通过事件触发状态变化
- 方便响应游戏中的各种变化
- 数据同步
- 确保多个玩家之间的状态同步
- 处理网络延迟问题
- UI集成
- 与UI系统紧密集成
- 自动更新界面显示
5. 使用建议
- 状态定义
- 清晰定义状态的属性和行为
- 避免状态之间的耦合
- 事件处理
- 合理使用事件系统
- 注意事件的触发顺序
- 性能优化
- 避免频繁的状态更新
- 合理使用缓存机制
- 调试支持
- 添加必要的日志
- 方便问题定位
通过状态系统,你可以更好地管理游戏对象的生命周期和行为,使代码更加清晰和易于维护。
我来详细介绍工具(Util)类的使用。
工具(Util)类详细介绍
1. 主要工具类
1. ActorUtil - 通用演员工具类
2. ActorAbilityUtil - 技能工具类
3. ActorBuffUtil - Buff工具类
4. ActorItemUtil - 物品工具类
5. ActorUnitUtil - 单位工具类
6. ActorFrameUtil - UI框架工具类
7. ActorTypeUtil - 演员类型工具类
2. 常用工具类详解
2.1 ActorUtil (通用演员工具)
// 获取单位所有演员列表
let actors = ActorUtil.getUnitAllActorList(unit);
// 遍历单位所有演员
ActorUtil.forUnitAllActorList(unit, (actor) => {
// 处理每个演员
});
// 判断单位是否拥有某个演员
if(ActorUtil.isUnitHasActor(unit, "演员ID")) {
// ...
}
// 获取单位所有演员属性
let attributes = ActorUtil.getUnitAllActorAttributes(unit);
2.2 ActorItemUtil (物品工具)
// 创建演员物品
let item = ActorItemUtil.createActorItem("物品ID", x, y);
// 给单位添加演员物品
let actorItem = ActorItemUtil.addActorItemForUnit("物品ID", unit);
// 获取单位指定类型的演员物品列表
let items = ActorItemUtil.getUnitActorItemList(unit, "物品ID");
// 判断单位是否拥有某个演员物品
if(ActorItemUtil.isUnitHasActorItem(unit, "物品ID")) {
// ...
}
2.3 ActorBuffUtil (Buff工具)
// 添加Buff
let buff = ActorBuffUtil.addActorBuff(unit, "BuffID", creator);
// 获取单位的Buff
let buff = ActorBuffUtil.getUnitActorBuff(unit, "BuffID");
// 清除单位的Buff
ActorBuffUtil.clearUnitActorBuff(unit, "BuffID");
// 清除单位所有Buff
ActorBuffUtil.clearUnitActorBuffs(unit);
// 添加Buff事件监听
ActorBuffUtil.addAnyActorBuffCreatedListener((buff) => {
// 处理Buff创建事件
});
2.4 ActorTypeUtil (类型工具)
// 注册演员类型
ActorTypeUtil.registerActorType({
id: "自定义类型",
name: "测试类型",
class: "物品",
// ... 其他属性
});
// 获取演员类型
let actorType = ActorTypeUtil.getActorType("类型ID");
// 遍历所有演员类型
ActorTypeUtil.forAllActorTypes((actorType) => {
// 处理每个类型
});
// 从基础物品注册演员类型
ActorTypeUtil.registerActorTypeFromBaseItemType("物品ID", {
// 额外属性
});
2.5 ActorFrameUtil (UI工具)
// 显示提示文本
ActorFrameUtil.showTipText(actor, "提示信息", 1.0);
// 显示警告文本
ActorFrameUtil.showWarnText(actor, "警告信息");
// 显示成功文本
ActorFrameUtil.showSuccessText(actor, "成功信息");
// 显示工具提示
ActorFrameUtil.showTooltip(actor);
3. 实际应用示例
3.1 物品升级系统
// 创建可升级物品
function createUpgradeableItem(itemId: string, unit: unit) {
// 创建物品
let item = ActorItemUtil.createActorItem(itemId, 0, 0);
// 添加到单位
UnitAddItem(unit, item.item);
// 设置初始属性
item.attribute = {
attack: 100,
level: 1
};
return item;
}
// 升级物品
function upgradeItem(item: ActorItem) {
let level = item.attribute.level + 1;
item.attribute = {
attack: 100 * level,
level: level
};
}
3.2 Buff管理系统
// Buff管理器
class BuffManager {
// 添加Buff
static addBuff(unit: unit, buffId: string) {
// 检查是否已有此Buff
let existBuff = ActorBuffUtil.getUnitActorBuff(unit, buffId);
if(existBuff) {
// 刷新持续时间
existBuff.update();
return;
}
// 添加新Buff
ActorBuffUtil.addActorBuff(unit, buffId);
}
// 清理过期Buff
static cleanExpiredBuffs(unit: unit) {
ActorBuffUtil.forUnitActorBuffs(unit, (buff) => {
if(buff.getRemainingTime() <= 0) {
buff.destroy();
}
});
}
}
3.3 物品交换系统
// 物品交换助手
class ItemExchangeHelper {
// 交换两个单位的物品
static exchangeItems(unit1: unit, unit2: unit, itemId: string) {
// 获取物品
let items1 = ActorItemUtil.getUnitActorItemList(unit1, itemId);
let items2 = ActorItemUtil.getUnitActorItemList(unit2, itemId);
// 执行交换
if(items1 && items1.length > 0) {
UnitAddItem(unit2, items1[0].item);
}
if(items2 && items2.length > 0) {
UnitAddItem(unit1, items2[0].item);
}
}
}
4. 使用建议
- 选择合适的工具类
- 优先使用 ActorUtil 处理通用逻辑
- 特殊需求使用专门的工具类
- 性能考虑
- 避免频繁创建和销毁对象
- 合理使用缓存机制
- 错误处理
- 添加必要的参数检查
- 处理异常情况
- 代码组织
- 按功能模块组织代码
- 保持代码清晰简洁
工具类提供了丰富的功能来简化开发,合理使用可以大大提高开发效率。
我来详细介绍属性(Attribute)系统的使用。
属性(Attribute)系统详细介绍
1. 基本概念
属性系统主要包含三个部分:
// 1. 基础属性接口
interface SolarAttribute {
attack?: number; // 攻击力
armor?: number; // 护甲
maxLife?: number; // 最大生命
maxMana?: number; // 最大魔法
strength?: number; // 力量
agility?: number; // 敏捷
intelligence?: number; // 智力
// ... 其他属性
}
// 2. 大数值属性支持
// BigAttributeCompatibleState.ts - 处理超过魔兽默认上限的属性值
// 3. 属性UI显示
// BigAttributeUICompatibleState.ts - 处理大数值的UI显示
2. 主要功能
2.1 基础属性设置
// 设置物品类型属性
AttributeUtil.setItemTypeAttribute("神圣剑", {
attack: 100,
armor: 10,
strength: 20
});
// 设置单位属性
AttributeUtil.setUnitAttribute(unit, {
maxLife: 1000,
maxMana: 500
});
// 设置Buff属性
AttributeUtil.setBuffAttribute(buff, {
attack: 50,
agility: 30
});
2.2 大数值支持
// 开启大数值支持
new BigAttributeCompatibleState();
// 设置超大数值
SetPlayerState(player, PLAYER_STATE_RESOURCE_GOLD, 999999999);
SetUnitState(unit, UNIT_STATE_MAX_LIFE, 100000000);
// 获取真实属性值
let realGold = GetPlayerState(player, PLAYER_STATE_RESOURCE_GOLD);
let realLife = GetUnitState(unit, UNIT_STATE_MAX_LIFE);
2.3 属性UI显示
// 开启大数值UI支持
new BigAttributeUICompatibleState();
// 配置UI显示
BigAttributeUICompatibleState.config = {
isShowGreenAttack: false, // 是否显示绿字攻击力
isShowGreenArmor: false // 是否显示绿字护甲
};
3. 实际应用示例
3.1 创建带属性的物品
// 注册物品类型
ActorTypeUtil.registerActorType({
id: "力量之剑",
name: "力量之剑",
class: "武器",
// 设置基础属性
onCreated: (actor) => {
actor.attribute = {
attack: 100,
strength: 20
};
},
// 升级时增加属性
onLevelUp: (actor) => {
let level = actor.level;
actor.attribute = {
attack: 100 * level,
strength: 20 * level
};
}
});
3.2 属性叠加系统
// 创建属性叠加管理器
class AttributeStackManager {
// 叠加属性
static stackAttribute(unit: unit, attribute: SolarAttribute) {
let currentAttr = AttributeUtil.getUnitAttribute(unit, true);
// 叠加各项属性
AttributeUtil.add(currentAttr, attribute);
// 刷新单位属性
UnitAttributeState.refreshUnitSolarAttribute(unit);
}
// 移除属性
static removeAttribute(unit: unit, attribute: SolarAttribute) {
let currentAttr = AttributeUtil.getUnitAttribute(unit);
// 移除属性
AttributeUtil.subtract(currentAttr, attribute);
// 刷新单位属性
UnitAttributeState.refreshUnitSolarAttribute(unit);
}
}
3.3 Buff属性系统
// 创建属性Buff
ActorTypeUtil.registerActorType({
id: "力量Buff",
class: "Buff",
// 设置Buff属性
onCreated: (actor) => {
actor.attribute = {
strength: 50
};
// 设置持续时间
actor.set("dur", 10);
},
// Buff层数变化时
onLevelChange: (actor, delta) => {
// 根据层数调整属性
actor.attribute = {
strength: 50 * actor.level
};
}
});
3.4 装备属性系统
// 装备属性管理器
class EquipmentAttributeManager {
// 装备物品
static equipItem(unit: unit, item: ActorItem) {
// 获取物品属性
let itemAttr = item.attribute;
if(!itemAttr) return;
// 应用装备属性
let unitAttr = AttributeUtil.getUnitAttribute(unit, true);
AttributeUtil.add(unitAttr, itemAttr);
// 刷新属性
UnitAttributeState.refreshUnitSolarAttribute(unit);
}
// 卸下物品
static unequipItem(unit: unit, item: ActorItem) {
let itemAttr = item.attribute;
if(!itemAttr) return;
// 移除装备属性
let unitAttr = AttributeUtil.getUnitAttribute(unit);
AttributeUtil.subtract(unitAttr, itemAttr);
// 刷新属性
UnitAttributeState.refreshUnitSolarAttribute(unit);
}
}
4. 使用建议
- 属性定义
- 明确定义需要的属性类型
- 合理设置属性值范围
- 大数值处理
- 需要大数值时开启相应支持
- 注意性能影响
- 属性计算
- 使用工具类进行属性计算
- 注意属性叠加顺序
- UI显示
- 合理配置UI显示方式
- 处理数值格式化
- 性能优化
- 避免频繁的属性计算
- 合理使用缓存机制
属性系统是游戏中的重要组成部分,合理使用可以实现复杂的属性计算和效果。通过与其他系统(如演员系统、状态系统)的配合,可以实现更加丰富的游戏功能。
其他重要且常用的模块
1. 事件系统 (Solar Event System)
// 使用示例
se.onUnitDeath((e) => {
// 单位死亡事件处理
});
se.playerChat("command", () => {
// 玩家聊天命令处理
});
这是一个统一的事件分发系统,用于处理游戏中的各种事件。
2. 数据管理系统 (DataBase)
// 使用示例
let solarData = DataBase.getUnitSolarData(unit);
let playerData = DataBase.getPlayerSolarData(player);
用于管理和存储游戏对象(单位、玩家等)的数据。
3. UI框架系统
// 使用示例
class MyUI {
constructor() {
// 创建UI元素
let frame = Frame.createTEXTBUTTON();
frame.setText("按钮文本");
frame.setSize(0.1, 0.02);
// 设置点击事件
frame.setOnClick(() => {
// 处理点击事件
});
}
}
提供了丰富的UI创建和管理功能。
4. 存档系统 (Archive System)
// 使用示例
ArchiveUtil.set(player, "key", value);
let data = ArchiveUtil.get(player, "key");
用于处理游戏存档和读档功能。
5. 同步系统 (Sync System)
// 使用示例
SyncUtil.syncData("eventName", data);
SyncUtil.onSyncData("eventName", (player, data) => {
// 处理同步数据
});
处理多人游戏中的数据同步。
6. 基础工具类 (BaseUtil)
// 使用示例
BaseUtil.runLater(1.0, () => {
// 延迟执行
});
BaseUtil.onTimer(1.0, () => {
// 定时执行
return true;
});
提供了大量常用的工具方法。
7. 伤害系统 (Damage System)
// 使用示例
SolarDamageState.addEventHandler(event => {
// 处理伤害事件
if(event.isAttack) {
// 处理攻击伤害
}
});
处理游戏中的伤害计算和效果。
8. 玩家系统 (Player System)
// 使用示例
PlayerUtil.forUsers(player => {
// 处理每个玩家
});
PlayerUtil.addGoldState(player, amount);
提供了玩家相关的功能。
这些模块在项目中经常配合使用,例如:
// 综合使用示例
class GameSystem {
constructor() {
// 注册事件
se.onUnitDeath((e) => {
// 获取数据
let unitData = DataBase.getUnitSolarData(e.trigUnit);
let playerData = DataBase.getPlayerSolarData(e.trigUnitOwner);
// 更新属性
AttributeUtil.setUnitAttribute(e.trigUnit, {
attack: 100,
armor: 10
});
// 同步数据
SyncUtil.syncData("unitDeath", {
unit: e.trigUnit,
player: e.trigUnitOwner
});
// 存档
ArchiveUtil.set(e.trigUnitOwner, "deathCount",
(ArchiveUtil.get(e.trigUnitOwner, "deathCount") || 0) + 1);
});
}
}
这些模块都是紧密关联的,共同构成了一个完整的游戏开发框架。每个模块都有其特定的职责,但又能很好地协同工作。选择使用哪些模块主要取决于具体的游戏需求。