Skip to content

脚本基础

这篇文档假定您对编程没有一点基础,逐步描述下跟 引.故事 有关的概念和知识。 若您已经掌握 JavaScript ,则可直接观看 引.Object 拓展

脚本语言

引.故事 依赖 引.Object 进行构建,脚本语言采用 JavaScript。 我们尽可能减低系统使用脚本的复杂度,使您可以仅通过了解下面的几个基础概念,就可以上手编写脚本。

什么是脚本?

计算机就是根据脚本中的一条一条指令运行的,就比如下面这段脚本:

代码中的注释

脚本中//之后灰色的内容就是对脚本下一行指令的注释说明,注释不是必须的,也不会被当作指令执行。

js
// 设置三个变量:资产=52.99万,颜值=999999999999,柳如烟的爱=假
let money = 529900, faceScore = 999999999999, liuruyanslove = false
// 如果资产+颜值>100000000
if (money + faceScore > 100000000) {
    // 柳如烟的爱=真
    liuruyanslove = true
}
else {
    // 柳如烟的爱=假
    liuruyanslove = false
}

计算机会根据脚本中的指令逐条执行,当执行结束,程序也就结束。

什么是对象(Object)?

对象就是一堆数据(例如变量)或功能的集合,就比如下面这段脚本:

js
// 创建一个叫 我 的对象:我包含多个键值
let me = {
    title: '小明',
    money: 529900, // 资产
    faceScore: 999999999999, // 颜值
    cp: 500, // 武力值
    mate: null // 伴侣为空
}

// 再创建一个叫 NPCList 的数组,数组中包含两个NPC
let NPCList = [
    {
        title: '柳如烟',
        money: 10000000,
        faceScore: 99999999999,
        cp: 10000
    },
    {
        title: '如花',
        money: 300,
        faceScore: 5,
        cp: 9999999999 //战力崩坏!!
    }
]


// 如果 我的资产 + 我的颜值 > 100000000
if (me.money + me.faceScore > 100000000) {
    // 我的伴侣 = 柳如烟
    me.mate = '柳如烟'

    // 下面为可选代码片段
    // 柳如烟在 NPCList 中的第 0 个(数组从 0 开始查)
    // 在编程中我们更多的是使用数组的第几个值
    me.mate = 0
    // 或者具体的值
    me.mate = NPCList[0]
}
// 如果 我的资产 + 我的颜值 > 100000000 不成立
else {
    // 我的伴侣 = 空
    me.mate = null
}

// 此时,如花开始横刀夺爱并强制成为我的伴侣
// 创建一个叫 如花 的变量,这个变量的值从 NPCList 数组的第 1 个数据取值(数组从 0 开始查)
// 如花就是 NPCList 的第 1 个数据
let ruhua = NPCList[1]

// 如果 我的伴侣为空
if (me.mate === null) {
    // 如果 我的武力值 < 如花的武力值
    if (me.cp < ruhua.cp) {
        // 我的伴侣 = 如花
        me.mate = '如花'
    }
}
// 如果 我的伴侣为空 不成立
else {
    // 创建一个叫 伴侣 的变量,暂时不给 伴侣 赋值
    let mate
    // 柳如烟就是 NPCList 的第 0 个数据
    // 伴侣 的值从 NPCList 数组的第 0 个数据取值(数组从 0 开始查)
    mate = NPCList[0]

    // 下面为可选代码片段
    // 如果在上面的可选代码片段中使用数组的第几个值 - me.mate = 0
    // 则变量 伴侣 可以从 NPCList 数组的第 我的伴侣的值 个数据取值
    mate = NPCList[me.mate]
    // 如果在上面的可选代码片段中使用具体的值 - me.mate = NPCList[0]
    // 则变量 伴侣 可直接从 我的伴侣 取值
    mate = me.mate
    // 在编程中我们更多使用可选代码片段的写法,这样可以支持更多的伴侣,而不是指定柳如烟


    // 如果 我的武力值 + 伴侣(柳如烟)的武力值 < 如花的武力值
    if (me.cp + mate.cp < ruhua.cp) {
        // 我的伴侣 = 如花 👍
        me.mate = '如花'
    }
}

什么是函数(Function)?

函数就是一段脚本的合集,就比如上面 什么是对象 中判断伴侣的脚本,我们就可以将他封装成一个函数,以供重复调用。

在本系统中,函数通常挂载在对象中,所以我们只用这种情况进行举例。

javascript
// 创建一个叫 我 的对象:我包含多个键值
let me = {
    title: '小明',
    money: 529900, // 资产
    faceScore: 999999999999, // 颜值
    cp: 500, // 武力值
    mate: null, // 伴侣为空
    /**
     * 让一个 npc 成为我的伴侣
     * @param npc 角色 - 输入量为一个角色
     * @return {Object|null}  输出量为当前伴侣或空
     */
    beMyMate(npc) {
        let ruhua = NPCList[1]

        // 如果当前已有伴侣,且伴侣不为 如花 
        // 注:当函数挂载于对象之中(此时的情况和函数写法),在本函数中可用 this 代指所挂载的对象 me
        if (this.mate !== null && this.mate !== ruhua) {
            // 则不能变更伴侣,并返回当前伴侣为输出量
            return this.mate
            // 此时函数结束运行,后续脚本都不再运行
        }

        // 如果 我的资产 + 我的颜值 > 角色的资产 + 角色的颜值
        if (this.money + this.faceScore > npc.money + npc.faceScore) {

            // 如果 我的武力值 + 角色的武力值 >= 如花的武力值
            if (this.cp + npc.cp >= ruhua.cp) {
                // 我的伴侣 = npc
                this.mate = npc
                // 返回 npc 作为输出量
                return npc
                // 此时函数结束运行,后续脚本都不再运行
            }
        }
        // 如果 我的资产 + 我的颜值 > 角色的资产 + 角色的颜值 不成立
        // 但是 如果 我的武力值 >= 如花的武力值
        else if (this.cp >= ruhua.cp) {

            // 摆脱 如花 的束缚,伴侣清空
            this.mate = null
            // 返回一个空值作为输出量
            return null
            // 此时函数结束运行,后续脚本都不再运行
        }


        // 若函数运行至此处,则 如花 强制绑定为伴侣
        this.mate = ruhua
        // 返回 角色 如花 作为输出量
        return ruhua
    }
}

引.Object 拓展

引.故事 的核心依赖 引.Object 进行构建,其中的数据对象基于 JavaScript 原生对象进行了一些拓展,使其具备了持久化热同步等特性。 同时也使子对象和数组的获取发生了一些变化。

由于持久化,引.Object 为每个对象分配了地址,对象地址在对象面板点开的第二行,点击地址即可复制,或者右键对象 引用,也会复制对象地址。

例如 片头 的地址就是 Element.6964ae79ef23ebc0858e8de3

引 的 对象

我们可以为数据对象绑定脚本来为其增加功能,点击编辑器中脚本的加号可以为数据对象创建并绑定脚本, 此时编辑器会为该脚本创建 JSDoc 用于代码提示。

下面以 引.故事 的一个事件脚本的显示判定为例,进行说明:

js
// 一个事件对象的脚本
export default {
    // 事件显示判定
    async show(save) {
        // 获取 本事件 的 目标场景
        const scene = await this.target

        // 通过地址获取 目标场景,点开对象后在第二行查看
        const target = await this._yin.get('Element.6964ae79ef23ebc0858e8de3')

        // 获取 目标场景 的 事件列表
        const events = await target.events
        // 获取完整列表
        await events.all()


        save.data.somevalue = 123
        // 保存 存档
        await save._save()

        // 保存 本事件,由于玩家没有 本事件 的管理权限,此处会报错。
        await this._save()
    }
}

恭喜看完

至此,为 引.故事 编写脚本的所有基础知识已经学完,下一篇教您具体如何操作。