LogoPixi’VN

Персонажи

Как определить, использовать и настраивать персонажей в Pixi’VN, включая сохранение, эмоции и пользовательские свойства.

What are characters? Characters are the actors that appear in a visual novel. В Pixi’VN персонажи создаются с использованием класса CharacterBaseModel или пользовательского класса.

Инициализация

Чтобы инициализировать персонажа, создайте новый экземпляр класса CharacterBaseModel (или вашего пользовательского класса) и добавьте его в словарь игровых персонажей, когда игра будет инициализирована.

It is recommended to import the instances at project startup, see the src/main.ts file.

Чтобы создать новый экземпляр CharacterBaseModel, вам нужны следующие параметры:

  • id: A unique identifier (string). Он используется для ссылки на персонажа в игре (должен быть уникальным). Если вы хотите создать персонажа с "эмоцией", вы можете передать объект.
  • props: Объект с свойствами персонажа:
    • name: Имя персонажа.
    • surname (Необязательно): Фамилия персонажа.
    • age (Необязательно): Возраст персонажа.
    • icon (Необязательно): URL-адрес изображения значка персонажа.
    • color (Необязательно): Цвет персонажа.
import { CharacterBaseModel, RegisteredCharacters } from "@drincs/pixi-vn";

export const liam = new CharacterBaseModel('liam', {
    name: 'Liam',
    surname: 'Smith',
    age: 25,
    icon: "https://example.com/liam.png",
    color: "#9e2e12"
});

export const emma = new CharacterBaseModel('emma', {
    name: 'Emma',
    surname: 'Johnson',
    age: 23,
    icon: "https://example.com/emma.png",
    color: "#9e2e12"
});

RegisteredCharacters.add([liam, emma]);

RegisteredCharacters.add обязательный для сохранения персонажей в игре.

Вы также можете создать функцию для загрузки персонажей. Важно, чтобы это было вызвано как минимум один раз перед использованием персонажей в игре, иначе они будут недоступны.

Get

Чтобы получить персонажа по его id, используйте функцию RegisteredCharacters.get.

import { RegisteredCharacters } from "@drincs/pixi-vn";

const liam = RegisteredCharacters.get('liam');

Получить все

Чтобы получить всех персонажей, используйте функцию RegisteredCharacters.values.

import { RegisteredCharacters } from "@drincs/pixi-vn";

const characters = RegisteredCharacters.values();

Использовать

ink

You can use this method with the ink syntax. See more here.

Вы можете использовать игрового персонажа, например, чтобы связать его с текущим диалогом. Вы можете использовать id персонажа или его экземпляр, но рекомендуется использовать экземпляр.

values/characters.ts
export const liam = new CharacterBaseModel('liam_id', {
    name: 'Liam',
    surname: 'Smith',
    age: 25,
    icon: "https://example.com/liam.png",
    color: "#9e2e12"
});
RegisteredCharacters.add([liam]);
narration.dialogue = { character: liam, text: "Hello" }
// or
narration.dialogue = { character: "liam_id", text: "Hello" }

Редактировать

ink

You can use this method with the ink syntax. See more here.

CharacterBaseModel — это сохраненный класс, что означает, что его свойства сохраняются в игровом хранилище.

Если имя персонажа изменится во время игры, новое имя будет сохранено в игровом хранилище и связано с его id.

Если идентификатор персонажа изменится с одной версии на другую, система не перенесет данные, связанные с предыдущим id, на новый id .

Свойства CharacterBaseModel, которые хранятся в игровом хранилище, следующие:

  • name: Имя персонажа.
  • surname: Фамилия персонажа.
  • возраст: Возраст персонажа.

Чтобы получить свойства, используемые при создании экземпляра класса, вы можете использовать:

  • defaultName: Имя персонажа.
  • defaultSurname: Фамилия персонажа.
  • defaultAge: Возраст персонажа.

Вот упрощенная реализация класса CharacterBaseModel для лучшего понимания свойств, которые хранятся в игровом хранилище:

CharacterBaseModel.ts
export default class CharacterBaseModel extends StoredClassModel implements CharacterBaseModelProps {
    constructor(id: string, props: CharacterBaseModelProps) {
        super(
            // ...
        )
        this.defaultName = props.name
        this.icon = props.icon
        // ...
    }

    // name property is stored in the game storage
    private defaultName: string = ""
    get name(): string {
        return this.getStorageProperty<string>("name") || this.defaultName
    }
    set name(value: string) {
        this.setStorageProperty<string>("name", value)
    }

    // icon property is not stored in the game storage
    icon: string = ""

    // ...
}

Эмоции персонажа

ink

You can use this method with the ink syntax. See more here.

Часто полезно иметь несколько типов одного и того же персонажа. Например, персонаж "Alice" и подтип, связанный с её эмоциональным состоянием, например "Раздосадованная Alice". Персонаж и подтип имеют одинаковые характеристики, за исключением одного или нескольких свойств, таких как иконка.

С помощью Pixi’VN вы можете создать "персонажа с эмоцией", передав объект вместо id, с следующими свойствами:

  • id: Идентификатор существующего персонажа.
  • emotion: Подкатегория персонажа (например, эмоция персонажа).
values/characters.ts
import { CharacterBaseModel, RegisteredCharacters } from "@drincs/pixi-vn";

export const alice = new CharacterBaseModel('alice', {
    name: 'Alice',
    icon: "https://example.com/alice.png",
    color: "#9e2e12"
});

export const angryAlice = new CharacterBaseModel({ id: 'alice', emotion: 'angry' }, {
    icon: "https://example.com/angryAlice.png",
});

RegisteredCharacters.add([alice, angryAlice]);
console.log(alice.name); // Alice

alice.name = "Eleonora";
console.log(alice.name); // Eleonora
console.log(angryAlice.name); // Eleonora

angryAlice.name = "Angry Eleonora";
console.log(alice.name); // Eleonora
console.log(angryAlice.name); // Angry Eleonora

Пользовательский класс

Templates

Во всех шаблонах класс Character уже определён в файле models/Character.ts. Вы можете использовать это напрямую или изменить его в соответствии с вашими потребностями.

Рекомендуется создать собственный класс Character, который расширяет CharacterStoredClass и "переопределяет" интерфейс CharacterInterface, чтобы добавлять, редактировать или удалять свойства или методы.

Например, если вы хотите создать класс Character, вам нужно "переопределить" интерфейс CharacterInterface, чтобы использовать свои свойства или методы. (Смотрите файл pixi-vn.d.ts)

Теперь вы можете создать класс Character, который расширяет CharacterStoredClass и реализует интерфейс CharacterInterface. (Для получения дополнительной информации о том, как создать класс в TypeScript, прочитайте официальную документацию)

Чтобы создать свойство, которое хранит свое значение в игровом хранилище, вы можете создать Getter/Setter и использовать методы this.getStorageProperty()/this.setStorageProperty(). (Смотрите файл Character.ts)

import { CharacterInterface, CharacterStoredClass } from "@drincs/pixi-vn";

export class Character extends CharacterStoredClass implements CharacterInterface {
    constructor(id: string | { id: string, emotion: string }, props: CharacterProps) {
        super(typeof id === "string" ? id : id.id, typeof id === "string" ? "" : id.emotion)
        this._icon = props.icon
        this._color = props.color
        this.defaultName = props.name
        this.defaultSurname = props.surname
        this.defaultAge = props.age
    }

    // Not stored properties
    
    readonly icon?: string;
    readonly color?: string | undefined;

    // Stored properties

    private defaultName?: string
    get name(): string {
        return this.getStorageProperty<string>("name") || this.defaultName || this.id
    }
    set name(value: string | undefined) {
        this.setStorageProperty<string>("name", value)
    }
    private defaultSurname?: string
    get surname(): string | undefined {
        return this.getStorageProperty<string>("surname") || this.defaultSurname
    }
    set surname(value: string | undefined) {
        this.setStorageProperty<string>("surname", value)
    }
    private defaultAge?: number | undefined
    get age(): number | undefined {
        return this.getStorageProperty<number>("age") || this.defaultAge
    }
    set age(value: number | undefined) {
        this.setStorageProperty<number>("age", value)
    }
}

interface CharacterProps {
    /**
     * The name of the character.
     */
    name?: string;
    /**
     * The surname of the character.
     */
    surname?: string;
    /**
     * The age of the character.
     */
    age?: number;
    /**
     * The icon of the character.
     */
    icon?: string;
    /**
     * The color of the character.
     */
    color?: string;
}