Skip to content

状态

角色的各项属性(生命、体力、理智、经验、称号等)通过状态(Status)来描述。你可以在 game.config.ts 中预先声明,然后在游戏中通过简单的 API 来读取或修改它们,这些值会实时反映在界面上方的状态栏与菜单页中。

状态支持两种值类型:number(数值型,如生命值、力量)和 string(字符串型,如称号、阵营)。两种类型可以在同一个组内混合使用。每个状态在定义时通过 default 字段的值自动确定其类型,之后不可更改——TypeScript 会在编译期检查类型错误,运行时也会进行校验。

注意:所有状态的 id 必须全局唯一。即使你按组将它们分开,不同 ADVUserStatusGroup 内部的属性 id 也不能重复,否则会造成运行时错误。

声明状态

你可以在 game.config.tsconfig 变量中新增 status 字段。该字段是一个对象,每一个顶层的 key 都是一个 状态组,用于将相关属性归类(例如“战斗属性”、“生存状态”等)。

typescript
export default Adv.defineConfig({
    // ... 其他配置
    status: {
        base: {
            name: '基础属性',
            content: {
                hp: {
                    name: '生命值',
                    max: 100,
                    default: 100,
                    color: '#d32f2f',
                    isDisplay: 'process',
                },
                sp: {
                    name: '体力',
                    max: 50,
                    default: 50,
                    color: '#388e3c',
                    isDisplay: 'process',
                },
            },
        },
        mental: {
            name: '精神状态',
            content: {
                sanity: {
                    name: '理智',
                    max: 100,
                    min: 0,
                    default: 80,
                    color: '#7b1fa2',
                    isDisplay: 'process',
                },
            },
        },
        info: {
            name: '个人信息',
            content: {
                title: {
                    name: '称号',
                    default: '新手冒险者', // 字符串类型 — 由 default 值自动推断
                    color: '#e3960c',
                    isDisplay: 'text',
                },
                faction: {
                    name: '阵营',
                    default: '中立',
                    isDisplay: 'hide', // 字符串类型也可以设为 hide
                },
            },
        },
    },
});
  • 外层的 basementalinfo 是组 ID,用于逻辑上的分组管理,不会暴露给玩家。
  • 每组都有一个可选的 name,它会在状态总览页面中作为小标题展示。
  • content 里存放的就是真正会被用到的一个个状态属性。number 和 string 类型可以在同一组内混合。
  • 状态的值类型由 default 字段自动推断:写数字就是 number 型,写字符串就是 string 型。一经确定,不可更改

状态属性的配置项

每个状态属性使用 ADVUserStatus 对象配置,它的各项说明如下:

参数名类型默认值描述
namestring可选。属性显示给玩家的名字,如 "生命值"。不填则为 id。
maxnumberInfinity属性的最大值。设置后,界面上会以进度条或数字的形式体现上限。仅对 number 型状态生效
minnumber0属性的最小值。设定后,值不会降低到该值以下。仅对 number 型状态生效
defaultnumber | string必填游戏开始时该属性的初始值。类型决定了该状态的永久类型:写数字则为 number 型,写字符串则为 string 型,之后不可混用。
colorstring() => string'black'显示时的强调色,用于进度条填充和数字/文字颜色。可以传入固定颜色字符串(如 '#d32f2f'),或一个返回颜色字符串的函数,实现动态变色。
isDisplay'none''hide''text''process' 或返回它们的函数'hide'控制该属性如何在界面上展示。详见下表。

显示类型 (isDisplay) 详解

效果
'text'在顶部状态栏靠右显示。number 型会带数字动画和 / max 后缀;string 型直接显示文字。
'process'除数字外,还以进度条形式展示在状态栏靠左,视觉上更直观地体现当前值与最大值的比例。仅适用于 number 型
'hide'在顶部的状态栏中隐藏该属性,但在菜单中的状态总览页面里仍然可见,适合展示一些相对次要但偶尔需要查看的属性。
'none'完全不在任何界面显示,适合作为纯粹的幕后数值(如隐藏好感度、成就计数等)。

isDisplay 也可以是一个函数,返回上述四种字符串之一,从而使显示方式根据游戏状态动态切换。例如受伤后原本隐藏的“伤口感染度”突然显示为进度条。

读取与修改状态值

游戏运行时,你可以通过 Adv.status 来读取或修改任意状态属性。

类型安全

状态的值类型在定义 default 时即已锁定。TypeScript 会在编译期为每个 status key 提供精确的类型推导,赋错类型会直接报编译错误。同时,运行时也会进行校验(错误码 106 / 107)。

typescript
Adv.status.hp = 10; // ✅ OK — hp 是 number 型
Adv.status.hp = '满血'; // ❌ 编译错误 + 运行时错误(107)

Adv.status.title = '屠龙者'; // ✅ OK — title 是 string 型
Adv.status.title = 0; // ❌ 编译错误 + 运行时错误(106)

读取当前值

typescript
// number 型 — 返回 number
const currentHp: number = Adv.status.hp; // 80

// string 型 — 返回 string
const currentTitle: string = Adv.status.title; // '新手冒险者'

修改 number 型状态

直接赋值即可更新状态,值会被自动限制在 minmax 之间。界面会自动刷新。

typescript
// 恢复全部生命
Adv.status.hp = 100;

// 受到伤害,减少 15 点生命
Adv.status.hp -= 15;

// 值自动钳制:若 min=0,则不会低于 0
Adv.status.hp = -10; // 实际存储为 0

修改 string 型状态

string 型状态直接赋值覆盖,不涉及 max/min 限制与数值累加。

typescript
Adv.status.title = '屠龙勇士';
Adv.status.faction = '混乱邪恶';

在回调中使用

你可以在场景的 onEnter、对话的 onStart,或者选项与检定的回调函数中自由使用这些读写操作:

typescript
Adv.appendScene('trap-room', {
    name: '陷阱房间',
    next: 'trap-dialog',
    onEnter: () => {
        // number 型:进入此房间自动扣除体力
        Adv.status.sp -= 10;
    },
});

Adv.appendScene('title-grant', {
    name: '授勋大殿',
    next: 'title-dialog',
    onEnter: () => {
        // string 型:进入此场景自动更新称号
        Adv.status.title = '王国勇士';
    },
});