Персонажи
Как определять, использовать и настраивать персонажей в Pixi’VN, включая хранение, эмоции и пользовательские свойства.
Что такое characters? Персонажи (characters) — это актёры, которые появляются в визуальной новелле. В Pixi’VN персонажи создаются с помощью класса CharacterBaseModel или пользовательского класса.
Инициализация
Чтобы инициализировать персонажа, создайте новый экземпляр класса CharacterBaseModel (или вашего пользовательского класса) и добавьте его в словарь персонажей игры при инициализации игры.
Рекомендуется импортировать экземпляры при запуске проекта.
RegisteredCharacters.add обязателен для сохранения персонажей в игре.
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]);Получить
Чтобы получить персонажа по его 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
Этот метод можно использовать с синтаксисом ink. Подробнее здесь.
Вы можете использовать игрового персонажа, например, чтобы связать его с текущим диалогом. Можно использовать id персонажа или экземпляр персонажа, но рекомендуется использовать экземпляр.
import { liam } from "@/content/characters";
narration.dialogue = { character: liam, text: "Hello" };
// or
narration.dialogue = { character: "liam_id", text: "Hello" };Редактировать
ink
Этот метод можно использовать с синтаксисом ink. Подробнее здесь.
CharacterBaseModel является сохраняемым классом, что означает, что его свойства сохраняются в хранилище игры. Например, если вы изменяете имя персонажа во время игры, новое имя будет сохранено в хранилище игры и привязано к его id.
Если id персонажа изменяется от одной версии к другой, система не перенесёт данные, привязанные к предыдущему id, к новому id.
Чтобы получить свойства, использованные при инстанциировании класса, можно использовать свойства default.
Вот упрощённая реализация класса CharacterBaseModel для лучшего понимания свойств, хранящихся в хранилище игры:
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("name", value);
}
// icon property is not stored in the game storage
icon: string = "";
// ...
}Эмоции персонажей
ink
Этот метод можно использовать с синтаксисом ink. Подробнее здесь.
Зачастую бывает полезно иметь несколько разновидностей одного и того же персонажа. Например, персонаж «Alice» и подтип, связанный с её эмоциональным состоянием, например «Злая Alice». Персонаж и подтип имеют одинаковые характеристики, за исключением одного или нескольких свойств, таких как иконка.
В Pixi’VN можно создать «персонажа с эмоцией», передав объект вместо id:
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Пользовательский класс
Шаблоны
Во всех шаблонах класс Character уже определён в файле models/Character.ts. Вы можете использовать его напрямую или изменить под свои нужды.
Рекомендуется создать собственный класс Character, который расширяет CharacterStoredClass и «переопределяет» интерфейс CharacterInterface для добавления, редактирования или удаления свойств или методов.
Например, если вы хотите создать класс Character, необходимо «переопределить» интерфейс CharacterInterface для использования ваших свойств или методов. (См. файл pixi-vn.d.ts)
Теперь можно создать класс Character, расширяющий CharacterStoredClass и реализующий CharacterInterface. (Дополнительную информацию о создании классов в TypeScript можно найти в официальной документации)
Чтобы создать свойство, хранящее своё значение в хранилище игры, можно создать Геттеры/Сеттеры и использовать методы 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("name", value);
}
private defaultSurname?: string;
get surname(): string | undefined {
return (
this.getStorageProperty<string>("surname") || this.defaultSurname
);
}
set surname(value: string | undefined) {
this.setStorageProperty("surname", value);
}
private defaultAge?: number | undefined;
get age(): number | undefined {
return this.getStorageProperty<number>("age") || this.defaultAge;
}
set age(value: number | undefined) {
this.setStorageProperty("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;
}