无名杀(libnoname/noname)异步技能开发指南
noname 项目地址: https://gitcode.com/gh_mirrors/nona/noname
前言
在无名杀游戏开发中,技能效果的实现一直是核心功能之一。随着JavaScript语言的发展,无名杀从v1.10.6版本开始引入了一种基于async/await的全新技能效果编写方式,这极大地提升了代码的可读性和可维护性。本文将全面介绍这种异步技能开发方法,帮助开发者更好地理解和运用这一技术。
异步技能基础概念
1. 传统技能写法 vs 异步技能写法
传统技能写法(Step Content):
let skill = {
content: function() {
"step 0"
player.draw(2);
"step 1"
player.chooseToDiscard(2, true);
}
}
异步技能写法(Async Content):
let skill = {
content: async function(event, trigger, player) {
await player.draw(2);
await player.chooseToDiscard(2, true);
}
}
2. 异步技能的核心优势
- 代码结构更清晰:消除了"step"标记,代码更接近原生JavaScript
- 调试更方便:避免了动态编译导致的调试困难
- 功能更强大:可以轻松实现传统写法难以完成的功能
- 维护性更好:符合现代JavaScript开发规范
深入理解Async/Await
1. async函数基础
async函数是ES2017引入的异步编程解决方案,具有以下特点:
- 函数声明前必须加
async
标识符 - 函数内部可以使用
await
关键字 - 函数返回值会被自动包装成Promise对象
2. await的工作原理
await
关键字用于等待一个Promise对象的状态变化:
- 如果等待的值不是Promise,会直接返回该值
- 如果等待的是Promise,会暂停函数执行直到Promise状态改变
- 对于无名杀中的事件,
await
会等待事件完成并返回事件对象
异步技能开发实践
1. 基本技能实现
以一个简单的摸牌弃牌技能为例:
let skill = {
trigger: {
player: "phaseBegin"
},
content: async function(event, trigger, player) {
// 摸两张牌
await player.draw(2);
// 如果手牌大于5张,弃两张牌
if (player.countCards("h") > 5) {
await player.chooseToDiscard(2, true);
}
}
}
2. 获取事件结果
在异步写法中,可以通过以下方式获取事件结果:
// 方法1:使用forResult
let cards = await player.draw(2).forResult();
// 方法2:解构赋值
let { result: cards } = await player.draw(2);
// 方法3:直接获取事件对象
let drawEvent = await player.draw(2);
let cards = drawEvent.result;
3. 流程控制替代方案
传统写法中的流程控制方法在异步写法中有对应的替代方案:
| 传统写法 | 异步写法替代方案 | |---------|----------------| | event.finish() | return | | event.goto(n) | if/while/for等流程控制语句 | | event.redo() | 循环语句 |
高级技巧与最佳实践
1. 何时使用await
在无名杀开发中,以下情况需要使用await:
- 会触发游戏时机的事件
- 需要玩家确认的操作
- 以async开头的函数(如asyncDraw)
- 游戏延迟(game.delay/delayx)
2. Promise的高级应用
Promise可以用于实现复杂的异步逻辑:
// 创建一个等待玩家点击的Promise
let { promise, resolve } = Promise.withResolvers();
button.listen(() => {
resolve(); // 玩家点击后解除等待
game.log("按钮被点击");
});
await promise; // 等待玩家点击
3. 闭包访问优势
异步写法支持闭包访问,可以更方便地管理变量:
function createSkill() {
let privateData = "秘密数据";
return {
content: async function() {
// 可以直接访问外层变量
game.log(privateData);
await player.draw(1);
}
};
}
异步技能与其他写法的对比
1. 与传统Step Content对比
优势:
- 代码更清晰易读
- 调试更方便
- 支持闭包访问
- 更符合现代JavaScript标准
2. 与Generator Content对比
虽然Generator Content也能实现类似功能,但Async Content具有以下优势:
- 语法更简洁
- 生态支持更好
- 可await的范围更广
3. 与Array Content的关系
在v1.10.15版本后,Async Content和Step Content在运行时会被封装为Array Content,这种设计提供了更好的生命周期管理。
开发建议与注意事项
- 避免在return后跟可await的值:这可能导致函数无法正常结束
- 合理使用await:不需要await的操作可以省略以提升性能
- 善用Promise:对于复杂异步逻辑,Promise是强大工具
- 保持代码简洁:利用现代JavaScript特性简化代码
- 逐步迁移:可以先将简单技能改为异步写法,逐步积累经验
结语
异步技能写法代表了无名杀未来的开发方向,它不仅使代码更加清晰易维护,还能实现更复杂的技能效果。作为开发者,掌握这一技术将大大提升开发效率和代码质量。希望本文能帮助你顺利过渡到异步技能开发模式,创造出更精彩的游戏内容。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考