@drincs/pixi-vn
Version:
Pixi'VN is a npm package that provides various features for creating visual novels.
4,334 lines (4,259 loc) • 151 kB
JavaScript
var pixi_js = require('pixi.js');
var deepDiff = require('deep-diff');
var sha1 = require('crypto-js/sha1');
var devtools = require('@pixi/devtools');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var sha1__default = /*#__PURE__*/_interopDefault(sha1);
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __decorateClass = (decorators, target, key, kind) => {
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
for (var i = decorators.length - 1, decorator; i >= 0; i--)
if (decorator = decorators[i])
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
if (kind && result) __defProp(target, key, result);
return result;
};
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// src/classes/CanvasEvent.ts
var CanvasEvent = class {
constructor() {
/**
* Get the id of the event. This variable is used in the system to get the event by id, {@link getEventInstanceById}
*/
this.id = "event_id_not_set";
this.id = this.constructor.prototype.id;
}
fn(_event, _element) {
throw new Error("[Pixi'VN] The method CanvasEvent.fn() must be overridden");
}
};
function getStepSha1(step) {
let sha1String = sha1__default.default(step.toString().toLocaleLowerCase());
return sha1String.toString();
}
function checkIfStepsIsEqual(step1, step2) {
return step1 === step2;
}
// src/classes/LabelAbstract.ts
var LabelAbstract = class {
/**
* @param id is the id of the label
* @param props is the properties of the label
*/
constructor(id, props) {
this._id = id;
this._onStepStart = props == null ? void 0 : props.onStepStart;
this._onLoadStep = props == null ? void 0 : props.onLoadStep;
this._onStepEnd = props == null ? void 0 : props.onStepEnd;
this._choiseIndex = props == null ? void 0 : props.choiseIndex;
}
/**
* Get the id of the label. This variable is used in the system to get the label by id, {@link getLabelById}
*/
get id() {
return this._id;
}
/**
* Get the corresponding steps number
* @param externalSteps
* @returns Numer of corresponding steps, for example, if externalSteps is [ABC, DEF, GHI] and the steps of the label is [ABC, GHT], the result will be 1
*/
getCorrespondingStepsNumber(externalSteps) {
if (externalSteps.length === 0) {
return 0;
}
let res = 0;
externalSteps.forEach((step, index) => {
if (checkIfStepsIsEqual(step, this.steps[index])) {
res = index;
}
});
return res;
}
/**
* Is a function that will be executed in {@link Label#onStepStart} and when the user goes back to it or when the user laods a save file.
* @returns Promise<void> or void
*/
get onStepStart() {
return (stepIndex, label) => __async(this, null, function* () {
if (this._onLoadStep) {
yield this._onLoadStep(stepIndex, label);
}
if (this._onStepStart) {
return yield this._onStepStart(stepIndex, label);
}
});
}
/**
* Get the function that will be executed a old step is reloaded. A step is reloaded when the user goes back to it or when the user laods a save file.
* @returns Promise<void> or void
*/
get onLoadStep() {
return this._onLoadStep;
}
/**
* Is a function that will be executed when the step ends.
* @returns Promise<void> or void
*/
get onStepEnd() {
return this._onStepEnd;
}
get choiseIndex() {
return this._choiseIndex;
}
};
// src/classes/Label.ts
var Label = class extends LabelAbstract {
/**
* @param id is the id of the label
* @param steps is the list of steps that the label will perform
* @param props is the properties of the label
*/
constructor(id, steps, props) {
super(id, props);
this._steps = steps;
}
/**
* Get the steps of the label.
*/
get steps() {
if (typeof this._steps === "function") {
return this._steps();
}
return this._steps;
}
};
// src/classes/CloseLabel.ts
var CLOSE_LABEL_ID = "__close-label-id__";
function newCloseLabel(choiseIndex) {
return new Label(CLOSE_LABEL_ID, [], {
choiseIndex
});
}
// src/decorators/LabelDecorator.ts
var registeredLabels = {};
function newLabel(id, steps, props) {
if (registeredLabels[id]) {
console.info(`[Pixi'VN] Label ${id} already exists, it will be overwritten`);
}
let label = new Label(id, steps, props);
registeredLabels[id] = label;
return label;
}
function getLabelById(id) {
let label = registeredLabels[id];
if (!label) {
console.error(`[Pixi'VN] Label ${id} not found`);
return;
}
return label;
}
function saveLabel(label) {
registeredLabels[label.id] = label;
}
var CanvasBase = class extends pixi_js.Container {
constructor() {
super(...arguments);
/**
* Get the id of the canvas element. This variable is used in the system to get the canvas element by id, {@link getCanvasElementInstanceById}
*/
this.pixivnId = "canvas_element_id_not_set";
}
/**
* This method return the memory of the canvas element.
*/
get memory() {
throw new Error("[Pixi'VN] The method CanvasBase.memory must be overridden");
}
/**
* This method set the memory of the canvas element.
*/
set memory(_value) {
throw new Error("[Pixi'VN] The method CanvasBase.memory must be overridden");
}
};
// src/functions/CanvasUtility.ts
function getTextureMemory(texture) {
let sourceTexture = texture.source;
let textureMemory = {
image: sourceTexture.label
};
return textureMemory;
}
function exportCanvasElement(element) {
return element.memory;
}
function importCanvasElement(memory) {
let element = getCanvasElementInstanceById(memory.pixivnId);
if (element) {
element.memory = memory;
} else {
throw new Error("[Pixi'VN] The element " + memory.pixivnId + " could not be created");
}
return element;
}
// src/classes/canvas/CanvasContainer.ts
var CANVAS_CONTAINER_ID = "CanvasContainer";
var CanvasContainer = class extends pixi_js.Container {
constructor(options) {
super(options);
this.pixivnId = CANVAS_CONTAINER_ID;
this.pixivnId = this.constructor.prototype.pixivnId || CANVAS_CONTAINER_ID;
}
get memory() {
let memory = getMemoryContainer(this);
this.children.forEach((child) => {
memory.elements.push(exportCanvasElement(child));
});
return memory;
}
set memory(value) {
setMemoryContainer(this, value);
value.elements.forEach((child) => {
this.addChild(importCanvasElement(child));
});
}
};
function getMemoryContainer(element) {
let className = "CanvasContainer";
if (element.hasOwnProperty("pixivnId")) {
className = element.pixivnId;
}
return {
pixivnId: className,
elements: [],
width: element.width,
height: element.height,
isRenderGroup: element.isRenderGroup,
blendMode: element.blendMode,
tint: element.tint,
alpha: element.alpha,
angle: element.angle,
renderable: element.renderable,
rotation: element.rotation,
scale: { x: element.scale.x, y: element.scale.y },
pivot: { x: element.pivot.x, y: element.pivot.y },
position: { x: element.position.x, y: element.position.y },
skew: { x: element.skew.x, y: element.skew.y },
visible: element.visible,
x: element.x,
y: element.y,
boundsArea: element.boundsArea,
cursor: element.cursor,
eventMode: element.eventMode,
interactive: element.interactive,
interactiveChildren: element.interactiveChildren,
hitArea: element.hitArea
};
}
function setMemoryContainer(element, memory) {
memory.isRenderGroup && (element.isRenderGroup = memory.isRenderGroup);
memory.blendMode && (element.blendMode = memory.blendMode);
memory.tint && (element.tint = memory.tint);
memory.alpha && (element.alpha = memory.alpha);
memory.angle && (element.angle = memory.angle);
memory.renderable && (element.renderable = memory.renderable);
memory.rotation && (element.rotation = memory.rotation);
if (memory.scale) {
if (typeof memory.scale === "number") {
element.scale.set(memory.scale, memory.scale);
} else {
element.scale.set(memory.scale.x, memory.scale.y);
}
}
if (memory.pivot) {
if (typeof memory.pivot === "number") {
element.pivot.set(memory.pivot, memory.pivot);
} else {
element.pivot.set(memory.pivot.x, memory.pivot.y);
}
}
memory.position && element.position.set(memory.position.x, memory.position.y);
memory.skew && element.skew.set(memory.skew.x, memory.skew.y);
memory.visible && (element.visible = memory.visible);
memory.x && (element.x = memory.x);
memory.y && (element.y = memory.y);
memory.boundsArea && (element.boundsArea = memory.boundsArea);
memory.cursor && (element.cursor = memory.cursor);
memory.eventMode && (element.eventMode = memory.eventMode);
memory.interactive && (element.interactive = memory.interactive);
memory.interactiveChildren && (element.interactiveChildren = memory.interactiveChildren);
memory.hitArea && (element.hitArea = memory.hitArea);
memory.width && (element.width = memory.width);
memory.height && (element.height = memory.height);
}
function getTexture(imageUrl) {
return __async(this, null, function* () {
if (pixi_js.Assets.cache.has(imageUrl)) {
return pixi_js.Assets.get(imageUrl);
}
return pixi_js.Assets.load(imageUrl).then((texture) => {
if (!texture) {
console.error("[Pixi'VN] Texture not found", imageUrl);
return;
}
if (!(texture instanceof pixi_js.Texture)) {
console.error("[Pixi'VN] File not is a image", imageUrl);
return;
}
return texture;
}).catch((e) => {
console.error("[Pixi'VN] Error loading image", e);
return;
});
});
}
function getFillGradientFillPattern(prop, propName) {
if (!(prop instanceof Object)) {
return prop;
}
console.warn(`[Pixi'VN] CanvasText.style.${propName} is a FillGradient or FillPattern, this is not supported yet.`, prop);
return void 0;
}
function getTextStyle(style) {
return {
align: style.align,
breakWords: style.breakWords,
dropShadow: style.dropShadow,
fill: getFillGradientFillPattern(style.stroke, "fill"),
fontFamily: style.fontFamily,
fontSize: style.fontSize,
fontStyle: style.fontStyle,
fontVariant: style.fontVariant,
fontWeight: style.fontWeight,
leading: style.leading,
letterSpacing: style.letterSpacing,
lineHeight: style.lineHeight,
padding: style.padding,
stroke: getFillGradientFillPattern(style.stroke, "stroke"),
textBaseline: style.textBaseline,
trim: style.trim,
whiteSpace: style.whiteSpace,
wordWrap: style.wordWrap,
wordWrapWidth: style.wordWrapWidth
};
}
// src/decorators/EventDecorator.ts
var registeredEvents = {};
function eventDecorator(name) {
return function(target) {
if (!name) {
name = target.name;
}
if (registeredEvents[name]) {
console.info(`[Pixi'VN] Event ${name} already exists, it will be overwritten`);
}
target.prototype.id = name;
registeredEvents[name] = target;
};
}
function getEventTypeById(eventId) {
try {
let eventType = registeredEvents[eventId];
if (!eventType) {
console.error(`[Pixi'VN] Event ${eventId} not found`);
return;
}
new eventType();
return eventType;
} catch (e) {
console.error(`[Pixi'VN] Error while getting Event ${eventId}`, e);
return;
}
}
function getEventInstanceById(eventId) {
try {
let eventType = registeredEvents[eventId];
if (!eventType) {
console.error(`[Pixi'VN] Event ${eventId} not found`);
return;
}
let event = new eventType();
return event;
} catch (e) {
console.error(`[Pixi'VN] Error while getting Event ${eventId}`, e);
return;
}
}
// src/classes/canvas/CanvasSprite.ts
var CANVAS_SPRITE_ID = "CanvasSprite";
var CanvasSprite = class _CanvasSprite extends pixi_js.Sprite {
constructor(options) {
super(options);
this.pixivnId = CANVAS_SPRITE_ID;
this._onEvents = {};
this.pixivnId = this.constructor.prototype.pixivnId || CANVAS_SPRITE_ID;
}
get memory() {
return getMemorySprite(this);
}
set memory(value) {
setMemorySprite(this, value);
}
get onEvents() {
return this._onEvents;
}
/**
* is same function as on(), but it keeps in memory the children.
* @param event The event type, e.g., 'click', 'mousedown', 'mouseup', 'pointerdown', etc.
* @param eventClass The class that extends CanvasEvent.
* @returns
* @example
* ```typescript
* \@eventDecorator()
* export class EventTest extends CanvasEvent<CanvasSprite> {
* override fn(event: CanvasEventNamesType, sprite: CanvasSprite): void {
* if (event === 'pointerdown') {
* sprite.scale.x *= 1.25;
* sprite.scale.y *= 1.25;
* }
* }
* }
* ```
*
* ```typescript
* let sprite = addImage("alien", 'https://pixijs.com/assets/eggHead.png')
* await sprite.load()
*
* sprite.eventMode = 'static';
* sprite.cursor = 'pointer';
* sprite.onEvent('pointerdown', EventTest);
*
* GameWindowManager.addCanvasElement("bunny", sprite);
* ```
*/
onEvent(event, eventClass) {
let id = eventClass.prototype.id;
let instance = getEventInstanceById(id);
this._onEvents[event] = id;
if (instance) {
super.on(event, () => {
instance.fn(event, this);
});
}
return this;
}
/**
* on() does not keep in memory the event class, use onEvent() instead
* @deprecated
* @private
* @param event
* @param fn
* @param context
*/
on(event, fn, context) {
return super.on(event, fn, context);
}
static from(source, skipCache) {
let sprite = pixi_js.Sprite.from(source, skipCache);
let mySprite = new _CanvasSprite();
mySprite.texture = sprite.texture;
return mySprite;
}
};
function getMemorySprite(element) {
let temp = getMemoryContainer(element);
return __spreadProps(__spreadValues({}, temp), {
pixivnId: element.pixivnId,
textureImage: getTextureMemory(element.texture),
anchor: { x: element.anchor.x, y: element.anchor.y },
roundPixels: element.roundPixels,
onEvents: element.onEvents
});
}
function setMemorySprite(element, memory) {
setMemoryContainer(element, memory);
getTexture(memory.textureImage.image).then((texture) => {
if (texture) {
element.texture = texture;
}
});
if (memory.anchor) {
if (typeof memory.anchor === "number") {
element.anchor.set(memory.anchor, memory.anchor);
} else {
element.anchor.set(memory.anchor.x, memory.anchor.y);
}
}
memory.roundPixels && (element.roundPixels = memory.roundPixels);
for (let event in memory.onEvents) {
let id = memory.onEvents[event];
let instance = getEventTypeById(id);
if (instance) {
element.onEvent(event, instance);
}
}
}
// src/classes/canvas/CanvasImage.ts
var CANVAS_IMAGE_ID = "CanvasImage";
var CanvasImage = class _CanvasImage extends CanvasSprite {
constructor(options, imageLink) {
super(options);
this.pixivnId = CANVAS_IMAGE_ID;
this.imageLink = "";
if (imageLink) {
this.imageLink = imageLink;
}
}
get memory() {
return __spreadProps(__spreadValues({}, getMemorySprite(this)), {
pixivnId: this.pixivnId,
imageLink: this.imageLink
});
}
set memory(memory) {
setMemorySprite(this, memory);
this.imageLink = memory.imageLink;
}
static from(source, skipCache) {
let sprite = pixi_js.Sprite.from(source, skipCache);
let mySprite = new _CanvasImage();
mySprite.texture = sprite.texture;
return mySprite;
}
/**
* Load the image from the link and set the texture of the sprite.
* @param image The link of the image. If it is not set, it will use the imageLink property.
* @returns A promise that resolves when the image is loaded.
*/
load(image) {
return __async(this, null, function* () {
if (!image) {
image = this.imageLink;
}
return getTexture(this.imageLink).then((texture) => {
if (texture) {
this.texture = texture;
}
}).catch((e) => {
console.error("[Pixi'VN] Error into CanvasImage.load()", e);
});
});
}
};
var CANVAS_TEXT_ID = "CanvasText";
var CanvasText = class extends pixi_js.Text {
constructor(options) {
super(options);
this.pixivnId = CANVAS_TEXT_ID;
this._onEvents = {};
this.pixivnId = this.constructor.prototype.pixivnId || CANVAS_TEXT_ID;
}
get memory() {
return getMemoryText(this);
}
set memory(value) {
setMemoryText(this, value);
}
get onEvents() {
return this._onEvents;
}
/**
* is same function as on(), but it keeps in memory the children.
* @param event The event type, e.g., 'click', 'mousedown', 'mouseup', 'pointerdown', etc.
* @param eventClass The class that extends CanvasEvent.
* @returns
* @example
* ```typescript
* \@eventDecorator()
* export class EventTest extends CanvasEvent<CanvasText> {
* override fn(event: CanvasEventNamesType, text: CanvasText): void {
* if (event === 'pointerdown') {
* text.scale.x *= 1.25;
* text.scale.y *= 1.25;
* }
* }
* }
* ```
*
* ```typescript
* const text = new CanvasText();
* text.text = "Hello World"
*
* text.eventMode = 'static';
* text.cursor = 'pointer';
* text.onEvent('pointerdown', EventTest);
*
* GameWindowManager.addCanvasElement("text", text);
* ```
*/
onEvent(event, eventClass) {
let id = eventClass.prototype.id;
let instance = getEventInstanceById(id);
this._onEvents[event] = id;
if (instance) {
super.on(event, () => {
instance.fn(event, this);
});
}
return this;
}
/**
* on() does not keep in memory the event class, use onEvent() instead
* @deprecated
* @private
* @param event
* @param fn
* @param context
*/
on(event, fn, context) {
return super.on(event, fn, context);
}
};
function getMemoryText(element) {
let temp = getMemoryContainer(element);
return __spreadProps(__spreadValues({}, temp), {
pixivnId: element.pixivnId,
anchor: { x: element.anchor.x, y: element.anchor.y },
text: element.text,
resolution: element.resolution,
style: getTextStyle(element.style),
roundPixels: element.roundPixels,
onEvents: element.onEvents
});
}
function setMemoryText(element, memory) {
setMemoryContainer(element, memory);
if (memory.anchor) {
if (typeof memory.anchor === "number") {
element.anchor.set(memory.anchor, memory.anchor);
} else {
element.anchor.set(memory.anchor.x, memory.anchor.y);
}
}
memory.text && (element.text = memory.text);
memory.resolution && (element.resolution = memory.resolution);
memory.style && (element.style = memory.style);
memory.roundPixels && (element.roundPixels = memory.roundPixels);
for (let event in memory.onEvents) {
let id = memory.onEvents[event];
let instance = getEventTypeById(id);
if (instance) {
element.onEvent(event, instance);
}
}
}
// src/decorators/CanvasElementDecorator.ts
var registeredCanvasElement = {};
function canvasElementDecorator(name) {
return function(target) {
if (!name) {
name = target.name;
}
if (registeredCanvasElement[name]) {
console.warn(`[Pixi'VN] CanvasElement ${name} already registered`);
}
target.prototype.pixivnId = name;
registeredCanvasElement[name] = target;
};
}
function getCanvasElementInstanceById(canvasId) {
try {
let eventType = registeredCanvasElement[canvasId];
if (!eventType) {
if (canvasId === CANVAS_CONTAINER_ID) {
eventType = CanvasContainer;
} else if (canvasId === CANVAS_IMAGE_ID) {
eventType = CanvasImage;
} else if (canvasId === CANVAS_SPRITE_ID) {
eventType = CanvasSprite;
} else if (canvasId === CANVAS_TEXT_ID) {
eventType = CanvasText;
}
}
if (!eventType) {
console.error(`[Pixi'VN] CanvasElement ${canvasId} not found`);
return;
}
let canvasElement = new eventType();
return canvasElement;
} catch (e) {
console.error(`[Pixi'VN] Error while getting CanvasElement ${canvasId}`, e);
return;
}
}
// src/decorators/CharacterDecorator.ts
var registeredCharacters = {};
function saveCharacter(character) {
if (Array.isArray(character)) {
character.forEach((c) => saveCharacter(c));
return;
}
if (registeredCharacters[character.id]) {
console.info(`[Pixi'VN] Character id ${character.id} already exists, it will be overwritten`);
}
registeredCharacters[character.id] = character;
}
function getCharacterById(id) {
try {
let character = registeredCharacters[id];
if (!character) {
console.error(`[Pixi'VN] Character ${id} not found`);
return;
}
return character;
} catch (e) {
console.error(`[Pixi'VN] Error while getting Character ${id}`, e);
return;
}
}
function getAllCharacters() {
return Object.values(registeredCharacters);
}
// src/decorators/TickerDecorator.ts
var registeredTickers = {};
function tickerDecorator(name) {
return function(target) {
if (!name) {
name = target.name;
}
if (registeredTickers[name]) {
console.info(`[Pixi'VN] Ticker ${name} already exists, it will be overwritten`);
}
target.prototype.id = name;
registeredTickers[name] = target;
};
}
function geTickerInstanceById(tickerId, args, duration, priority) {
try {
let ticker = registeredTickers[tickerId];
if (!ticker) {
console.error(`[Pixi'VN] Ticker ${tickerId} not found`);
return;
}
return new ticker(args, duration, priority);
} catch (e) {
console.error(`[Pixi'VN] Error while getting Ticker ${tickerId}`, e);
return;
}
}
// src/types/CloseType.ts
var Close = "close";
// src/classes/ChoiceMenuOption.ts
var ChoiceMenuOption = class {
/**
* @param text Text to be displayed in the menu
* @param label Label to be opened when the option is selected or the id of the label
* @param props Properties to be passed to the label and olther parameters that you can use when get all the choice menu options. It be converted to a JSON string, so it cannot contain functions or classes.
* @param type Type of the label to be opened. @default "call"
*/
constructor(text, label, props, type = "call") {
/**
* Properties to be passed to the label and olther parameters that you can use when get all the choice menu options.
* @example
* ```tsx
* setChoiceMenuOptions([
* new ChoiceMenuOption("Hello", helloLabel, { disabled: true }),
* ])
* return <List>
* {getChoiceMenuOptions()?.map((item, index) => {
* return (
* <ChoiceButton
* disabled={item.props.disabled}
* onClick={() => {
* afterSelectChoice(item)
* }}
* >
* {item.text}
* </ChoiceButton>
* )
* })}
* </List>
* ```
*/
this.props = {};
this.text = text;
this._label = label;
this.type = type;
if (props) {
this.props = props;
}
}
/**
* Label to be opened when the option is selected
*/
get label() {
let label = this._label;
if (typeof label === "string") {
let res = getLabelById(label);
if (res) {
label = res;
} else {
console.error(`Label ${label} not found, so it will be closed`);
label = newCloseLabel();
}
}
return label;
}
};
var ChoiceMenuOptionClose = class {
/**
* @param text Text to be displayed in the menu
* @param closeCurrentLabel If true, the current label will be closed. @default false
*/
constructor(text, closeCurrentLabel = false) {
/**
* Label to be opened when the option is selected
*/
this.label = newCloseLabel();
/**
* Type of the label to be opened
*/
this.type = Close;
/**
* Properties to be passed to the label and olther parameters that you can use when get all the choice menu options.
* @example
* ```tsx
* setChoiceMenuOptions([
* new ChoiceMenuOption("Hello", helloLabel, { disabled: true }),
* ])
* return <List>
* {getChoiceMenuOptions()?.map((item, index) => {
* return (
* <ChoiceButton
* disabled={item.props.disabled}
* onClick={() => {
* afterSelectChoice(item)
* }}
* >
* {item.text}
* </ChoiceButton>
* )
* })}
* </List>
* ```
*/
this.props = {};
this.text = text;
this.closeCurrentLabel = closeCurrentLabel;
}
};
// src/functions/FlagsUtility.ts
function setFlag(name, value) {
let flags = GameStorageManager.getVariable(GameStorageManager.keysSystem.FLAGS_CATEGORY_KEY) || [];
if (value) {
if (!flags.includes(name)) {
flags.push(name);
}
} else {
let index = flags.indexOf(name);
if (index > -1) {
flags.splice(index, 1);
}
}
GameStorageManager.setVariable(GameStorageManager.keysSystem.FLAGS_CATEGORY_KEY, flags);
}
function getFlag(name) {
let flags = GameStorageManager.getVariable(GameStorageManager.keysSystem.FLAGS_CATEGORY_KEY) || [];
return flags.includes(name);
}
// src/functions/DialogueUtility.ts
function setDialogue(props) {
let text = "";
let character = void 0;
let dialogue;
if (typeof props === "string") {
text = props;
dialogue = new DialogueBaseModel(text, character);
} else if (Array.isArray(props)) {
text = props.join();
dialogue = new DialogueBaseModel(text, character);
} else if (!(props instanceof DialogueBaseModel)) {
if (Array.isArray(props.text)) {
text = props.text.join();
} else {
text = props.text;
}
if (props.character) {
if (typeof props.character === "string") {
character = props.character;
} else {
character = props.character.id;
}
}
dialogue = new DialogueBaseModel(text, character);
} else {
dialogue = props;
}
if (getFlag(GameStorageManager.keysSystem.ADD_NEXT_DIALOG_TEXT_INTO_THE_CURRENT_DIALOG_FLAG_KEY)) {
let glueDialogue = getDialogue();
if (glueDialogue) {
dialogue.text = `${glueDialogue.text}${dialogue.text}`;
}
setFlag(GameStorageManager.keysSystem.ADD_NEXT_DIALOG_TEXT_INTO_THE_CURRENT_DIALOG_FLAG_KEY, false);
}
GameStorageManager.setVariable(GameStorageManager.keysSystem.CURRENT_DIALOGUE_MEMORY_KEY, dialogue);
GameStorageManager.setVariable(GameStorageManager.keysSystem.LAST_DIALOGUE_ADDED_IN_STEP_MEMORY_KEY, GameStepManager.lastStepIndex);
}
function getDialogue() {
return GameStorageManager.getVariable(GameStorageManager.keysSystem.CURRENT_DIALOGUE_MEMORY_KEY);
}
function clearDialogue() {
GameStorageManager.setVariable(GameStorageManager.keysSystem.CURRENT_DIALOGUE_MEMORY_KEY, void 0);
}
function setChoiceMenuOptions(options) {
let value = options.map((option) => {
if (option instanceof ChoiceMenuOptionClose) {
return {
text: option.text,
type: Close,
closeCurrentLabel: option.closeCurrentLabel
};
}
return __spreadProps(__spreadValues({}, option), {
label: option.label.id
});
});
GameStorageManager.setVariable(GameStorageManager.keysSystem.CURRENT_MENU_OPTIONS_MEMORY_KEY, value);
GameStorageManager.setVariable(GameStorageManager.keysSystem.LAST_MENU_OPTIONS_ADDED_IN_STEP_MEMORY_KEY, GameStepManager.lastStepIndex);
}
function getChoiceMenuOptions() {
let d = GameStorageManager.getVariable(GameStorageManager.keysSystem.CURRENT_MENU_OPTIONS_MEMORY_KEY);
if (d) {
let options = [];
d.forEach((option, index) => {
if (option.type === Close) {
let itemLabel = newCloseLabel(index);
let choice = new ChoiceMenuOptionClose(option.text, option.closeCurrentLabel);
choice.label = itemLabel;
options.push(choice);
return;
}
let label = getLabelById(option.label);
if (label) {
let itemLabel = new Label(label.id, label.steps, {
onStepStart: label.onStepStart,
choiseIndex: index
});
options.push(new ChoiceMenuOption(option.text, itemLabel, option.props, option.type));
}
});
return options;
}
return void 0;
}
function clearChoiceMenuOptions() {
GameStorageManager.setVariable(GameStorageManager.keysSystem.CURRENT_MENU_OPTIONS_MEMORY_KEY, void 0);
}
function getDialogueHistory() {
let list = [];
GameStepManager.stepsHistory.forEach((step) => {
let dialoge = step.dialoge;
let requiredChoices = step.choices;
if (list.length > 0 && list[list.length - 1].choices && !list[list.length - 1].playerMadeChoice && step.currentLabel) {
let oldChoices = list[list.length - 1].choices;
if (oldChoices) {
let choiceMade = false;
if (step.choiceIndexMade !== void 0 && oldChoices.length > step.choiceIndexMade) {
oldChoices[step.choiceIndexMade].isResponse = true;
choiceMade = true;
}
list[list.length - 1].playerMadeChoice = choiceMade;
list[list.length - 1].choices = oldChoices;
}
}
if (dialoge || requiredChoices) {
let choices = requiredChoices == null ? void 0 : requiredChoices.map((choice) => {
return {
text: choice.text,
type: choice.type,
isResponse: false
};
});
list.push({
dialoge,
playerMadeChoice: false,
choices,
stepIndex: step.index
});
}
});
return list;
}
// src/functions/GameUtility.ts
function clearAllGameDatas() {
GameStorageManager.clear();
GameWindowManager.clear();
GameStepManager.clear();
}
// src/classes/ticker/TickerBase.ts
var TickerBase = class {
/**
* @param args The arguments that you want to pass to the ticker.
* @param duration The duration of the ticker in seconds. If is undefined, the step will end only when the animation is finished (if the animation doesn't have a goal to reach then it won't finish). @default undefined
* @param priority The priority of the ticker. @default UPDATE_PRIORITY.NORMAL
*/
constructor(args, duration, priority) {
/**
* Get the id of the ticker. This variable is used in the system to get the ticker by id, {@link geTickerInstanceById}
*/
this.id = "ticker_id_not_set";
this.args = args;
this.duration = duration;
this.priority = priority;
this.id = this.constructor.prototype.id;
}
/**
* The method that will be called every frame.
* This method should be overridden and you can use GameWindowManager.addCanvasElement() to get the canvas element of the canvas, and edit them.
* @param _ticker The ticker that is calling this method
* @param _args The arguments that you passed when you added the ticker
* @param _tags The tags of the canvas elements that are connected to this ticker
* @param _tickerId The id of the ticker. You can use this to get the ticker from the {@link GameWindowManager.currentTickers}
*/
fn(_ticker, _args, _tags, _tickerId) {
throw new Error("[Pixi'VN] The method TickerBase.fn() must be overridden");
}
};
// src/classes/ticker/FadeAlphaTicker.ts
exports.FadeAlphaTicker = class FadeAlphaTicker extends TickerBase {
fn(ticker, args, tags, tickerId) {
let type = args.type === void 0 ? "hide" : args.type;
let duration = args.duration === void 0 ? 1 : args.duration;
let speed = 1 / (duration * 60);
let limit = args.limit === void 0 ? type === "hide" ? 0 : 1 : args.limit;
let tagToRemoveAfter2 = args.tagToRemoveAfter || [];
if (typeof tagToRemoveAfter2 === "string") {
tagToRemoveAfter2 = [tagToRemoveAfter2];
}
if (type === "hide" && limit < 0) {
limit = 0;
}
if (type === "show" && limit > 1) {
limit = 1;
}
tags.filter((tag) => {
var _a;
let element = GameWindowManager.getCanvasElement(tag);
if (args.startOnlyIfHaveTexture) {
if (element && element instanceof pixi_js.Sprite && ((_a = element.texture) == null ? void 0 : _a.label) == "EMPTY") {
return false;
}
}
return true;
}).forEach((tag) => {
let element = GameWindowManager.getCanvasElement(tag);
if (element && element instanceof pixi_js.Container) {
if (type === "show" && element.alpha < limit) {
element.alpha += speed * ticker.deltaTime;
} else if (type === "hide" && element.alpha > limit) {
element.alpha -= speed * ticker.deltaTime;
}
if (type === "show" && element.alpha >= limit) {
element.alpha = limit;
GameWindowManager.onEndOfTicker(tag, this, tagToRemoveAfter2, tickerId);
} else if (type === "hide" && element.alpha <= limit) {
element.alpha = limit;
GameWindowManager.onEndOfTicker(tag, this, tagToRemoveAfter2, tickerId);
}
}
});
}
};
exports.FadeAlphaTicker = __decorateClass([
tickerDecorator()
], exports.FadeAlphaTicker);
// src/functions/TickerUtility.ts
function updateTickerProgression(args, propertyName, progression, valueConvert) {
let limit = valueConvert && progression.limit ? valueConvert(progression.limit) : progression.limit;
if (args[propertyName] === void 0 || !progression || args[propertyName] === limit) {
return;
}
if (typeof args[propertyName] === "number") {
if (progression.type === "linear") {
args[propertyName] = getLinearProgression(args[propertyName], progression);
} else if (progression.type === "exponential") {
args[propertyName] = getExponentialProgression(args[propertyName], progression);
}
} else if (args[propertyName] !== void 0 && typeof args[propertyName] === "object" && args[propertyName].haveOwnProperty("x") && args[propertyName].haveOwnProperty("y") && typeof args[propertyName].x === "number" && typeof args[propertyName].y === "number") {
if (progression.type === "linear") {
args[propertyName].x = getLinearProgression(args[propertyName].x, progression);
args[propertyName].y = getLinearProgression(args[propertyName].y, progression);
} else if (progression.type === "exponential") {
args[propertyName].x = getExponentialProgression(args[propertyName].x, progression);
args[propertyName].y = getExponentialProgression(args[propertyName].y, progression);
}
}
}
function getLinearProgression(number, progression, valueConvert) {
let limit = valueConvert && progression.limit ? valueConvert(progression.limit) : progression.limit;
let amt = valueConvert ? valueConvert(progression.amt) : progression.amt;
if (limit !== void 0) {
if (number > limit && amt > 0) {
return limit;
} else if (number < limit && amt < 0) {
return limit;
}
}
return number + amt;
}
function getExponentialProgression(number, progression, valueConvert) {
let limit = valueConvert && progression.limit ? valueConvert(progression.limit) : progression.limit;
if (limit !== void 0) {
if (number > limit && progression.percentage > 0) {
return limit;
} else if (number < limit && progression.percentage < 0) {
return limit;
}
}
return number + number * progression.percentage;
}
// src/classes/ticker/MoveTicker.ts
exports.MoveTicker = class MoveTicker extends TickerBase {
fn(ticker, args, tags, tickerId) {
let xSpeed = 1;
let ySpeed = 1;
if (args.speed) {
if (typeof args.speed === "number") {
xSpeed = this.speedConvert(args.speed);
ySpeed = this.speedConvert(args.speed);
} else {
xSpeed = this.speedConvert(args.speed.x);
ySpeed = this.speedConvert(args.speed.y);
}
}
let destination = args.destination;
let tagToRemoveAfter2 = args.tagToRemoveAfter || [];
if (typeof tagToRemoveAfter2 === "string") {
tagToRemoveAfter2 = [tagToRemoveAfter2];
}
tags.filter((tag) => {
var _a;
let element = GameWindowManager.getCanvasElement(tag);
if (args.startOnlyIfHaveTexture) {
if (element && element instanceof pixi_js.Sprite && ((_a = element.texture) == null ? void 0 : _a.label) == "EMPTY") {
return false;
}
}
return true;
}).forEach((tag) => {
let element = GameWindowManager.getCanvasElement(tag);
if (element && element instanceof pixi_js.Container) {
let xDistance = destination.x - element.x > 0 ? 1 : -1;
if (xDistance != 0) {
element.x += xDistance * xSpeed * ticker.deltaTime;
let newDistance = destination.x - element.x;
if (xDistance < 0 && newDistance > 0 || xDistance > 0 && newDistance < 0) {
element.x = destination.x;
}
}
let yDistance = destination.y - element.y > 0 ? 1 : -1;
if (yDistance != 0) {
element.y += yDistance * ySpeed * ticker.deltaTime;
let newDistance = destination.y - element.y;
if (yDistance < 0 && newDistance > 0 || yDistance > 0 && newDistance < 0) {
element.y = destination.y;
}
}
if (element.x == destination.x && element.y == destination.y) {
GameWindowManager.onEndOfTicker(tag, this, tagToRemoveAfter2, tickerId);
}
}
});
if (args.speedProgression)
updateTickerProgression(args, "speed", args.speedProgression, this.speedConvert);
}
speedConvert(speed) {
return speed / 6;
}
};
exports.MoveTicker = __decorateClass([
tickerDecorator()
], exports.MoveTicker);
exports.RotateTicker = class RotateTicker extends TickerBase {
fn(ticker, args, tags, tickerId) {
let speed = this.speedConvert(args.speed === void 0 ? 1 : args.speed);
let clockwise = args.clockwise === void 0 ? true : args.clockwise;
let tagToRemoveAfter2 = args.tagToRemoveAfter || [];
if (typeof tagToRemoveAfter2 === "string") {
tagToRemoveAfter2 = [tagToRemoveAfter2];
}
tags.filter((tag) => {
var _a;
let element = GameWindowManager.getCanvasElement(tag);
if (args.startOnlyIfHaveTexture) {
if (element && element instanceof pixi_js.Sprite && ((_a = element.texture) == null ? void 0 : _a.label) == "EMPTY") {
return false;
}
}
return true;
}).forEach((tag) => {
let element = GameWindowManager.getCanvasElement(tag);
if (element && element instanceof pixi_js.Container) {
if (clockwise)
element.rotation += speed * ticker.deltaTime;
else
element.rotation -= speed * ticker.deltaTime;
if (speed < 1e-5 && !(args.speedProgression && args.speedProgression.type == "linear" && args.speedProgression.amt != 0)) {
GameWindowManager.onEndOfTicker(tag, this, tagToRemoveAfter2, tickerId);
}
}
});
if (args.speedProgression)
updateTickerProgression(args, "speed", args.speedProgression, this.speedConvert);
}
speedConvert(speed) {
return speed / 60;
}
};
exports.RotateTicker = __decorateClass([
tickerDecorator()
], exports.RotateTicker);
exports.ZoomTicker = class ZoomTicker extends TickerBase {
fn(ticker, args, tags, tickerId) {
let xSpeed = 0.1;
let ySpeed = 0.1;
if (args.speed) {
if (typeof args.speed === "number") {
xSpeed = this.speedConvert(args.speed);
ySpeed = this.speedConvert(args.speed);
} else {
xSpeed = this.speedConvert(args.speed.x);
ySpeed = this.speedConvert(args.speed.y);
}
}
let tagToRemoveAfter2 = args.tagToRemoveAfter || [];
if (typeof tagToRemoveAfter2 === "string") {
tagToRemoveAfter2 = [tagToRemoveAfter2];
}
let type = args.type || "zoom";
let xLimit = type === "zoom" ? Infinity : 0;
let yLimit = type === "zoom" ? Infinity : 0;
if (args.limit) {
if (typeof args.limit === "number") {
xLimit = args.limit;
yLimit = args.limit;
} else {
xLimit = args.limit.x;
yLimit = args.limit.y;
}
}
tags.filter((tag) => {
var _a;
let element = GameWindowManager.getCanvasElement(tag);
if (args.startOnlyIfHaveTexture) {
if (element && element instanceof pixi_js.Sprite && ((_a = element.texture) == null ? void 0 : _a.label) == "EMPTY") {
return false;
}
}
return true;
}).forEach((tag) => {
let element = GameWindowManager.getCanvasElement(tag);
if (element && element instanceof pixi_js.Container) {
if (type === "zoom" && (element.scale.x < xLimit || element.scale.y < yLimit)) {
element.scale.x += xSpeed * ticker.deltaTime;
element.scale.y += ySpeed * ticker.deltaTime;
} else if (type === "unzoom" && (element.scale.x > xLimit || element.scale.y > yLimit)) {
element.scale.x -= xSpeed * ticker.deltaTime;
element.scale.y -= ySpeed * ticker.deltaTime;
}
if (type === "zoom") {
if (element.scale.x > xLimit) {
element.scale.x = xLimit;
}
if (element.scale.y > yLimit) {
element.scale.y = yLimit;
}
if (element.scale.x >= xLimit && element.scale.y >= yLimit) {
element.scale.x = xLimit;
element.scale.y = yLimit;
this.onEndOfTicker(tag, tickerId, element, tagToRemoveAfter2);
}
} else if (type === "unzoom") {
if (element.scale.x < xLimit) {
element.scale.x = xLimit;
}
if (element.scale.y < yLimit) {
element.scale.y = yLimit;
}
if (element.scale.x <= xLimit && element.scale.y <= yLimit) {
element.scale.x = xLimit;
element.scale.y = yLimit;
this.onEndOfTicker(tag, tickerId, element, tagToRemoveAfter2);
}
}
if (xSpeed < 1e-5 && ySpeed < 1e-5 && !(args.speedProgression && args.speedProgression.type == "linear" && args.speedProgression.amt != 0)) {
this.onEndOfTicker(tag, tickerId, element, tagToRemoveAfter2);
}
}
});
if (args.speedProgression)
updateTickerProgression(args, "speed", args.speedProgression, this.speedConvert);
}
speedConvert(speed) {
return speed / 60;
}
onEndOfTicker(tag, tickerId, _element, tagToRemoveAfter2) {
GameWindowManager.onEndOfTicker(tag, this, tagToRemoveAfter2, tickerId);
}
};
exports.ZoomTicker = __decorateClass([
tickerDecorator()
], exports.ZoomTicker);
var ZoomInOutTicker = class extends exports.ZoomTicker {
constructor(props, duration, priority) {
super(props, duration, priority);
}
onEndOfTicker(tag, tickerId, element, tagToRemoveAfter2) {
if (element.children.length > 0) {
let elementChild = element.children[0];
GameWindowManager.addCanvasElement(tag, elementChild);
}
super.onEndOfTicker(tag, tickerId, element, tagToRemoveAfter2);
}
};
// src/constants.ts
var PIXIVN_VERSION = "0.6.14";
var Repeat = "repeat";
function Pause(duration) {
return {
type: "pause",
duration
};
}
// src/functions/ImageUtility.ts
function addImage(tag, imageUrl) {
let image = new CanvasImage();
image.imageLink = imageUrl;
GameWindowManager.addCanvasElement(tag, image);
return image;
}
function loadImage(canvasImages) {
return __async(this, null, function* () {
if (!Array.isArray(canvasImages)) {
return [canvasImages];
}
let promises = Array(canvasImages.length);
for (let i = 0; i < canvasImages.length; i++) {
promises[i] = getTexture(canvasImages[i].imageLink);
}
return Promise.all(promises).then((textures) => {
return textures.map((texture, index) => {
if (texture) {
canvasImages[index].texture = texture;
return canvasImages[index];
}
canvasImages[index].load();
return canvasImages[index];
});
});
});
}
function showImage(tag, imageUrl) {
return __async(this, null, function* () {
let image = addImage(tag, imageUrl);
yield image.load();
return image;
});
}
function removeCanvasElement(tag) {
GameWindowManager.removeCanvasElement(tag);
}
function showWithDissolveTransition(_0, _1) {
return __async(this, arguments, function* (tag, image, props = {}, priority) {
var _a;
let oldCanvasTag = void 0;
if (GameWindowManager.getCanvasElement(tag)) {
oldCanvasTag = tag + "_temp_disolve";
GameWindowManager.editCanvasElementTag(tag, oldCanvasTag);
}
let canvasElement;
if (typeof image === "string") {
canvasElement = addImage(tag, image);
} else {
canvasElement = image;
GameWindowManager.addCanvasElement(tag, canvasElement);
}
if (canvasElement instanceof CanvasImage && ((_a = canvasElement.texture) == null ? void 0 : _a.label) == "EMPTY") {
yield canvasElement.load();
}
canvasElement.alpha = 0;
let effect = new exports.FadeAlphaTicker(__spreadProps(__spreadValues({}, props), {
type: "show",
tagToRemoveAfter: oldCanvasTag,
startOnlyIfHaveTexture: true
}), 10, priority);
GameWindowManager.addTicker(tag, effect);
return;
});
}
function removeWithDissolveTransition(tag, props = {}, priority) {
if (typeof tag === "string") {
tag = [tag];
}
let effect = new exports.FadeAlphaTicker(__spreadProps(__spreadValues({}, props), {
type: "hide",
tagToRemoveAfter: tag,
startOnlyIfHaveTexture: true
}), 10, priority);
GameWindowManager.addTicker(tag, effect);
}
function showWithFadeTransition(_0, _1) {
return __async(this, arguments, function* (tag, image, props = {}, priority) {
var _a;
if (!GameWindowManager.getCanvasElement(tag)) {
return showWithDissolveTransition(tag, image, props, priority);
}
let oldCanvasTag = tag + "_temp_fade";
GameWindowManager.editCanvasElementTag(tag, oldCanvasTag);
let canvasElement;
if (typeof image === "string") {
canvasElement = addImage(tag, image);
} else {
canvasElement = image;
GameWindowManager.addCanvasElement(tag, canvasElement);
}
if (canvasElement instanceof CanvasImage && ((_a = canvasElement.texture) == null ? void 0 : _a.label) == "EMPTY") {
yield canvasElement.load();
}
canvasElement.alpha = 0;
GameWindowManager.addTickersSteps(oldCanvasTag, [
new exports.FadeAlphaTicker(__spreadProps(__spreadValues({}, props), {
type: "hide",
startOnlyIfHaveTexture: true
}))
]);
GameWindowManager.addTickersSteps(tag, [
Pause(props.duration || 1),
new exports.FadeAlphaTicker(__spreadProps(__spreadValues({}, props), {
type: "show",
startOnlyIfHaveTexture: true
}))
]);
});
}
function removeWithFadeTransition(tag, props = {}, priority) {
return removeWithDissolveTransition(tag, props, priority);
}
function moveIn(_0, _1) {
return __async(this, arguments, function* (tag, image, props = { direction: "right" }, priority) {
var _a;
let canvasElement;
if (typeof image === "string") {
canvasElement = addImage(tag, image);
} else {
canvasElement = image;
GameWindowManager.addCanvasElement(tag, canvasElement);
}
if (canvasElement instanceof CanvasImage && ((_a = canvasElement.texture) == null ? void 0 : _a.label) == "EMPTY") {
yield canvasElement.load();
}
let destination = { x: canvasElement.x, y: canvasElement.y };
if (props.direction == "up") {
canvasElement.y = GameWindowManager.canvasHeight + canvasElement.height;
} else if (props.direction == "down") {
canvasElement.y = -canvasElement.height;
} else if (props.direction == "left") {
canvasElement.x = GameWindowManager.canvasWidth + canvasElement.width;
} else if (props.direction == "right") {
canvasElement.x = -canvasElement.width;
}
let effect = new exports.MoveTicker(__spreadProps(__spreadValues({}, props), {
destination,
startOnlyIfHaveTexture: true
}), priority);
GameWindowManager.addTicker(tag, effect);
});
}
function moveOut(tag, props = { direction: "right" }, priority) {
let canvasElement = GameWindowManager.getCanvasElement(tag);
if (!canvasElement) {
console.warn("[Pixi'VN] The canvas element is not found.");
return;
}
let destination = { x: canvasElement.x, y: canvasElement.y };
if (props.direction == "up") {
destination.y = -canvasElement.height;
} else if (props.direction == "down") {
destination.y = GameWindowManager.canvasHeight + canvasElement.height;
} else if (props.direction == "left") {
destination.x = -canvasElement.width;
} else if (props.direction == "right") {
destination.x = GameWindowManager.canvasWidth + canvasElement.width;
}
let effect = new exports.MoveTicker(__spreadProps(__spreadValues({}, props), {
destination,
startOnlyIfHaveTexture: true,
tagToRemoveAfter: tag
}), priority);
GameWindowManager.addTicker(tag, effect);
}
function zoomIn(_0, _1) {
return __async(this, arguments, function* (tag, image, props = { direction: "right" }, priority) {
var _a;
let canvasElement;
if (typeof image === "string") {
canvasElement = new CanvasImage({}, image);
} else {
canvasElement = image;
}
let container = new CanvasContainer();
container.addChild(canvasElement);
container.height = GameWindowManager.canvasHeight;
container.width = GameWindowManager.canvasWidth;
GameWindowManager.addCanvasElement(tag, container);
if (canvasElement instanceof CanvasImage && ((_a = canvasElement.texture) == null ? void 0 : _a.label) == "EMPTY") {
yield canvasElement.load();
}
if (props.direction == "up") {
container.pivot.y = GameWindowManager.canvasHeight;
container.pivot.x = GameWindowManager.canvasWidth / 2;
container.y = GameWindowManager.canvasHeight;
container.x = GameWindowManager.canvasWidth / 2;
} else if (props.direction == "down") {
container.pivot.y = 0;
container.pivot.x = GameWindowManager.canvasWidth / 2;
container.y = 0;
container.x = GameWindowManager.canvasWidth / 2;
} else if (props.direction == "left") {
container.pivot.x = GameWindowManager.canvasWidth;
container.pivot.y = GameWindowManager.canvasHeight / 2;
container.x = GameWindowManager.canvasWidth;
container.y = GameWindowManager.canvasHeight / 2;
} else if (props.direction == "right") {
container.pivot.x = 0;
container.pivot.y = GameWindowManager.canvasHeight / 2;
container.x = 0;
container.y = GameWindowManager.canvasHeight / 2;
}
container.scale.set(0);
let effect = new ZoomInOutTicker(__spreadProps(__spreadValues({}, props), {
startOnlyIfHaveTexture: true,
type: "zoom",
limit: 1
}), priority);
GameWindowManager.addTicker(tag, effect);
});
}
function zoomOut(tag, props = { direction: "right" }, priority) {
let canvasElement = GameWindowManager.getCanvasElement(tag);
if (!canvasElement) {
console.warn("[Pixi'VN] The canvas element is not found.");
return;
}
let container = new CanvasContainer();
container.addChild(canvasElement);
container.height = GameWindowManager.canvasHeight;
container.width = GameWindowManager.canvasWidth;
GameWindowManager.addCanvasElement(tag, container);
if (props.direction == "up") {
container.pivot.y = GameWindowManager.canvasHeight;
container.pivot.x = GameWindowManager.canvasWidth / 2;
container.y = GameWindowManager.canvasHeight;
container.x = GameWindowManager.canvasWidth / 2;
} else if (props.direction == "down") {
container.pivot.y = 0;
container.pivot.x = GameWindowManager.canvasWidth / 2;
container.y = 0;
container.x = GameWindowManager.canvasWidth / 2;
} else if (props.direction == "left") {
container.pivot.x = GameWindowManager.canvasWidth;
container.pivot.y = GameWindowManager.canvasHeight / 2;
container.x = GameWindowManager.canvasWidth;
container.y = GameWindowManager.canvasHeight / 2;
} else if (props.direction == "right") {
container.pivot.x = 0;
container.pivot.y = GameWindowManager.canvasHeight / 2;
container.x = 0;
container.y = GameWindowManager.canvasHeight / 2;
}
container.scale.set(1);
let effect = new ZoomInOutTicker(__spreadProps(__spreadValues({}, props), {
startOnlyIfHaveTexture: true,
type: "unzoom",
limit: 0,
tagToRemoveAfter: tag
}), priority);
GameWindowManager.addTicker(tag, effect);
}
// src/functions/Importer.ts
function importPixiVNJson(data) {
try {
if (typeof data === "string") {
data = JSON.parse(data);
}
} catch (e) {
console.error("[Pixi'VN] Error parsing imported Pixi'VN JSON", e);
return;
}
if (typeof data !== "object") {
console.error("[Pixi'VN] Error parsing imported Pixi'VN JSON: data is not an object");
return;
}
if (data.labels) {
let labels = data.labels;
for (const labelId in labels) {
try {
const steps = labels[labelId];
let label = new LabelJson2(labelId, steps);
saveLabel(label);
} catch (e) {
console.error(`[Pixi'VN] Error creating JSON label ${labelId}`, e);
}
}
}
}
// src/functions/SavesUtility.ts
function getSaveData() {
return {
pixivn_version: PIXIVN_VERSION,
stepData: GameStepManager.export(),
storageData: GameStorageManager.export(),
canvasData: GameWindowManager.export(),
path: window.location.pathname
};
}
function getSaveJson() {
const saveData = getSaveData();
return JSON.stringify(saveData);
}
function loadSaveData(data, navigate) {
return __async(this, null, function* () {
yield GameStepManager.import(data.stepData);
GameStorageManager.import(data.storageData);
GameWindowManager.import(data.canvasData);
navigate(data.path);
});
}
function loadSaveJson(dataString, navigate) {
return __async(this, null, function* () {
yield loadSaveData(jsonToSaveData(dataString), navigate);
});
}
function jsonToSaveData(json) {
return JSON.parse(json);
}
// src/functions/ExportUtility.ts
function createExportableElement(element) {
try {
let elementString = JSON.stringify(element);
return JSON.parse(elementString);
} catch (e) {
console.error("[Pixi'VN] Error creating exportable element", e);
throw new Error("[Pixi'VN] Error creating exportable element");
}
}
// src/functions/DiffUtility.ts
function restoreDeepDiffChanges(data, differences) {
let result = createExportableElement(data);
differences.forEach((diff2) => {
let dataToEdit = result;
if (diff2.path && diff2.path.length > 0) {
diff2.path.forEach((path, index) => {
if (diff2.path && index === diff2.path.length - 1) {
if (diff2.kind === "E" || diff2.kind === "D") {
dataToEdit[path] = diff2.lhs;
} else if (diff2.kind === "N") {
if (Number.isInteger(path)) {
if (Array.isArray(dataToEdit)) {
dataToEdit.splice(path, 1);
}
} else if (typeof path === "string") {
delete dataToEdit[path];
}
} else if (diff2.kind === "A") {
let index2 = diff2.index;
if (diff2.item.kind === "N") {
dataToEdit[path].splice(index2, 1);
} else if (diff2.item.kind === "E" || diff2.item.kind === "D") {
dataToEdit[path][index2] = diff2.item.lhs;
} else if (diff2.item.kind === "A") {
console.warn("[Pixi'VN] Nested array found, skipping diff", diff2);
} else {
console.warn("[Pixi'VN] No array found, skipping diff", diff2);
}
}
} else {
dataToEdit = dataToEdit[path];
}
});
} else {
console.warn("[Pixi'VN] No path found, skipping diff", diff2);
}
});
return result;
}
// src/managers/StorageManager.ts
var _GameStorageManager = class _GameStorageManager {
constructor() {
}
static get keysSystem() {
return {
/**
* The key of the current dialogue memory
*/
CURRENT_DIALOGUE_MEMORY_KEY: "___current_dialogue_memory___",
/**
* The key of the last dialogue added in the step memory
*/
LAST_DIALOGUE_ADDED_IN_STEP_MEMORY_KEY: "___last_dialogue_added_in_step_memory___",
/**
* The key of the current menu options memory
*/
CURRENT_MENU_OPTIONS_MEMORY_KEY: "___current_menu_options_memory___",
/**
* The key of the last menu options added in the step memory
*/
LAST_MENU_OPTIONS_ADDED_IN_STEP_MEMORY_KEY: "___last_menu_options_added_in_step_memory___",
/**
* The key of the characters memory
*/
CHARACTER_CATEGORY_KEY: "___character___",
/**
* The key of the flags memory
*/
FLAGS_CATEGORY_KEY: "___flags___",
/**
* This variable is used to add the next dialog text into the current dialog memory.
* This value was added to introduce Ink Glue functionality https://github.com/inkle/ink/blob/master/Documentation/WritingWithInk.md#glue
*/
ADD_NEXT_DIALOG_TEXT_INTO_THE_CURRENT_DIALOG_FLAG_KEY: "___glue___"
};
}
/**
* Set a variable in the storage
* @param key The key of the variable
* @param value The value of the variable. If undefined, the variable will be removed
* @returns
*/
static setVariable(key, value) {
key = key.toLowerCase();
if (value === void 0 || value === null) {
if (_GameStorageManager.storage.hasOwnProperty(key)) {
delete _GameStorageManager.storage[key];
}
return;
}
_GameStorageManager.storage[key] = value;
}
/**
* Get a variable from the storage
* @param key The key of the variable
* @returns The value of the variable. If the variable does not exist, it will return undefined
*/
static getVariable(key) {
key = key.toLowerCase();
if (_GameStorageManager.storage.hasOwnProperty(key)) {
return _GameStorageManager.storage[key];
}
return void 0;
}
/**
* Remove a variable from the storage
* @param key The key of the variable
* @returns
*/
static removeVariable(key) {
key = key.toLowerCase();
if (_GameStorageManager.storage.hasOwnProperty(key)) {
delete _GameStorageManager.storage[key];
}
}
/**
* Clear the storage and the oidsUsed
* @returns
*/
static clear() {
_GameStorageManager.storage = {};
}
static exportJson() {
return JSON.stringify(this.export());
}
static export() {
return createExportableElement(_GameStorageManager.storage);
}
static importJson(dataString) {
_GameStorageManager.import(JSON.parse(dataString));
}
static import(data) {
_GameStorageManager.clear();
try {
if (data) {
_GameStorageManager.storage = data;
} else {
console.warn("[Pixi'VN] No storage data found");
}
} catch (e) {
console.error("[Pixi'VN] Error importing data", e);
}
}
};
_GameStorageManager.storage = {};
var GameStorageManager = _GameStorageManager;
// src/functions/EasterEgg.ts
function asciiArtLog() {
console.info(`
____ _ _ ___ ___ _
| _ \\(_)_ _(_| ) \\ / / \\ | |
| |_) | \\ \\/ / |/ \\ \\ / /| \\| |
| __/| |> <| | \\ V / | |\\ |
|_| |_/_/\\_\\_| \\_/ |_| \\_|
`);
}
// src/types/ticker/TagToRemoveAfterType.ts
var tagToRemoveAfter = "tagToRemoveAfter";
// src/managers/WindowManager.ts
var _GameWindowManager = class _GameWindowManager {
constructor() {
}
/**
* The PIXI Application instance.
* It not recommended to use this property directly.
*/
static get app() {
if (!_GameWindowManager._app) {
throw new Error("[Pixi'VN] GameWindowManager.app is undefined");
}
return _GameWindowManager._app;
}
/**
* If the manager is initialized.
*/
static get isInitialized() {
return _GameWindowManager._isInitialized;
}
static get screen() {
return _GameWindowManager.app.screen;
}
/**
* Initialize the PIXI Application and the interface div.
* This method should be called before any other method.
* @param element The html element where I will put the canvas. Example: document.body
* @param width The width of the canvas
* @param height The height of the canvas
* @param options The options of PIXI Application
* @example
* ```typescript
* const body = document.body
* if (!body) {
* throw new Error('body element not found')
* }
* await GameWindowManager.initialize(body, 1920, 1080, {
* backgroundColor: "#303030"
* })
* ```
*/
static initialize(element, width, height, options) {
return __async(this, null, function* () {
_GameWindowManager.canvasWidth = width;
_GameWindowManager.canvasHeight = height;
_GameWindowManager._app = new pixi_js.Application();
return _GameWindowManager.app.init(__spreadValues({
resolution: window.devicePixelRatio || 1,
autoDensity: true,
width,
height
}, options)).then(() => {
devtools.initDevtools({ app: _GameWindowManager._app });
_GameWindowManager._isInitialized = true;
this.addCanvasIntoHTMLElement(element);
window.addEventListener("resize", _GameWindowManager.resize);
_GameWindowManager.resize();
asciiArtLog();
});
});
}
/**
* Add the canvas into a html element.
* @param element it is the html element where I will put the canvas. Example: document.body
*/
static addCanvasIntoHTMLElement(element) {
if (_GameWindowManager.isInitialized) {
element.appendChild(_GameWindowManager.app.canvas);
} else {
console.error("[Pixi'VN] GameWindowManager is not initialized");
}
}
/**
* Initialize the interface div and add it into a html element.
* @param element it is the html element where I will put the interface div. Example: document.getElementById('root')
* @example
* ```tsx
* const root = document.getElementById('root')
* if (!root) {
* throw new Error('root element not found')
* }
* GameWindowManager.initializeHTMLLayout(root)
* const reactRoot = createRoot(GameWindowManager.htmlLayout)
* reactRoot.render(
* <App />
* )
* ```
*/
static initializeHTMLLayout(element) {
let div = document.createElement("div");
div.style.position = "absolute";
div.style.pointerEvents = "none";
element.appendChild(div);
_GameWindowManager.htmlLayout = div;
_GameWindowManager.resize();
}
/* Resize Metods */
/**
* This method returns the scale of the screen.
*/
static get screenScale() {
let screenWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
let screenHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
return Math.min(screenWidth / _GameWindowManager.canvasWidth, screenHeight / _GameWindowManager.canvasHeight);
}
/**
* This method returns the width of the screen enlarged by the scale.
*/
static get screenWidth() {
return Math.floor(_GameWindowManager.screenScale * _GameWindowManager.canvasWidth);
}
/**
* This method returns the height of the screen enlarged by the scale.
*/
static get screenHeight() {
return Math.floor(_GameWindowManager.screenScale * _GameWindowManager.canvasHeight);
}
/**
* This method returns the horizontal margin of the screen.
*/
static get horizontalMargin() {
let screenWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
return (screenWidth - _GameWindowManager.screenWidth) / 2;
}
/**
* This method returns the vertical margin of the screen.
*/
static get verticalMargin() {
let screenHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
return (screenHeight - _GameWindowManager.screenHeight) / 2;
}
/**
* This method is called when the screen is resized.
*/
static resize() {
if (_GameWindowManager.isInitialized) {
let style = _GameWindowManager.app.canvas.style;
style.width = `${_GameWindowManager.screenWidth}px`;
style.height = `${_GameWindowManager.screenHeight}px`;
style.marginLeft = `${_GameWindowManager.horizontalMargin}px`;
style.marginRight = `${_GameWindowManager.horizontalMargin}px`;
style.marginTop = `${_GameWindowManager.verticalMargin}px`;
style.marginBottom = `${_GameWindowManager.verticalMargin}px`;
}
if (_GameWindowManager.htmlLayout) {
_GameWindowManager.htmlLayout.style.width = `${_GameWindowManager.screenWidth}px`;
_GameWindowManager.htmlLayout.style.height = `${_GameWindowManager.screenHeight}px`;
_GameWindowManager.htmlLayout.style.marginLeft = `${_GameWindowManager.horizontalMargin}px`;
_GameWindowManager.htmlLayout.style.marginRight = `${_GameWindowManager.horizontalMargin}px`;
_GameWindowManager.htmlLayout.style.marginTop = `${_GameWindowManager.verticalMargin}px`;
_GameWindowManager.htmlLayout.style.marginBottom = `${_GameWindowManager.verticalMargin}px`;
}
}
/* Edit Canvas Elements Methods */
/**
* This is a dictionary that contains all Canvas Elements of Canvas, currently.
*/
static get currentCanvasElements() {
return _GameWindowManager._children;
}
/**
* Add a canvas element to the canvas.
* If there is a canvas element with the same tag, it will be removed.
* @param tag The tag of the canvas element.
* @param canvasElement The canvas elements to be added.
* @example
* ```typescript
* const texture = await Assets.load('https://pixijs.com/assets/bunny.png');
* const sprite = CanvasSprite.from(texture);
* GameWindowManager.addCanvasElement("bunny", sprite);
* ```
*/
static addCanvasElement(tag, canvasElement) {
if (_GameWindowManager._children[tag]) {
_GameWindowManager.removeCanvasElement(tag);
}
_GameWindowManager.app.stage.addChild(canvasElement);
_GameWindowManager._children[tag] = canvasElement;
_GameWindowManager.childrenTagsOrder.push(tag);
}
/**
* Remove a canvas element from the canvas.
* And remove all tickers that are not connected to any canvas element.
* @param tags The tag of the canvas element to be removed.
* @returns
* @example
* ```typescript
* GameWindowManager.removeCanvasElement("bunny");
* ```
*/
static removeCanvasElement(tags) {
if (typeof tags === "string") {
tags = [tags];
}
tags.forEach((tag) => {
if (_GameWindowManager._children[tag]) {
_GameWindowManager.app.stage.removeChild(_GameWindowManager._children[tag]);
delete _GameWindowManager._children[tag];
_GameWindowManager.removeTickerByCanvasElement(tag);
}
});
_GameWindowManager.childrenTagsOrder = _GameWindowManager.childrenTagsOrder.filter((t) => !tags.includes(t));
}
/**
* Get a canvas element by the tag.
* @param tag The tag of the canvas element.
* @returns The canvas element.
* @example
* ```typescript
* const sprite = GameWindowManager.getCanvasElement<CanvasSprite>("bunny");
* ```
*/
static getCanvasElement(tag) {
return _GameWindowManager._children[tag];
}
/**
* Check if a DisplayObject is on the canvas.
* @param pixiElement The DisplayObject to be checked.
* @returns If the DisplayObject is on the canvas.
*/
static canvasElementIsOnCanvas(pixiElement) {
return _GameWindowManager.app.stage.children.includes(pixiElement);
}
/**
* Remove all canvas elements from the canvas.
* And remove all tickers that are not connected to any canvas element.
*/
static removeCanvasElements() {
_GameWindowManager.app.stage.removeChildren();
_GameWindowManager._children = {};
_GameWindowManager.childrenTagsOrder = [];
_GameWindowManager.removeAllTickers();
}
/**
* Edit the tag of a canvas element.
* @param oldTag The old tag of the canvas element.
* @param newTag The new tag of the canvas element.
*/
static editCanvasElementTag(oldTag, newTag) {
if (_GameWindowManager._children[oldTag]) {
_GameWindowManager._children[newTag] = _GameWindowManager._children[oldTag];
delete _GameWindowManager._children[oldTag];
}
if (_GameWindowManager._currentTickersSteps[oldTag]) {
_GameWindowManager._currentTickersSteps[newTag] = _GameWindowManager._currentTickersSteps[oldTag];
delete _GameWindowManager._currentTickersSteps[oldTag];
}
for (let id in _GameWindowManager._currentTickers) {
let ticker = _GameWindowManager._currentTickers[id];
if (ticker.canvasElementTags.includes(oldTag)) {
ticker.canvasElementTags = ticker.canvasElementTags.map((t) => t === oldTag ? newTag : t);
if (ticker.args.hasOwnProperty(tagToRemoveAfter)) {
let tagToRemoveAfter2 = ticker.args.tagToRemoveAfter;
if (typeof tagToRemoveAfter2 === "string") {
tagToRemoveAfter2 = [tagToRemoveAfter2];
}
if (Array.isArray(tagToRemoveAfter2)) {
ticker.args.tagToRemoveAfter = tagToRemoveAfter2.map((t) => t === oldTag ? newTag : t);
}
}
}
}
for (let timeout in _GameWindowManager._currentTickersTimeouts) {
let TickerTimeout = _GameWindowManager._currentTickersTimeouts[timeout];
if (TickerTimeout.tags.includes(oldTag)) {
TickerTimeout.tags = TickerTimeout.tags.map((t) => t === oldTag ? newTag : t);
}
}
}
/** Edit Tickers Methods */
/**
* Currently tickers that are running.
*/
static get currentTickers() {
return _GameWindowManager._currentTickers;
}
static get currentTickersList() {
return Object.values(_GameWindowManager._currentTickers);
}
static get currentTickersWithoutCreatedBySteps() {
return Object.fromEntries(Object.entries(_GameWindowManager._currentTickers).filter(([_, ticker]) => !ticker.createdByTicketStepsId));
}
/**
* The steps of the tickers
*/
static get currentTickersSteps() {
return _GameWindowManager._currentTickersSteps;
}
static generateTickerId(tickerData) {
try {
return sha1__default.default(JSON.stringify(tickerData)).toString() + "_" + Math.random().toString(36).substring(7);
} catch (e) {
throw new Error(`[Pixi'VN] Error to generate ticker id: ${e}`);
}
}
/**
* Run a ticker. You can run multiple addTicker with the same tag and different tickerClasses.
* If you run a ticker with the same tag and tickerClass, the old ticker will be removed.
* If already exists a sequence of tickers with the same tag, it will be removed.
* @param canvasEslementTag The tag of the canvas element that will use the ticker.
* @param ticker The ticker class to be run.
* @param args The arguments to be used in the ticker.
* @param duration The time to be used in the ticker. This number is in seconds. If it is undefined, the ticker will run forever.
* @param priority The priority to be used in the ticker.
* @returns
* @example
* ```typescript
* GameWindowManager.addTicker("alien", new RotateTicker({ speed: 0.2 }))
* ```
*/
static addTicker(canvasElementTag, ticker) {
let tickerId = ticker.id;
if (typeof canvasElementTag === "string") {
canvasElementTag = [canvasElementTag];
}
if (!geTickerInstanceById(tickerId, ticker.args, ticker.duration, ticker.priority)) {
console.error(`[Pixi'VN] Ticker ${tickerId} not found`);
return;
}
let tickerHistory = {
fn: () => {
},
id: tickerId,
args: createExportableElement(ticker.args),
canvasElementTags: canvasElementTag,
priority: ticker.priority,
duration: ticker.duration
};
let id = _GameWindowManager.generateTickerId(tickerHistory);
_GameWindowManager.pushTicker(id, tickerHistory, ticker);
if (ticker.duration) {
let timeout = setTimeout(() => {
_GameWindowManager.removeTickerTimeoutInfo(timeout);
let tickerTimeoutInfo = _GameWindowManager._currentTickersTimeouts[timeout.toString()];
if (tickerTimeoutInfo) {
_GameWindowManager.removeTicker(id);
}
}, ticker.duration * 1e3);
_GameWindowManager.addTickerTimeoutInfo(canvasElementTag, tickerId, timeout.toString(), true);
}
}
static pushTicker(id, tickerData, ticker) {
_GameWindowManager.removeAssociationBetweenTickerCanvasElement(tickerData.canvasElementTags, ticker);
_GameWindowManager._currentTickers[id] = tickerData;
tickerData.fn = (t) => {
let data = _GameWindowManager._currentTickers[id];
if (data) {
ticker == null ? void 0 : ticker.fn(t, data.args, data.canvasElementTags, id);
}
};
_GameWindowManager.app.ticker.add(tickerData.fn, void 0, tickerData.priority);
}
/**
* Run a sequence of tickers. If exists a ticker steps with the same tag, it will be removed.
* @param tag The tag of canvas element that will use the tickers.
* @param steps The steps of the tickers.
* @param currentStepNumber The current step number. It is used to continue the sequence of tickers.
* @returns
* @example
* ```typescript
* GameWindowManager.addTickersSteps("alien", [
* new RotateTicker({ speed: 0.1, clockwise: true }, 2), // 2 seconds
* Pause(1), // 1 second
* new RotateTicker({ speed: 0.2, clockwise: false }, 2),
* Repeat,
* ])
* ```
*/
static addTickersSteps(tag, steps, currentStepNumber = 0) {
if (steps.length == 0) {
console.warn("[Pixi'VN] The steps of the tickers is empty");
return;
}
_GameWindowManager.removeTickerStepByCanvasElement(tag);
_GameWindowManager._currentTickersSteps[tag] = {
currentStepNumber,
steps: steps.map((step) => {
if (step === Repeat) {
return step;
}
if (step.hasOwnProperty("type") && step.type === "pause") {
return step;
}
let tickerId = step.id;
return {
ticker: tickerId,
args: createExportableElement(step.args),
duration: step.duration
};
})
};
_GameWindowManager.runTickersSteps(tag);
}
static restoneTickersSteps(data) {
for (let tag in data) {
let steps = data[tag];
_GameWindowManager._currentTickersSteps[tag] = steps;
_GameWindowManager.runTickersSteps(tag);
}
}
static runTickersSteps(tag) {
let step = _GameWindowManager._currentTickersSteps[tag].steps[_GameWindowManager._currentTickersSteps[tag].currentStepNumber];
if (step === Repeat) {
step = _GameWindowManager._currentTickersSteps[tag].steps[0];
_GameWindowManager._currentTickersSteps[tag].currentStepNumber = 0;
if (step === Repeat) {
console.error("[Pixi'VN] TikersSteps has a RepeatType in the first step");
return;
}
}
if (step.hasOwnProperty("type") && step.type === "pause") {
let timeout = setTimeout(() => {
let tickerTimeoutInfo = _GameWindowManager._currentTickersTimeouts[timeout.toString()];
if (tickerTimeoutInfo) {
tickerTimeoutInfo.tags.forEach((tag2) => {
_GameWindowManager.nextTickerStep(tag2);
});
}
_GameWindowManager.removeTickerTimeoutInfo(timeout);
}, step.duration * 1e3);
_GameWindowManager.addTickerTimeoutInfo(tag, "steps", timeout.toString(), false);
return;
}
let ticker = geTickerInstanceById(step.ticker, step.args, step.duration, step.priority);
if (!ticker) {
console.error(`[Pixi'VN] Ticker ${step.ticker} not found`);
return;
}
let tickerName = ticker.id;
let tickerHistory = {
fn: () => {
},
id: tickerName,
args: createExportableElement(ticker.args),
canvasElementTags: [tag],
priority: ticker.priority,
duration: ticker.duration,
createdByTicketStepsId: tag
};
let id = _GameWindowManager.generateTickerId(tickerHistory);
_GameWindowManager.pushTicker(id, tickerHistory, ticker);
if (ticker.duration) {
let timeout = setTimeout(() => {
let tickerTimeoutInfo = _GameWindowManager._currentTickersTimeouts[timeout.toString()];
if (tickerTimeoutInfo) {
_GameWindowManager.removeTicker(id);
tickerTimeoutInfo.tags.forEach((tag2) => {
_GameWindowManager.nextTickerStep(tag2);
});
}
_GameWindowManager.removeTickerTimeoutInfo(timeout);
}, ticker.duration * 1e3);
_GameWindowManager.addTickerTimeoutInfo(tag, tickerName, timeout.toString(), false);
}
}
static nextTickerStep(tag) {
if (_GameWindowManager._currentTickersSteps[tag]) {
let steps = _GameWindowManager._currentTickersSteps[tag];
if (steps.currentStepNumber + 1 < steps.steps.length) {
steps.currentStepNumber++;
_GameWindowManager._currentTickersSteps[tag] = steps;
_GameWindowManager.runTickersSteps(tag);
} else {
_GameWindowManager.removeTickerStepByCanvasElement(tag);
}
}
}
static onEndOfTicker(canvasElementTags, ticker, canvasElementTagsToDelete, tickerId) {
let tickerData = _GameWindowManager._currentTickers[tickerId];
_GameWindowManager.removeAssociationBetweenTickerCanvasElement(canvasElementTags, ticker);
_GameWindowManager.removeCanvasElement(canvasElementTagsToDelete);
if (tickerData) {
_GameWindowManager.removeTicker(tickerId);
if (tickerData.duration == void 0 && tickerData.createdByTicketStepsId) {
_GameWindowManager.nextTickerStep(tickerData.createdByTicketStepsId);
}
}
}
/**
* Remove a connection between a canvas element and a ticker.
* And remove the ticker if there is no canvas element connected to it.
* @param tags The tag of the canvas element that will use the ticker.
* @param ticker The ticker class to be removed.
* @example
* ```typescript
* GameWindowManager.removeAssociationBetweenTickerCanvasElement("alien", RotateTicker)
* ```
*/
static removeAssociationBetweenTickerCanvasElement(tags, ticker) {
let tickerId;
if (typeof ticker === "string") {
tickerId = ticker;
} else if (ticker instanceof TickerBase) {
tickerId = ticker.id;
} else {
tickerId = ticker.prototype.id;
}
if (typeof tags === "string") {
tags = [tags];
}
for (let id in _GameWindowManager._currentTickers) {
let ticker2 = _GameWindowManager._currentTickers[id];
if (ticker2.id === tickerId) {
_GameWindowManager._currentTickers[id].canvasElementTags = ticker2.canvasElementTags.filter((e) => !tags.includes(e));
}
}
for (let timeout in _GameWindowManager._currentTickersTimeouts) {
let TickerTimeout = _GameWindowManager._currentTickersTimeouts[timeout];
if (TickerTimeout.ticker === tickerId && TickerTimeout.canBeDeletedBeforeEnd) {
_GameWindowManager._currentTickersTimeouts[timeout].tags = TickerTimeout.tags.filter((t) => !tags.includes(t));
}
}
_GameWindowManager.removeTickersWithoutAssociatedCanvasElement();
}
/**
* Remove all tickers that are not connected to any existing canvas element.
*/
static removeTickersWithoutAssociatedCanvasElement() {
for (let id in _GameWindowManager._currentTickers) {
let ticker = _GameWindowManager._currentTickers[id];
ticker.canvasElementTags = ticker.canvasElementTags.filter((e) => _GameWindowManager._children[e]);
if (ticker.canvasElementTags.length === 0) {
_GameWindowManager.removeTicker(id);
}
}
for (let tag in _GameWindowManager._currentTickersSteps) {
if (_GameWindowManager._children[tag] === void 0) {
delete _GameWindowManager._currentTickersSteps[tag];
}
}
Object.entries(_GameWindowManager._currentTickersTimeouts).forEach(([timeout, { tags }]) => {
if (tags.length === 0) {
_GameWindowManager.removeTickerTimeout(timeout);
}
});
}
static addTickerTimeoutInfo(tags, ticker, timeout, canBeDeletedBeforeEnd) {
if (typeof tags === "string") {
tags = [tags];
}
_GameWindowManager._currentTickersTimeouts[timeout] = {
tags,
ticker,
canBeDeletedBeforeEnd
};
}
static removeTickerTimeoutInfo(timeout) {
if (typeof timeout !== "string") {
timeout = timeout.toString();
}
if (_GameWindowManager._currentTickersTimeouts[timeout]) {
delete _GameWindowManager._currentTickersTimeouts[timeout];
}
}
static removeTickerTimeout(timeout) {
if (typeof timeout !== "string") {
timeout = timeout.toString();
}
clearTimeout(Number(timeout));
_GameWindowManager.removeTickerTimeoutInfo(timeout);
}
static removeTickerTimeoutsByTag(tag, checkCanBeDeletedBeforeEnd) {
for (let timeout in _GameWindowManager._currentTickersTimeouts) {
let tagsWithoutTagToRemove = _GameWindowManager._currentTickersTimeouts[timeout].tags.filter((t) => t !== tag);
if (tagsWithoutTagToRemove.length === 0) {
let canBeDeletedBeforeEnd = _GameWindowManager._currentTickersTimeouts[timeout].canBeDeletedBeforeEnd;
if (!checkCanBeDeletedBeforeEnd || canBeDeletedBeforeEnd) {
_GameWindowManager.removeTickerTimeout(timeout);
}
} else {
_GameWindowManager._currentTickersTimeouts[timeout].tags = tagsWithoutTagToRemove;
}
}
}
/**
* Remove all tickers from the canvas.
*/
static removeAllTickers() {
_GameWindowManager._currentTickersSteps = {};
Object.keys(_GameWindowManager._currentTickers).forEach((id) => {
_GameWindowManager.removeTicker(id);
});
_GameWindowManager._currentTickers = {};
for (let timeout in _GameWindowManager._currentTickersTimeouts) {
_GameWindowManager.removeTickerTimeout(timeout);
}
}
/**
* Remove all tickers from a canvas element.
* @param tag The tag of the canvas element that will use the ticker.
*/
static removeTickerByCanvasElement(tag) {
if (typeof tag === "string") {
tag = [tag];
}
tag.forEach((tag2) => {
for (let id in _GameWindowManager._currentTickers) {
let ticker = _GameWindowManager._currentTickers[id];
if (ticker.canvasElementTags.includes(tag2)) {
_GameWindowManager.removeTicker(id);
}
}
if (_GameWindowManager._currentTickersSteps[tag2]) {
delete _GameWindowManager._currentTickersSteps[tag2];
}
_GameWindowManager.removeTickerTimeoutsByTag(tag2, false);
delete _GameWindowManager._currentTickersSteps[tag2];
});
}
static removeTickerStepByCanvasElement(tag) {
if (_GameWindowManager._currentTickersSteps[tag]) {
delete _GameWindowManager._currentTickersSteps[tag];
}
for (let id in _GameWindowManager._currentTickers) {
let ticker = _GameWindowManager._currentTickers[id];
if (ticker.createdByTicketStepsId === tag) {
_GameWindowManager.removeTicker(id);
}
}
}
static removeTicker(tickerId) {
let ticker = _GameWindowManager._currentTickers[tickerId];
if (ticker) {
if (ticker.args.hasOwnProperty(tagToRemoveAfter)) {
let tagToRemoveAfter2 = ticker.args.tagToRemoveAfter;
_GameWindowManager.removeCanvasElement(tagToRemoveAfter2);
}
_GameWindowManager.app.ticker.remove(ticker.fn);
delete _GameWindowManager._currentTickers[tickerId];
}
}
/**
* Clear the canvas and the tickers.
*/
static clear() {
_GameWindowManager.removeCanvasElements();
}
/* Export and Import Methods */
/**
* Export the canvas and the tickers to a JSON string.
* @returns The JSON string.
*/
static exportJson() {
return JSON.stringify(this.export());
}
/**
* Export the canvas and the tickers to an object.
* @returns The object.
*/
static export() {
let currentElements = {};
for (let tag in _GameWindowManager._children) {
currentElements[tag] = exportCanvasElement(_GameWindowManager._children[tag]);
}
return {
currentTickers: createExportableElement(_GameWindowManager.currentTickersWithoutCreatedBySteps),
currentTickersSteps: createExportableElement(_GameWindowManager._currentTickersSteps),
currentElements: createExportableElement(currentElements),
childrenTagsOrder: createExportableElement(_GameWindowManager.childrenTagsOrder)
};
}
/**
* Import the canvas and the tickers from a JSON string.
* @param dataString The JSON string.
*/
static importJson(dataString) {
_GameWindowManager.import(JSON.parse(dataString));
}
/**
* Import the canvas and the tickers from an object.
* @param data The object.
*/
static import(data) {
_GameWindowManager.clear();
try {
if (data.hasOwnProperty("childrenTagsOrder") && data.hasOwnProperty("currentElements")) {
let currentElements = data["currentElements"];
let childrenTagsOrder = data["childrenTagsOrder"];
childrenTagsOrder.forEach((tag) => {
if (currentElements[tag]) {
let element = importCanvasElement(currentElements[tag]);
_GameWindowManager.addCanvasElement(tag, element);
_GameWindowManager.childrenTagsOrder.push(tag);
}
});
} else {
console.error("[Pixi'VN] The data does not have the properties childrenTagsOrder and currentElements");
return;
}
if (data.hasOwnProperty("currentTickers")) {
let currentTickers = data["currentTickers"];
for (let id in currentTickers) {
let t = currentTickers[id];
let tags = t.canvasElementTags;
let ticker = geTickerInstanceById(t.id, t.args, t.duration, t.priority);
if (ticker) {
_GameWindowManager.addTicker(tags, ticker);
} else {
console.error(`[Pixi'VN] Ticker ${t.id} not found`);
}
}
}
if (data.hasOwnProperty("currentTickersSteps")) {
let currentTickersSteps = data["currentTickersSteps"];
_GameWindowManager.restoneTickersSteps(currentTickersSteps);
}
} catch (e) {
console.error("[Pixi'VN] Error importing data", e);
}
}
};
_GameWindowManager._app = void 0;
_GameWindowManager._isInitialized = false;
_GameWindowManager._children = {};
/**
* The order of the children tags.
*/
_GameWindowManager.childrenTagsOrder = [];
_GameWindowManager._currentTickers = {};
_GameWindowManager._currentTickersSteps = {};
_GameWindowManager._currentTickersTimeouts = {};
var GameWindowManager = _GameWindowManager;
// src/managers/StepManager.ts
var _GameStepManager = class _GameStepManager {
constructor() {
}
static get stepsHistory() {
return _GameStepManager._stepsHistory;
}
/**
* lastStepIndex is the last step index that occurred during the progression of the steps. **Not is the length of the stepsHistory - 1.**
*/
static get lastStepIndex() {
return _GameStepManager._lastStepIndex;
}
/**
* Increase the last step index that occurred during the progression of the steps.
*/
static increaseLastStepIndex() {
_GameStepManager._lastStepIndex++;
}
static get openedLabels() {
return _GameStepManager._openedLabels;
}
/**
* currentLabelId is the current label id that occurred during the progression of the steps.
*/
static get currentLabelId() {
if (_GameStepManager._openedLabels.length > 0) {
let item = _GameStepManager._openedLabels[_GameStepManager._openedLabels.length - 1];
return item.label;
}
return void 0;
}
/**
* currentLabel is the current label that occurred during the progression of the steps.
*/
static get currentLabel() {
if (_GameStepManager.currentLabelId) {
return getLabelById(_GameStepManager.currentLabelId);
}
}
static get currentLabelStepIndex() {
if (_GameStepManager._openedLabels.length > 0) {
let item = _GameStepManager._openedLabels[_GameStepManager._openedLabels.length - 1];
return item.currentStepIndex;
}
return null;
}
/**
* lastHistoryStep is the last history step that occurred during the progression of the steps.
*/
static get lastHistoryStep() {
if (_GameStepManager._stepsHistory.length > 0) {
return _GameStepManager._stepsHistory[_GameStepManager._stepsHistory.length - 1];
}
return null;
}
static get originalStepData() {
if (!_GameStepManager._originalStepData) {
return {
path: "",
storage: {},
canvas: {
childrenTagsOrder: [],
currentElements: {},
currentTickers: {},
currentTickersSteps: {}
},
labelIndex: -1,
openedLabels: []
};
}
return createExportableElement(_GameStepManager._originalStepData);
}
static set originalStepData(value) {
_GameStepManager._originalStepData = createExportableElement(value);
}
static get currentStepData() {
let currentStepData = {
path: window.location.pathname,
storage: GameStorageManager.export(),
canvas: GameWindowManager.export(),
labelIndex: _GameStepManager.currentLabelStepIndex || 0,
openedLabels: createExportableElement(_GameStepManager._openedLabels)
};
return currentStepData;
}
/* Edit History Methods */
/**
* Add a label to the history.
* @param label The label to add to the history.
*/
static addStepHistory(step, choiseMade) {
let stepHistory = getStepSha1(step);
let currentStepData = _GameStepManager.currentStepData;
if (_GameStepManager.originalStepData) {
if (_GameStepManager.originalStepData.openedLabels.length === currentStepData.openedLabels.length) {
try {
let lastStepDataOpenedLabelsString = JSON.stringify(_GameStepManager.originalStepData.openedLabels);
let historyStepOpenedLabelsString = JSON.stringify(currentStepData.openedLabels);
if (lastStepDataOpenedLabelsString === historyStepOpenedLabelsString && _GameStepManager.originalStepData.path === currentStepData.path && _GameStepManager.originalStepData.labelIndex === currentStepData.labelIndex) {
return;
}
} catch (e) {
console.error("[Pixi'VN] Error comparing openedLabels", e);
}
}
}
let data = deepDiff.diff(_GameStepManager.originalStepData, currentStepData);
if (data) {
let dialoge = void 0;
let requiredChoices = void 0;
if (GameStorageManager.getVariable(GameStorageManager.keysSystem.LAST_DIALOGUE_ADDED_IN_STEP_MEMORY_KEY) === _GameStepManager.lastStepIndex) {
dialoge = getDialogue();
}
if (GameStorageManager.getVariable(GameStorageManager.keysSystem.LAST_MENU_OPTIONS_ADDED_IN_STEP_MEMORY_KEY) === _GameStepManager.lastStepIndex) {
requiredChoices = GameStorageManager.getVariable(GameStorageManager.keysSystem.CURRENT_MENU_OPTIONS_MEMORY_KEY);
}
_GameStepManager._stepsHistory.push({
diff: data,
currentLabel: _GameStepManager.currentLabelId,
dialoge,
choices: requiredChoices,
stepSha1: stepHistory,
index: _GameStepManager.lastStepIndex,
choiceIndexMade: choiseMade
});
_GameStepManager.originalStepData = currentStepData;
}
_GameStepManager.increaseLastStepIndex();
}
/**
* Add a label to the history.
* @param label The label to add to the history.
*/
static pushNewLabel(label) {
let currentLabel = getLabelById(label);
if (!currentLabel) {
throw new Error(`[Pixi'VN] Label ${label} not found`);
}
_GameStepManager._openedLabels.push({
label,
currentStepIndex: 0
});
}
/**
* Close the current label and add it to the history.
* @returns
*/
static closeCurrentLabel() {
if (!_GameStepManager.currentLabelId) {
console.warn("[Pixi'VN] No label to close");
return;
}
if (!_GameStepManager.currentLabel) {
console.error("[Pixi'VN] currentLabel not found");
return;
}
_GameStepManager._openedLabels.pop();
}
/**
* Close all labels and add them to the history. **Attention: This method can cause an unhandled game ending.**
*/
static closeAllLabels() {
while (_GameStepManager._openedLabels.length > 0) {
_GameStepManager.closeCurrentLabel();
}
}
/**
* Increase the current step index of the current label.
*/
static increaseCurrentStepIndex() {
let item = _GameStepManager._openedLabels[_GameStepManager._openedLabels.length - 1];
_GameStepManager._openedLabels[_GameStepManager._openedLabels.length - 1] = __spreadProps(__spreadValues({}, item), {
currentStepIndex: item.currentStepIndex + 1
});
}
static restorLastLabelList() {
_GameStepManager._openedLabels = _GameStepManager.originalStepData.openedLabels;
}
/* Run Methods */
static get canGoNext() {
let options = getChoiceMenuOptions();
if (options && options.length > 0) {
return false;
}
return true;
}
/**
* Execute the next step and add it to the history.
* @param props The props to pass to the step.
* @param choiseMade The index of the choise made by the player. (This params is used in the choice menu)
* @returns StepLabelResultType or undefined.
* @example
* ```typescript
* function nextOnClick() {
* setLoading(true)
* GameStepManager.goNext(yourParams)
* .then((result) => {
* setUpdate((p) => p + 1)
* setLoading(false)
* if (result) {
* // your code
* }
* })
* .catch((e) => {
* setLoading(false)
* console.error(e)
* })
* }
* ```
*/
static goNext(props, choiseMade) {
return __async(this, null, function* () {
if (!_GameStepManager.canGoNext) {
console.warn("[Pixi'VN] The player must make a choice");
return;
}
if (_GameStepManager.currentLabel && _GameStepManager.currentLabel.onStepEnd) {
yield _GameStepManager.currentLabel.onStepEnd(_GameStepManager.currentLabelStepIndex || 0, _GameStepManager.currentLabel);
}
_GameStepManager.increaseCurrentStepIndex();
return yield _GameStepManager.runCurrentStep(props, choiseMade);
});
}
/**
* Execute the current step and add it to the history.
* @param props The props to pass to the step.
* @param choiseMade The choise made by the player.
* @returns StepLabelResultType or undefined.
*/
static runCurrentStep(props, choiseMade) {
return __async(this, null, function* () {
if (_GameStepManager.currentLabelId) {
let currentLabelStepIndex = _GameStepManager.currentLabelStepIndex;
if (currentLabelStepIndex === null) {
console.error("[Pixi'VN] currentLabelStepIndex is null");
return;
}
let currentLabel = _GameStepManager.currentLabel;
if (!currentLabel) {
console.error("[Pixi'VN] currentLabel not found");
return;
}
if (currentLabel.steps.length > currentLabelStepIndex) {
let onStepRun = currentLabel.onStepStart;
if (onStepRun) {
yield onStepRun(currentLabelStepIndex, currentLabel);
}
let step = currentLabel.steps[currentLabelStepIndex];
let result = yield step(props);
_GameStepManager.addStepHistory(step, choiseMade);
return result;
} else if (_GameStepManager.openedLabels.length > 1) {
_GameStepManager.closeCurrentLabel();
return yield _GameStepManager.goNext(props, choiseMade);
} else {
_GameStepManager.restorLastLabelList();
if (_GameStepManager.gameEnd) {
return yield _GameStepManager.gameEnd(props);
}
console.error("[Pixi'VN] The end of the game is not managed, so the game is blocked. Read this documentation to know how to manage the end of the game: https://pixi-vn.web.app/start/labels.html#how-manage-the-end-of-the-game");
return;
}
}
});
}
/**
* Execute the label and add it to the history. (It's similar to Ren'Py's call function)
* @param label The label to execute or the id of the label
* @param props The props to pass to the label.
* @returns StepLabelResultType or undefined.
* @example
* ```typescript
* GameStepManager.callLabel(startLabel, yourParams).then((result) => {
* if (result) {
* // your code
* }
* })
* ```
* @example
* ```typescript
* // if you use it in a step label you should return the result.
* return GameStepManager.callLabel(startLabel).then((result) => {
* return result
* })
* ```
*/
static callLabel(label, props) {
return __async(this, null, function* () {
let choiseMade = void 0;
let labelId;
if (typeof label === "string") {
labelId = label;
} else {
labelId = label.id;
if (typeof label.choiseIndex === "number") {
choiseMade = label.choiseIndex;
}
}
try {
if (labelId === CLOSE_LABEL_ID) {
let closeCurrentLabel = newCloseLabel(choiseMade);
let choice = {
label: closeCurrentLabel,
text: "",
closeCurrentLabel: false,
type: "close",
props: {}
};
return _GameStepManager.closeChoiceMenu(choice, props);
}
let tempLabel = getLabelById(labelId);
if (!tempLabel) {
throw new Error(`[Pixi'VN] Label ${labelId} not found`);
}
if (_GameStepManager.currentLabel && _GameStepManager.currentLabel.onStepEnd) {
yield _GameStepManager.currentLabel.onStepEnd(_GameStepManager.currentLabelStepIndex || 0, _GameStepManager.currentLabel);
}
_GameStepManager.pushNewLabel(tempLabel.id);
} catch (e) {
console.error("[Pixi'VN] Error calling label", e);
return;
}
return yield _GameStepManager.runCurrentStep(props, choiseMade);
});
}
/**
* Execute the label, close the current label, execute the new label and add the new label to the history. (It's similar to Ren'Py's jump function)
* @param label The label to execute.
* @param props The props to pass to the label or the id of the label
* @returns StepLabelResultType or undefined.
* @example
* ```typescript
* GameStepManager.jumpLabel(startLabel, yourParams).then((result) => {
* if (result) {
* // your code
* }
* })
* ```
* @example
* ```typescript
* // if you use it in a step label you should return the result.
* return GameStepManager.jumpLabel(startLabel).then((result) => {
* return result
* })
* ```
*/
static jumpLabel(label, props) {
return __async(this, null, function* () {
_GameStepManager.closeCurrentLabel();
let choiseMade = void 0;
let labelId;
if (typeof label === "string") {
labelId = label;
} else {
labelId = label.id;
if (typeof label.choiseIndex === "number") {
choiseMade = label.choiseIndex;
}
}
try {
if (labelId === CLOSE_LABEL_ID) {
let closeCurrentLabel = newCloseLabel(choiseMade);
let choice = {
label: closeCurrentLabel,
text: "",
closeCurrentLabel: false,
type: "close",
props: {}
};
return _GameStepManager.closeChoiceMenu(choice, props);
}
let tempLabel = getLabelById(labelId);
if (!tempLabel) {
throw new Error(`[Pixi'VN] Label ${labelId} not found`);
}
if (_GameStepManager.currentLabel && _GameStepManager.currentLabel.onStepEnd) {
yield _GameStepManager.currentLabel.onStepEnd(_GameStepManager.currentLabelStepIndex || 0, _GameStepManager.currentLabel);
}
_GameStepManager.pushNewLabel(tempLabel.id);
} catch (e) {
console.error("[Pixi'VN] Error jumping label", e);
return;
}
return yield _GameStepManager.runCurrentStep(props, choiseMade);
});
}
/**
* When the player is in a choice menu, can use this function to exit to the choice menu.
* @param choice
* @param props
* @returns StepLabelResultType or undefined.
* @example
* ```typescript
* GameStepManager.closeChoiceMenu(yourParams).then((result) => {
* if (result) {
* // your code
* }
* })
* ```
*/
static closeChoiceMenu(choice, props) {
return __async(this, null, function* () {
let label = choice.label;
let choiseMade = void 0;
if (typeof label.choiseIndex === "number") {
choiseMade = label.choiseIndex;
}
if (choice.closeCurrentLabel) {
_GameStepManager.closeCurrentLabel();
}
return _GameStepManager.goNext(props, choiseMade);
});
}
/* After Update Methods */
// /**
// * After the update or code edit, some steps or labels may no longer match.
// * - In case of step mismatch, the game will be updated to the last matching step.
// * - In case of label mismatch, the game gives an error.
// * @returns
// */
// private static afterUpdate() {
// // TODO: implement
// if (!GameStepManager.currentLabel) {
// // TODO: implement
// return
// }
// let currentLabel = getLabelInstanceByClassName(GameStepManager.currentLabel)
// if (!currentLabel) {
// console.error("Label not found")
// return
// }
// let oldSteps = GameStepManager.stepsAfterLastHistoryLabel
// let currentStepIndex = currentLabel.getCorrespondingStepsNumber(oldSteps)
// let stepToRemove = oldSteps.length - currentStepIndex
// GameStepManager.removeLastHistoryNodes(stepToRemove)
// GameStepManager.loadLastStep()
// }
// private static loadLastStep() {
// // TODO: implement
// }
// /**
// * Remove a number of items from the last of the history.
// * @param itemNumber The number of items to remove from the last of the history.
// */
// private static removeLastHistoryNodes(itemNumber: number) {
// // TODO: implement
// for (let i = 0; i < itemNumber; i++) {
// GameStepManager._stepsHistory.pop()
// }
// }
// /**
// * stepsAfterLastHistoryLabel is a list of steps that occurred after the last history label.
// */
// private static get stepsAfterLastHistoryLabel(): StepHistoryDataType[] {
// let length = GameStepManager._stepsHistory.length
// let steps: StepHistoryDataType[] = []
// for (let i = length - 1; i >= 0; i--) {
// let element = GameStepManager._stepsHistory[i]
// if (typeof element === "object" && "stepSha1" in element) {
// steps.push(element.stepSha1)
// }
// else {
// break
// }
// }
// steps = steps.reverse()
// return steps
// }
/* Go Back & Refresh Methods */
/**
* Go back to the last step and add it to the history.
* @param navigate The navigate function.
* @param steps The number of steps to go back.
* @returns
* @example
* ```typescript
* export function goBack(navigate: (path: string) => void, afterBack?: () => void) {
* GameStepManager.goBack(navigate)
* afterBack && afterBack()
* }
* ```
*/
static goBack(navigate, steps = 1) {
return __async(this, null, function* () {
if (steps <= 0) {
console.warn("[Pixi'VN] Steps must be greater than 0");
return;
}
if (_GameStepManager._stepsHistory.length <= 1) {
console.warn("[Pixi'VN] No steps to go back");
return;
}
let restoredStep = _GameStepManager.goBackInternal(steps, _GameStepManager.originalStepData);
if (restoredStep) {
_GameStepManager._originalStepData = restoredStep;
_GameStepManager._openedLabels = createExportableElement(restoredStep.openedLabels);
if (_GameStepManager.currentLabel && _GameStepManager.currentLabel.onLoadStep) {
yield _GameStepManager.currentLabel.onLoadStep(_GameStepManager.currentLabelStepIndex || 0, _GameStepManager.currentLabel);
}
GameStorageManager.import(createExportableElement(restoredStep.storage));
GameWindowManager.import(createExportableElement(restoredStep.canvas));
navigate(restoredStep.path);
} else {
console.error("[Pixi'VN] Error going back");
}
});
}
static goBackInternal(steps, restoredStep) {
if (steps <= 0) {
return restoredStep;
}
if (_GameStepManager._stepsHistory.length == 0) {
return restoredStep;
}
let lastHistoryStep = _GameStepManager.lastHistoryStep;
if (lastHistoryStep) {
try {
let result = restoreDeepDiffChanges(restoredStep, lastHistoryStep.diff);
_GameStepManager._lastStepIndex = lastHistoryStep.index;
_GameStepManager._stepsHistory.pop();
return _GameStepManager.goBackInternal(steps - 1, result);
} catch (e) {
console.error("[Pixi'VN] Error applying diff", e);
return restoredStep;
}
} else {
return restoredStep;
}
}
/**
* Return true if it is possible to go back.
*/
static get canGoBack() {
return _GameStepManager._stepsHistory.length > 1;
}
/**
* Add a label to the history.
*/
static clear() {
_GameStepManager._stepsHistory = [];
_GameStepManager._openedLabels = [];
}
/* Export and Import Methods */
/**
* Export the history to a JSON string.
* @returns The history in a JSON string.
*/
static exportJson() {
return JSON.stringify(this.export());
}
/**
* Export the history to an object.
* @returns The history in an object.
*/
static export() {
return {
stepsHistory: _GameStepManager._stepsHistory,
openedLabels: _GameStepManager._openedLabels,
lastStepIndex: _GameStepManager._lastStepIndex,
originalStepData: _GameStepManager._originalStepData
};
}
/**
* Import the history from a JSON string.
* @param dataString The history in a JSON string.
*/
static importJson(dataString) {
return __async(this, null, function* () {
yield _GameStepManager.import(JSON.parse(dataString));
});
}
/**
* Import the history from an object.
* @param data The history in an object.
*/
static import(data) {
return __async(this, null, function* () {
_GameStepManager.clear();
try {
if (data.hasOwnProperty("stepsHistory")) {
_GameStepManager._stepsHistory = data["stepsHistory"];
} else {
console.warn("[Pixi'VN] Could not import stepsHistory data, so will be ignored");
}
if (data.hasOwnProperty("openedLabels")) {
_GameStepManager._openedLabels = data["openedLabels"];
} else {
console.warn("[Pixi'VN] Could not import openedLabels data, so will be ignored");
}
if (data.hasOwnProperty("lastStepIndex")) {
_GameStepManager._lastStepIndex = data["lastStepIndex"];
} else {
console.warn("[Pixi'VN] Could not import lastStepIndex data, so will be ignored");
}
if (data.hasOwnProperty("originalStepData")) {
_GameStepManager._originalStepData = data["originalStepData"];
} else {
console.warn("[Pixi'VN] Could not import originalStepData data, so will be ignored");
}
if (_GameStepManager.currentLabel && _GameStepManager.currentLabel.onLoadStep) {
yield _GameStepManager.currentLabel.onLoadStep(_GameStepManager.currentLabelStepIndex || 0, _GameStepManager.currentLabel);
}
} catch (e) {
console.error("[Pixi'VN] Error importing data", e);
}
});
}
};
/**
* stepHistory is a list of label events and steps that occurred during the progression of the steps.
*/
_GameStepManager._stepsHistory = [];
_GameStepManager._lastStepIndex = 0;
_GameStepManager._openedLabels = [];
_GameStepManager._originalStepData = void 0;
/**
* Function to be executed at the end of the game. It should be set in the game initialization.
* @example
* ```typescript
* GameStepManager.gameEnd = async (props) => {
* props.navigate("/end")
* }
* ```
*/
_GameStepManager.gameEnd = void 0;
var GameStepManager = _GameStepManager;
// src/classes/StoredClassModel.ts
var StoredClassModel = class {
/**
* @param categoryId The id of the category. For example if you are storing a character class, you can use "characters" as categoryId. so all instances of the character class will be stored in the "characters" category.
* @param id The id of instance of the class. This id must be unique for the category.
*/
constructor(categoryId, id) {
this.categoryId = categoryId;
this._id = id;
}
/**
* Is id of the stored class. is unique for this class.
*/
get id() {
return this._id;
}
/**
* Update a property in the storage.
* @param propertyName The name of the property to set.
* @param value The value to set. If is undefined, the property will be removed from the storage.
*/
setStorageProperty(propertyName, value) {
let storage = GameStorageManager.getVariable(this.categoryId);
if (!storage) {
storage = {};
}
if (!storage.hasOwnProperty(this.id)) {
storage[this.id] = {};
}
if (value === void 0 || value === null) {
if (storage[this.id].hasOwnProperty(propertyName)) {
delete storage[this.id][propertyName];
}
} else {
storage[this.id] = __spreadProps(__spreadValues({}, storage[this.id]), { [propertyName]: value });
}
if (Object.keys(storage[this.id]).length === 0) {
delete storage[this.id];
}
GameStorageManager.setVariable(this.categoryId, storage);
}
/**
* Get a property from the storage.
* @param propertyName The name of the property to get.
* @returns The value of the property. If the property is not found, returns undefined.
*/
getStorageProperty(propertyName) {
let storage = GameStorageManager.getVariable(this.categoryId);
if (storage && storage.hasOwnProperty(this.id) && storage[this.id].hasOwnProperty(propertyName)) {
return storage[this.id][propertyName];
}
return void 0;
}
};
// src/classes/CharacterBaseModel.ts
var CharacterBaseModel2 = class extends StoredClassModel {
/**
* @param id The id of the character.
* @param props The properties of the character.
*/
constructor(id, props) {
super(GameStorageManager.keysSystem.CHARACTER_CATEGORY_KEY, id);
this.defaultName = "";
this.defaultName = props.name;
this.defaultSurname = props.surname;
this.defaultAge = props.age;
this._icon = props.icon;
this._color = props.color;
}
/***
* The name of the character.
* If you set undefined, it will return the default name.
*/
get name() {
return this.getStorageProperty("name") || this.defaultName;
}
set name(value) {
this.setStorageProperty("name", value);
}
/**
* The surname of the character.
* If you set undefined, it will return the default surname.
*/
get surname() {
return this.getStorageProperty("surname") || this.defaultSurname;
}
set surname(value) {
this.setStorageProperty("surname", value);
}
/**
* The age of the character.
* If you set undefined, it will return the default age.
*/
get age() {
return this.getStorageProperty("age") || this.defaultAge;
}
set age(value) {
this.setStorageProperty("age", value);
}
/**
* The icon of the character.
*/
get icon() {
return this._icon;
}
/**
* The color of the character.
*/
get color() {
return this._color;
}
};
// src/classes/DialogueBaseModel.ts
var DialogueBaseModel = class {
/**
* @param text The text of the dialogue.
* @param character The id of the character that is speaking.
* @param oltherParams Other parameters that can be stored in the dialogue.
*/
constructor(text, character, oltherParams = {}) {
/**
* The text of the dialogue.
*/
this.text = "";
/**
* Other parameters that can be stored in the dialogue.
*/
this.oltherParams = {};
if (typeof text === "string") {
this.text = text;
if (typeof character === "string") {
this.character = character;
} else {
this.character = character == null ? void 0 : character.id;
}
this.oltherParams = oltherParams;
} else {
this.text = text.text;
if (text.character) {
this.character = text.character;
}
this.oltherParams = text.oltherParams || {};
}
}
/**
* Export the dialogue to a DialogueBaseData object.
*
* @returns The data of the dialogue.
*/
export() {
return {
text: this.text,
character: this.character,
oltherParams: this.oltherParams
};
}
};
// src/classes/LabelJson.ts
var LabelJson2 = class extends LabelAbstract {
/**
* @param id is the id of the label
* @param steps is the list of steps that the label will perform
* @param props is the properties of the label
*/
constructor(id, steps, props) {
super(id, props);
this._steps = steps;
}
/**
* Get the steps of the label.
*/
get steps() {
if (typeof this._steps === "function") {
return this._steps().map(this.stepConverter);
}
return this._steps.map(this.stepConverter);
}
stepConverter(step) {
return (props) => {
if (step.choices) {
let options = step.choices.map((option) => {
let text = "";
if (Array.isArray(option.text)) {
text = option.text.join();
} else {
text = option.text;
}
return new ChoiceMenuOption(text, option.label, option.props, option.type);
});
setChoiceMenuOptions(options);
} else {
clearChoiceMenuOptions();
}
if (step.glueEnabled) {
setFlag(GameStorageManager.keysSystem.ADD_NEXT_DIALOG_TEXT_INTO_THE_CURRENT_DIALOG_FLAG_KEY, true);
} else if (step.glueEnabled === false) {
setFlag(GameStorageManager.keysSystem.ADD_NEXT_DIALOG_TEXT_INTO_THE_CURRENT_DIALOG_FLAG_KEY, false);
}
if (step.dialog) {
setDialogue(step.dialog);
}
if (step.labelToOpen) {
if (step.labelToOpen.type === "jump") {
GameStepManager.jumpLabel(step.labelToOpen.labelId, props);
} else {
GameStepManager.callLabel(step.labelToOpen.labelId, props);
}
}
if (step.goNextStep) {
GameStepManager.goNext(props);
}
if (step.end === "game_end") {
GameStepManager.closeAllLabels();
GameStepManager.goNext(props);
} else if (step.end === "label_end") {
GameStepManager.closeCurrentLabel();
}
};
}
};
// src/labels/TestConstant.ts
var juliette = new CharacterBaseModel2("___pixivn_juliette___", {
name: "Juliette",
age: 25,
icon: "https://firebasestorage.googleapis.com/v0/b/pixi-vn.appspot.com/o/public%2Fcharacters%2Fjuliette-square.webp?alt=media",
color: "#ac0086"
});
saveCharacter(juliette);
var eggHeadImage = "https://pixijs.com/assets/eggHead.png";
var eggHeadName = `<span style="color:purple">Egg Head</span>`;
var flowerTopImage = "https://pixijs.com/assets/flowerTop.png";
var flowerTopName = `<span style="color:green">Flower Top</span>`;
var helmlokImage = "https://pixijs.com/assets/helmlok.png";
var helmlokName = `<span style="color:blue">Helmlok</span>`;
var skullyImage = "https://pixijs.com/assets/skully.png";
var skullyName = `<span style="color:red">Skully</span>`;
var bunnyImage = "https://pixijs.com/assets/bunny.png";
var bunnyName = `Bunny`;
// src/labels/BaseCanvasElementTestLabel.ts
var BASE_CANVAS_ELEMENT_LABEL = "___pixi_vn_base_canvas_element_label___";
var baseCanvasElementTestLabel = newLabel(
BASE_CANVAS_ELEMENT_LABEL,
[
() => __async(void 0, null, function* () {
let number = 25;
setDialogue({
character: juliette,
text: `Here's what's going to happen: I'm going to create ${number} bunnies (CanvasSprites) and put them in a CanvasContainer.`
});
const container = new CanvasContainer();
GameWindowManager.addCanvasElement("container", container);
const texture = yield pixi_js.Assets.load(bunnyImage);
for (let i = 0; i < number; i++) {
const bunny = new CanvasSprite(texture);
bunny.x = i % 5 * 40;
bunny.y = Math.floor(i / 5) * 40;
container.addChild(bunny);
}
container.x = GameWindowManager.screen.width / 2;
container.y = GameWindowManager.screen.height / 2;
container.pivot.x = container.width / 2;
container.pivot.y = container.height / 2;
GameWindowManager.addTicker("container", new exports.RotateTicker({ speed: 1 }));
}),
() => __async(void 0, null, function* () {
removeCanvasElement("container");
setDialogue({
character: juliette,
text: `Here's what's going to happen: I'm going to create some CanvasText with different styles and put them on the stage.
But it will generate a warn message, because the FillGradient or FillPattern has not yet been supported by the Pixi\u2019VN ( you can see the status of the issue here: [#76](https://github.com/DRincs-Productions/pixi-vn/issues/76)).`
});
const basicStyle = new pixi_js.TextStyle({
fill: "#ffffff"
});
const basicText = new CanvasText({
text: "Basic text in pixi",
style: basicStyle
});
basicText.x = 50;
basicText.y = 100;
GameWindowManager.addCanvasElement("basicText", basicText);
const fill = new pixi_js.FillGradient(0, 0, 0, 36 * 1.7 * 7);
const colors = [16777215, 65433].map((color) => pixi_js.Color.shared.setValue(color).toNumber());
colors.forEach((number, index) => {
const ratio = index / colors.length;
fill.addColorStop(ratio, number);
});
const style = new pixi_js.TextStyle({
fontFamily: "Arial",
fontSize: 36,
fontStyle: "italic",
fontWeight: "bold",
fill: { fill },
stroke: { color: "#4a1850", width: 5, join: "round" },
dropShadow: {
color: "#ff5f74",
blur: 4,
angle: Math.PI / 6,
distance: 6
},
wordWrap: true,
wordWrapWidth: 440
});
const richText = new CanvasText({
text: "Rich text with a lot of options and across multiple lines",
style
});
richText.x = 50;
richText.y = 220;
GameWindowManager.addCanvasElement("richText", richText);
const skewStyle = new pixi_js.TextStyle({
fontFamily: "Arial",
dropShadow: {
alpha: 0.8,
angle: 2.1,
blur: 4,
color: "0x111111",
distance: 10
},
fill: "#ffffff",
stroke: { color: "#004620", width: 12, join: "round" },
fontSize: 60,
fontWeight: "lighter"
});
const skewText = new CanvasText({
text: "SKEW IS COOL",
style: skewStyle
});
skewText.skew.set(0.65, -0.3);
skewText.anchor.set(0.5, 0.5);
skewText.x = 300;
skewText.y = 480;
GameWindowManager.addCanvasElement("skewText", skewText);
})
]
);
var EventTest1 = class extends CanvasEvent {
fn(event, sprite) {
if (event === "pointerdown") {
sprite.scale.x *= 1.25;
sprite.scale.y *= 1.25;
}
}
};
EventTest1 = __decorateClass([
eventDecorator("___pixi_vn_canvas_events_test_event1___")
], EventTest1);
var EventTest2 = class extends CanvasEvent {
fn(event, sprite) {
if (event === "pointerdown") {
sprite.isdown = true;
sprite.texture = pixi_js.Texture.from("https://pixijs.com/assets/button_down.png");
sprite.alpha = 1;
} else if (event === "pointerup" || event === "pointerupoutside") {
sprite.isdown = false;
if (sprite.isOver) {
sprite.texture = pixi_js.Texture.from("https://pixijs.com/assets/button_over.png");
} else {
sprite.texture = pixi_js.Texture.from("https://pixijs.com/assets/button.png");
}
} else if (event === "pointerover") {
sprite.isOver = true;
if (sprite.isdown) {
return;
}
sprite.texture = pixi_js.Texture.from("https://pixijs.com/assets/button_over.png");
} else if (event === "pointerout") {
sprite.isOver = false;
if (sprite.isdown) {
return;
}
sprite.texture = pixi_js.Texture.from("https://pixijs.com/assets/button.png");
}
}
};
EventTest2 = __decorateClass([
eventDecorator("___pixi_vn_canvas_events_test_event2___")
], EventTest2);
var CANVAS_EVENTS_TEST_LABEL = "___pixi_vn_canvas_events_test___";
var canvasEventsTestLabel = newLabel(
CANVAS_EVENTS_TEST_LABEL,
[
() => setDialogue({
character: juliette,
text: "This is the test of clickable elements in a canvas."
}),
() => __async(void 0, null, function* () {
setDialogue({
character: juliette,
text: `This is my friend, ${bunnyName}. It's small now, but if you try to click on it it will get bigger and bigger. (This example is from the official [PixiJS website](https://pixijs.com/8.x/examples/events/click).)`
});
const texture = yield pixi_js.Assets.load(bunnyImage);
const sprite = CanvasSprite.from(texture);
sprite.scale.set(3);
sprite.anchor.set(0.5);
sprite.x = GameWindowManager.screen.width / 2;
sprite.y = GameWindowManager.screen.height / 2;
sprite.eventMode = "static";
sprite.cursor = "pointer";
sprite.onEvent("pointerdown", EventTest1);
GameWindowManager.addCanvasElement("bunny", sprite);
}),
() => __async(void 0, null, function* () {
GameWindowManager.clear();
setDialogue({
character: juliette,
text: `This is the test of buttons in a canvas. (This example is from the official [PixiJS website](https://pixijs.com/8.x/examples/events/interactivity).)`
});
const backgroundT = yield pixi_js.Assets.load("https://pixijs.com/assets/bg_button.jpg");
const background = new CanvasSprite(backgroundT);
background.width = GameWindowManager.screen.width;
background.height = GameWindowManager.screen.height;
GameWindowManager.addCanvasElement("bg", background);
const textureButton = yield pixi_js.Assets.load("https://pixijs.com/assets/button.png");
const buttons = [];
const buttonPositions = [175, 75, 655, 75, 410, 325, 150, 465, 685, 445];
for (let i = 0; i < 5; i++) {
const button = new CanvasSprite(textureButton);
button.anchor.set(0.5);
button.x = buttonPositions[i * 2];
button.y = buttonPositions[i * 2 + 1];
button.eventMode = "static";
button.cursor = "pointer";
button.onEvent("pointerdown", EventTest2).onEvent("pointerup", EventTest2).onEvent("pointerupoutside", EventTest2).onEvent("pointerover", EventTest2).onEvent("pointerout", EventTest2);
GameWindowManager.addCanvasElement("button" + i, button);
buttons.push(button);
}
buttons[0].scale.set(1.2);
buttons[2].rotation = Math.PI / 10;
buttons[3].scale.set(0.8);
buttons[4].scale.set(0.8, 1.2);
buttons[4].rotation = Math.PI;
})
],
{
onLoadStep: () => __async(void 0, null, function* () {
yield pixi_js.Assets.load([
"https://pixijs.com/assets/bg_button.jpg",
"https://pixijs.com/assets/button.png",
"https://pixijs.com/assets/button_down.png",
"https://pixijs.com/assets/button_over.png"
]);
})
}
);
var AlienTintingTest = class extends CanvasSprite {
constructor() {
super(...arguments);
this.direction = 0;
this.turningSpeed = 0;
this.speed = 0;
}
get memory() {
return __spreadProps(__spreadValues({}, super.memory), {
direction: this.direction,
turningSpeed: this.turningSpeed,
speed: this.speed
});
}
set memory(memory) {
super.memory = memory;
this.direction = memory.direction;
this.turningSpeed = memory.turningSpeed;
this.speed = memory.speed;
}
static from(source, skipCache) {
let sprite = pixi_js.Sprite.from(source, skipCache);
let mySprite = new AlienTintingTest();
mySprite.texture = sprite.texture;
return mySprite;
}
};
AlienTintingTest = __decorateClass([
canvasElementDecorator("___pixi_vn_custom_canvas_element___")
], AlienTintingTest);
var TintingTestTicker = class extends TickerBase {
constructor() {
super({});
}
fn(_t, _args, tags) {
tags.forEach((tag) => {
const dudeBoundsPadding = 100;
const dudeBounds = new pixi_js.Rectangle(
-dudeBoundsPadding,
-dudeBoundsPadding,
GameWindowManager.screen.width + dudeBoundsPadding * 2,
GameWindowManager.screen.height + dudeBoundsPadding * 2
);
let dude = GameWindowManager.getCanvasElement(tag);
if (dude && dude instanceof AlienTintingTest) {
dude.direction += dude.turningSpeed * 0.01;
dude.x += Math.sin(dude.direction) * dude.speed;
dude.y += Math.cos(dude.direction) * dude.speed;
dude.rotation = -dude.direction - Math.PI / 2;
if (dude.x < dudeBounds.x) {
dude.x += dudeBounds.width;
} else if (dude.x > dudeBounds.x + dudeBounds.width) {
dude.x -= dudeBounds.width;
}
if (dude.y < dudeBounds.y) {
dude.y += dudeBounds.height;
} else if (dude.y > dudeBounds.y + dudeBounds.height) {
dude.y -= dudeBounds.height;
}
}
});
}
};
TintingTestTicker = __decorateClass([
tickerDecorator("___pixi_vn_custom_ticker___")
], TintingTestTicker);
var CUSTOM_TICKER_CANVAS_ELEMENT_TEST_LABEL = "___pixi_vn_custom_ticker_canvas_element_test___";
var customTickerCanvasElementTestLabel = newLabel(
CUSTOM_TICKER_CANVAS_ELEMENT_TEST_LABEL,
[
() => __async(void 0, null, function* () {
const totalDudes = 100;
for (let i = 0; i < totalDudes; i++) {
const texture = yield pixi_js.Assets.load(eggHeadImage);
const dude = AlienTintingTest.from(texture);
dude.anchor.set(0.5);
dude.scale.set(0.8 + Math.random() * 0.3);
dude.x = Math.random() * GameWindowManager.screen.width;
dude.y = Math.random() * GameWindowManager.screen.height;
dude.tint = Math.random() * 16777215;
dude.direction = Math.random() * Math.PI * 2;
dude.turningSpeed = Math.random() - 0.8;
dude.speed = 2 + Math.random() * 2;
GameWindowManager.addCanvasElement("alien" + i, dude);
GameWindowManager.addTicker("alien" + i, new TintingTestTicker());
}
setDialogue({
character: juliette,
text: `This is a test of custom ticker and canvas element. In this test, we have created ${totalDudes} ${eggHeadName} with random tint, scale, position, direction, turning speed, and speed. With the custom ticker, we are moving the custom canvas element in a random direction. (This example is from the official [PixiJS website](https://pixijs.com/8.x/examples/events/interactivity).)`
});
})
]
);
// src/labels/ImagesAnimationsTestLabel.ts
var IMAGE_ANIMAIONS_TEST_LABEL = "___pixi_vn_images_animations_test___";
var imagesAnimationsTest = newLabel(IMAGE_ANIMAIONS_TEST_LABEL, [
() => __async(void 0, null, function* () {
setDialogue({ character: juliette, text: `These are my 4 puppets: ${eggHeadName}, ${flowerTopName}, ${helmlokName} and ${skullyName}. They can appear, disappear and animate at my will.` });
let eggHead = addImage("eggHead", eggHeadImage);
yield eggHead.load();
eggHead.x = 100;
eggHead.y = 100;
let flowerTop = addImage("flowerTop", flowerTopImage);
flowerTop.x = 300;
flowerTop.y = 100;
flowerTop.load();
let helmlok = addImage("helmlok", helmlokImage);
helmlok.x = 100;
helmlok.y = 300;
let skully = addImage("skully", skullyImage);
skully.x = 300;
skully.y = 300;
yield loadImage([helmlok, skully]);
}),
() => __async(void 0, null, function* () {
setDialogue({ character: juliette, text: "Here's what they can do." });
setChoiceMenuOptions([
new ChoiceMenuOption("Dissolve effect", imagesDissolveTest, {}),
new ChoiceMenuOption("Fade effect", imagesFadeTest, {}),
new ChoiceMenuOption("Rotate", imagesRotateTest, {}),
new ChoiceMenuOption("Move", imagesMoveTest, {}),
new ChoiceMenuOption("Zoom", imagesZoomTest, {}),
new ChoiceMenuOption("Move in/out", imagesMoveInOutTest, {}),
new ChoiceMenuOption("Zoom in/out", imagesZoomInOutTest, {}),
new ChoiceMenuOptionClose("Cancel", true)
]);
}),
(props) => GameStepManager.jumpLabel(IMAGE_ANIMAIONS_TEST_LABEL, props)
]);
var imagesDissolveTest = newLabel("___pixi_vn_images_dissolve_test___", [
() => {
setDialogue({
character: juliette,
text: `Here's what's going to happen:
- ${eggHeadName} will disappear with a dissolve effect. If you go next, ${eggHeadName} reappears with a dissolve effect without stopping the dissolve effect
- ${eggHeadName} will appear instead of ${flowerTopName}.
- ${helmlokName} will disappear with a fade effect and reappear with a fade effect, and repeat.
- ${skullyName} will disappear with a fade effect, wait for 0.5 seconds, and reappear with a fade effect.`
});
removeWithDissolveTransition(["eggHead"], { duration: 2 });
let eggHead = new CanvasImage({ x: 300, y: 100 }, eggHeadImage);
showWithDissolveTransition("flowerTop", eggHead, { duration: 1 });
GameWindowManager.addTickersSteps(
"helmlok",
[
new exports.FadeAlphaTicker({
duration: 1,
type: "hide"
}, 1),
new exports.FadeAlphaTicker({
duration: 1,
type: "show"
}, 1),
Repeat
]
);
GameWindowManager.addTickersSteps(
"skully",
[
new exports.FadeAlphaTicker({
duration: 0.5,
type: "hide",
limit: 0.3
}, 1),
Pause(0.5),
new exports.FadeAlphaTicker({
duration: 1,
type: "show"
}, 1)
]
);
},
() => __async(void 0, null, function* () {
showWithDissolveTransition("eggHead", eggHeadImage, { duration: 0.5 });
})
]);
var imagesFadeTest = newLabel("___pixi_vn_images_fade_test___", [
() => {
setDialogue({
character: juliette,
text: `Here's what's going to happen:
- ${eggHeadName} will disappear with a dissolve effect. If you go next, ${eggHeadName} reappears with a dissolve effect with stopping the dissolve effect
- ${eggHeadName} will appear instead of ${flowerTopName}.
- ${helmlokName} will disappear with a fade effect and reappear with a fade effect, and repeat.
- ${skullyName} will disappear with a fade effect, wait for 0.5 seconds, and reappear with a fade effect.`
});
removeWithFadeTransition(["eggHead"], { duration: 2 });
let eggHead = new CanvasImage({ x: 300, y: 100 }, eggHeadImage);
showWithFadeTransition("flowerTop", eggHead, { duration: 1 });
GameWindowManager.addTickersSteps(
"helmlok",
[
new exports.FadeAlphaTicker({
duration: 1,
type: "hide"
}),
new exports.FadeAlphaTicker({
duration: 1,
type: "show"
}),
Repeat
]
);
GameWindowManager.addTickersSteps(
"skully",
[
new exports.FadeAlphaTicker({
duration: 0.5,
type: "hide",
limit: 0.3
}),
Pause(0.5),
new exports.FadeAlphaTicker({
duration: 1,
type: "show"
})
]
);
},
() => __async(void 0, null, function* () {
let eggHeadOld = GameWindowManager.getCanvasElement("eggHead");
if (eggHeadOld)
eggHeadOld.alpha = 0;
showWithFadeTransition("eggHead", eggHeadImage, { duration: 0.5 });
})
]);
var imagesRotateTest = newLabel("___pixi_vn_images_rotate_test___", [
() => {
setDialogue({
character: juliette,
text: `Here's what's going to happen:
- ${eggHeadName} will rotate with a anchor set to 0.
- ${flowerTopName} will rotate with a anchor set to 0.5 and a exponential speed progression.
- ${helmlokName} will rotate with a anchor set to 0.5, rotate clockwise for 2 seconds, rotate counterclockwise with a exponential (-0.05) speed progression, and when it reaches 0, it will repeat.
- ${skullyName} will rotate with a anchor set to 1, rotate 3 seconds clockwise, wait for 0.5 seconds, and rotate 7 seconds counterclockwise.`
});
let eggHead = GameWindowManager.getCanvasElement("eggHead");
if (eggHead)
eggHead.anchor.set(0);
let flowerTop = GameWindowManager.getCanvasElement("flowerTop");
if (flowerTop)
flowerTop.anchor.set(0.5);
let helmlok = GameWindowManager.getCanvasElement("helmlok");
if (helmlok)
helmlok.anchor.set(0.5);
let skully = GameWindowManager.getCanvasElement("skully");
if (skully)
skully.anchor.set(1);
GameWindowManager.addTicker("eggHead", new exports.RotateTicker({
speed: 6,
clockwise: true
}));
GameWindowManager.addTicker("flowerTop", new exports.RotateTicker({
speed: 6,
clockwise: false,
speedProgression: { type: "exponential", percentage: 0.01, limit: 300 }
}));
GameWindowManager.addTickersSteps("helmlok", [
new exports.RotateTicker({
speed: 6,
clockwise: true
}, 2),
new exports.RotateTicker({
speed: 100,
clockwise: false,
speedProgression: { type: "exponential", percentage: -0.05 }
}),
Repeat
]);
GameWindowManager.addTickersSteps("skully", [
new exports.RotateTicker({
speed: 6,
clockwise: true
}, 3),
Pause(0.5),
new exports.RotateTicker({
speed: 6,
clockwise: false
}, 7)
]);
}
]);
var imagesMoveTest = newLabel("___pixi_vn_images_move_test___", [
() => {
setDialogue({
character: juliette,
text: `Here's what's going to happen:
- ${eggHeadName} will move to { x: 500, y: 100 } with a speed of 24.
- ${flowerTopName} will move to { x: 500, y: 300 } with a speed of 18.
- ${helmlokName} will move to { x: 100, y: 500 } with a speed of 150 and a linear speed progression of -2 ( limit 10 ), and then move to { x: 1700, y: 500 } with a speed of 10 and a linear speed progression of 2 ( limit 150 ), and repeat.
- ${skullyName} will move to { x: 500, y: 500 } with a speed of 40, wait for 0.5 seconds, and move to { x: 100, y: 100 } with a speed of 40.`
});
GameWindowManager.addTicker("eggHead", new exports.MoveTicker({
destination: { x: 500, y: 100 },
speed: 24
}));
GameWindowManager.addTicker("flowerTop", new exports.MoveTicker({
destination: { x: 500, y: 300 },
speed: 18
}));
GameWindowManager.addTickersSteps("helmlok", [
new exports.MoveTicker({
destination: { x: 100, y: 500 },
speed: 150,
speedProgression: { type: "linear", amt: -2, limit: 10 }
}),
new exports.MoveTicker({
destination: { x: 1700, y: 500 },
speed: 10,
speedProgression: { type: "linear", amt: 2, limit: 150 }
}),
Repeat
]);
GameWindowManager.addTickersSteps("skully", [
new exports.MoveTicker({
destination: { x: 500, y: 500 },
speed: 40
}),
Pause(0.5),
new exports.MoveTicker({
destination: { x: 100, y: 100 },
speed: 40
})
]);
}
]);
var imagesZoomTest = newLabel("___pixi_vn_images_zoom_test___", [
() => {
setDialogue({
character: juliette,
text: `Here's what's going to happen:
- ${eggHeadName} will zoom out with a speed of 3 and a limit of -0.5.
- ${flowerTopName} will zoom in with a speed of 3 and a limit of 2.
- ${helmlokName} will unzoom with a speed of 3 and a limit of -1, and zoom in with a speed of 3 and a limit of 1, and repeat.
- ${skullyName} will zoom in with a speed of 0.1 and a limit of 5, wait for 0.5 seconds, and zoom out with a speed of 3 and a limit of 1.`
});
let eggHead = GameWindowManager.getCanvasElement("eggHead");
if (eggHead)
eggHead.scale.set(2);
let helmlok = GameWindowManager.getCanvasElement("helmlok");
if (helmlok)
helmlok.anchor.set(0.5);
GameWindowManager.addTicker("eggHead", new exports.ZoomTicker({
speed: 3,
limit: -0.5,
type: "unzoom"
}));
GameWindowManager.addTicker("flowerTop", new exports.ZoomTicker({
speed: 3,
limit: 2
}));
GameWindowManager.addTickersSteps("helmlok", [
new exports.ZoomTicker({
speed: 3,
limit: -1,
type: "unzoom"
}),
new exports.ZoomTicker({
speed: 3,
limit: 1
}),
Repeat
]);
GameWindowManager.addTickersSteps("skully", [
new exports.ZoomTicker({
speed: 0.1,
limit: 5,
speedProgression: { type: "exponential", percentage: 0.02 }
}),
Pause(0.5),
new exports.ZoomTicker({
"type": "unzoom",
speed: 3,
limit: 1
})
]);
}
]);
var imagesMoveInOutTest = newLabel("___pixi_vn_images_move_in_out_test___", [
() => __async(void 0, null, function* () {
setDialogue({
character: juliette,
text: `Here's what's going to happen:
- ${eggHeadName} will move in from the top with a speed of 80. If you go next, ${eggHeadName} will move out from the bottom with a speed of 80.
- ${flowerTopName} will move in from the right with a speed of 80 and a speed progression of 0.02. If you go next, ${flowerTopName} will move out from the left with a speed of 80 and a speed progression of 0.02.
- ${helmlokName} will move in from the left with a speed of 80. If you go next, ${helmlokName} will move out from the right with a speed of 80.
- ${skullyName} will move in from the bottom with a speed of 80 and a speed progression of 0.02. If you go next, ${skullyName} will move out from the top with a speed of 80 and a speed progression of 0.02.`
});
let eggHead = new CanvasImage({ x: 100, y: 100 }, eggHeadImage);
let flowerTop = new CanvasImage({ x: 300, y: 100 }, flowerTopImage);
let helmlok = new CanvasImage({ x: 100, y: 300 }, helmlokImage);
let skully = new CanvasImage({ x: 300, y: 300 }, skullyImage);
moveIn("eggHead", eggHead, { speed: 80, direction: "down" });
moveIn("flowerTop", flowerTop, {
speed: 80,
direction: "left",
speedProgression: { type: "exponential", percentage: 0.02 }
});
moveIn("helmlok", helmlok, { speed: 80, direction: "right" });
moveIn("skully", skully, {
speed: 80,
direction: "up",
speedProgression: { type: "exponential", percentage: 0.02 }
});
}),
() => {
moveOut("eggHead", { speed: 80, direction: "down" });
moveOut("flowerTop", { speed: 80, direction: "left" });
moveOut("helmlok", { speed: 80, direction: "right" });
moveOut("skully", { speed: 80, direction: "up" });
}
]);
var imagesZoomInOutTest = newLabel("___pixi_vn_images_zoom_in_out_test___", [
() => __async(void 0, null, function* () {
setDialogue({
character: juliette,
text: `Here's what's going to happen:
- ${eggHeadName} will zoom in with a speed of 3. If you go next, ${eggHeadName} will zoom out with a speed of 3.
- ${flowerTopName} will zoom in with a speed of 3 and a speed progression of 0.02. If you go next, ${flowerTopName} will zoom out with a speed of 3.
- ${helmlokName} will zoom in with a speed of 3. If you go next, ${helmlokName} will zoom out with a speed of 1.
- ${skullyName} will zoom in with a speed of 3 and a speed progression of 0.02. If you go next, ${skullyName} will zoom out with a speed of 3 and a speed progression of 0.02.`
});
GameWindowManager.removeCanvasElements();
let eggHead = new CanvasImage({ x: 100, y: 100 }, eggHeadImage);
let flowerTop = new CanvasImage({ x: 300, y: 100 }, flowerTopImage);
let helmlok = new CanvasImage({ x: 100, y: 300 }, helmlokImage);
let skully = new CanvasImage({ x: 300, y: 300 }, skullyImage);
zoomIn("eggHead", eggHead, { speed: 3, direction: "down" });
zoomIn("flowerTop", flowerTop, {
speed: 3,
direction: "left",
speedProgression: { type: "exponential", percentage: 0.02 }
});
zoomIn("helmlok", helmlok, { speed: 3, direction: "right" });
zoomIn("skully", skully, {
speed: 3,
direction: "up",
speedProgression: { type: "exponential", percentage: 0.02 }
});
}),
() => __async(void 0, null, function* () {
zoomOut("eggHead", {
speed: 3,
direction: "down",
speedProgression: { type: "exponential", percentage: 0.02 }
});
zoomOut("flowerTop", { speed: 3, direction: "left" });
zoomOut("helmlok", { speed: 1, direction: "right" });
zoomOut("skully", {
speed: 3,
direction: "up",
speedProgression: { type: "exponential", percentage: 0.02 }
});
})
]);
// src/labels/MarkdownTest.ts
var MARKDOWN_TEST_LABEL = "___pixi_vn_markdown_test___";
var markdownTest = newLabel(MARKDOWN_TEST_LABEL, [
() => __async(void 0, null, function* () {
setDialogue({
character: juliette,
text: `
# Markdown Test
Hello, this is a test of the markdown parser. Pixi'VN does not manage markdown, but you can implement a markdown parser to display text with markdown syntax.
For example in React, you can use the library [react-markdown](https://www.npmjs.com/package/react-markdown).
## Colored Text
<span style="color:blue">some *blue* text</span>.
<span style="color:red">some *red* text</span>.
<span style="color:green">some *green* text</span>.
## Bold Text
**This is bold text.**
## Italic Text
*This is italic text.*
## Delete Text
~~This is deleted text.~~
## Link Test
[Link to Google](https://www.google.com)
## H2 Test
### H3 Test
#### H4 Test
## Code Test
\`Hello World\`
\`\`\`js
console.log("Hello World")
\`\`\`
## List Test
- Item 1
* Item 2
- [x] Item 3
## Table Test
| Header 1 | Header 2 |
| -------- | -------- |
| Cell 1 | Cell 2 |
## Separator Test
***
Footer
`
});
})
]);
// src/labels/StepLabelTest.ts
var STEP_LABEL_TEST_LABEL = "___pixi_vn_step_label_test___";
var stepLabelTestLAbel = newLabel(STEP_LABEL_TEST_LABEL, [
() => __async(void 0, null, function* () {
setDialogue({ character: juliette, text: `Pixi'VN manages the succession of "screens" with steps. Each step is a function that can be asynchronous.` });
}),
() => __async(void 0, null, function* () {
setDialogue({ character: juliette, text: "The labels are containers of steps, they are used to organize the steps in a more readable way. For start a steps sequence, you must call or jump to a label." });
}),
() => __async(void 0, null, function* () {
setDialogue({ character: juliette, text: "It is also possible to ask the player to make a choice." });
}),
() => __async(void 0, null, function* () {
setDialogue({ character: juliette, text: "Browsing through available tests is one way to test the steps/labels system." });
})
]);
// src/labels/StartLabel.ts
var pixivnTestStartLabel = newLabel(
"___pixi_vn_example_start_label___",
[
() => {
let currentTimeName = "";
const hour = (/* @__PURE__ */ new Date()).getHours();
if (hour >= 5 && hour < 12) {
currentTimeName = "morning\u{1F505}";
} else if (hour >= 12 && hour < 18) {
currentTimeName = "afternoon\u{1F506}";
} else if (hour >= 18 && hour < 22) {
currentTimeName = "evening\u26C5";
} else {
currentTimeName = "night\u{1F319}";
}
setDialogue({ character: juliette, text: `Good ${currentTimeName}! I'm ${juliette.name}, your virtual assistant. I'm here to help you with your tests.` });
},
() => setDialogue({ character: juliette, text: `You are running the Pixi\u2019VN v${PIXIVN_VERSION} test. This test will guide you through the different features of the library.` }),
(props) => GameStepManager.jumpLabel(pixivnTestStartLabel2, props)
]
);
var openLink = newLabel(
"___pixi_vn_open_link___",
[
(props) => {
window.open(props.link);
GameStepManager.goNext(props);
}
]
);
var RESTART_TEST_LABEL = "___pixi_vn_restart_test_label___";
var pixivnTestStartLabel2 = newLabel(
RESTART_TEST_LABEL,
[
() => {
GameWindowManager.clear();
setDialogue({ character: juliette, text: "Which test would you like to start with?" });
setChoiceMenuOptions([
new ChoiceMenuOption("Open Pixi\u2019VN Wiki", openLink, { link: "https://pixi-vn.web.app/" }),
new ChoiceMenuOption("Images, Transitions and Animations Test", imagesAnimationsTest, {}),
new ChoiceMenuOption("Canvas Events Test", canvasEventsTestLabel, {}),
new ChoiceMenuOption("Base Canvas Element Test", baseCanvasElementTestLabel, {}),
new ChoiceMenuOption("Custom Ticker Canvas Element Test", customTickerCanvasElementTestLabel, {}),
new ChoiceMenuOption("Steps and Labels Test", stepLabelTestLAbel, {}),
new ChoiceMenuOption("Markdown Test", markdownTest, {}),
new ChoiceMenuOption("Open Pixi\u2019VN Github Issues", openLink, { link: "https://github.com/DRincs-Productions/pixi-vn/issues" })
]);
},
(props) => GameStepManager.jumpLabel(RESTART_TEST_LABEL, props)
]
);
Object.defineProperty(exports, "Assets", {
enumerable: true,
get: function () { return pixi_js.Assets; }
});
exports.CanvasBase = CanvasBase;
exports.CanvasContainer = CanvasContainer;
exports.CanvasEvent = CanvasEvent;
exports.CanvasImage = CanvasImage;
exports.CanvasSprite = CanvasSprite;
exports.CanvasText = CanvasText;
exports.CharacterBaseModel = CharacterBaseModel2;
exports.ChoiceMenuOption = ChoiceMenuOption;
exports.ChoiceMenuOptionClose = ChoiceMenuOptionClose;
exports.Close = Close;
exports.DialogueBaseModel = DialogueBaseModel;
exports.GameStepManager = GameStepManager;
exports.GameStorageManager = GameStorageManager;
exports.GameWindowManager = GameWindowManager;
exports.Label = Label;
exports.LabelJson = LabelJson2;
exports.Pause = Pause;
exports.Repeat = Repeat;
exports.StoredClassModel = StoredClassModel;
exports.TickerBase = TickerBase;
exports.addImage = addImage;
exports.canvasElementDecorator = canvasElementDecorator;
exports.clearAllGameDatas = clearAllGameDatas;
exports.clearChoiceMenuOptions = clearChoiceMenuOptions;
exports.clearDialogue = clearDialogue;
exports.eventDecorator = eventDecorator;
exports.getAllCharacters = getAllCharacters;
exports.getCharacterById = getCharacterById;
exports.getChoiceMenuOptions = getChoiceMenuOptions;
exports.getDialogue = getDialogue;
exports.getDialogueHistory = getDialogueHistory;
exports.getFlag = getFlag;
exports.getLabelById = getLabelById;
exports.getSaveData = getSaveData;
exports.getSaveJson = getSaveJson;
exports.getTexture = getTexture;
exports.importPixiVNJson = importPixiVNJson;
exports.juliette = juliette;
exports.loadImage = loadImage;
exports.loadSaveData = loadSaveData;
exports.loadSaveJson = loadSaveJson;
exports.moveIn = moveIn;
exports.moveOut = moveOut;
exports.newLabel = newLabel;
exports.pixivnTestStartLabel = pixivnTestStartLabel;
exports.removeCanvasElement = removeCanvasElement;
exports.removeWithDissolveTransition = removeWithDissolveTransition;
exports.removeWithFadeTransition = removeWithFadeTransition;
exports.saveCharacter = saveCharacter;
exports.setChoiceMenuOptions = setChoiceMenuOptions;
exports.setDialogue = setDialogue;
exports.setFlag = setFlag;
exports.showImage = showImage;
exports.showWithDissolveTransition = showWithDissolveTransition;
exports.showWithFadeTransition = showWithFadeTransition;
exports.tickerDecorator = tickerDecorator;
exports.zoomIn = zoomIn;
exports.zoomOut = zoomOut;
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map
;