Added detailed docs on schemas, dialogs, lists, and text (#53)

* Added detailed docs on schemas, dialogs, lists, and text

* TSLint fixups

* Finished README.md

* Trailing whitespace...
This commit is contained in:
Josh Goldberg
2018-03-25 19:43:16 -07:00
committed by GitHub
parent 669eea3638
commit 73092c68a1
7 changed files with 1085 additions and 196 deletions
+150
View File
@@ -7,6 +7,156 @@
In-game menu and dialog creation and management for GameStartr.
<!-- {{/Top}} -->
MenuGraphr automates creating in-game menus containing paragraphs or scrolling lists of text.
Each menu has a unique name by which its globally identified as well as a rectangular position relative to its parent.
Menus can be positioned as children of the root game's MapScreenr viewport or of each other.
## Usage
MenuGraphr instances take in, at the very least, a GameStartr game to create Things within.
The game should have have a `"Menu"` Thing defined.
### Constructor
```typescript
const gameStarter = new GameStartr({ ... });
const menuGrapher = new MenuGraphr({ gameStarter });
```
#### `gameStarter`
The parent GameStartr managing Things.
This is the only mandatory settings field.
#### `aliases`
Alternate Thing titles for characters, such as `" "` for `"Space"`.
Normally, Things used as menu text have titles equal to `"Text"` plus the name of the character.
These will replace the name of the character in that computation.
```typescript
// Uses "TextSpace" instead of "Text "
new MenuGraphr({
aliases: {
" ": "Space",
},
gameStarter,
});
```
#### `sounds`
Sounds that should be played for certain menu actions.
So far, this is only `onInteraction`, which is whenever a menu is interacted with
(usually off the A or B buttons being pressed).
These are played with the GameStartr's AudioPlayr.
```typescript
new MenuGraphr({
gameStarter,
sounds: {
onInteraction: "Bloop",
}
});
```
#### `replacements`
Programmatic replacements for deliniated words.
Allows texts in menus to contain dynamic values using predetermined strings.
These can be hardcoded strings or functions to generate them.
```typescript
new MenuGraphr({
gameStarter,
replacements: {
"DYNAMIC": () => gameStarter.itemsHolder.get("dynamic-value"),
"STATIC": "My name here!",
},
});
```
Menu dialogs and lists will directly replace the values of replacements between the menu's `replacerKey` (see below):
```typescript
menuGrapher.addMenuDialog("GeneralText", [
// Inserts the value of gameStarter.itemsHolder.get("dynamic-value")
"Dynamic value: %%%%%%%DYNAMIC%%%%%%%",
// Inserts "My name here!"
"Static value: %%%%%%%STATIC%%%%%%%",
]);
```
#### `replacerKey`
Separator for words to replace using `replacements`.
Defaults to `"%%%%%%%"`.
```typescript
new MenuGraphr({
gameStarter,
replacements: {
"STATIC": "My name here!",
},
replacerKey: "|",
});
```
```typescript
menuGrapher.addMenuDialog("GeneralText", [
// Inserts "My name here!"
"Static value: |STATIC|",
]);
```
#### `schemas`
Known menu schemas, keyed by name.
Those properties are defined on `IMenuSchema`.
See [`docs/schemas.md`](./docs/schemas.md).
```typescript
new MenuGraphr({
gameStarter,
schemas: {
GeneralText: {
size: {
height: 96,
width: 320,
},
},
},
});
```
### `createMenu`
Menus are created with `createMenu`, which takes in the string name of the menu and any additional properties.
```typescript
menuGrapher.createMenu("GeneralText", { /* ... */ });
```
Each menu is identified by a unique string name.
When `createMenu` creates a menu, any existing menu under that name is disposed of.
### `setActiveMenu`
Sets a menu to appear to have user focus.
For dialogs, this allows the user to "A" through them.
For lists, this visualizes the selected index with an "Arrow" Thing.
Only one menu may be active at any time.
There does not need to be an active menu, and menus are not active by default.
```typescript
menuGrapher.createMenu("GeneralText");
menuGrapher.addMenuDialog("GeneralText", "Hello world!");
menuGrapher.setActiveMenu("GeneralText");
```
<!-- {{Development}} -->
## Development
+98
View File
@@ -0,0 +1,98 @@
# Dialogs
Menu dialogs refer to any amount of text on a menu.
Some dialogs are static, and just used to display text Things on top of a menu.
Others are dynamic and can advance through formatted lines of interactive text.
## `addMenuDialog`
Adds dialog-style text to a menu.
If the text would overflow the menu's size, excess horizontal lines are delayed.
The user can advance through the menu with "A" button presses.
Parameters:
* `menuName`: Name of the menu.
* `dialog`: Raw dialog to add to the menu, as strings, arrays of strings, or complex placement commands.
* `onCompletion`: Optional callback for when the text is done.
### Dialogs
The actual type for menu dialogs is weirdly flexible:
```typescript
type IMenuDialogRaw = string | (string | string[] | (string | string[])[] | IMenuWordCommandBase)[];
```
#### String Dialogs
The simplest dialogs will typically just contain strings:
When provided as a raw string, the dialog is split across whitespace to generate words.
This forces the dialog to not wrap words across lines.
```typescript
// Creates a new GeneralText menu, deleting any existing one
menuGrapher.createMenu("GeneralText");
// Adds the dialog to GeneralText
menuGrapher.addMenuDialog("GeneralText", "Hello world!");
// Sets GeneralText as the active, input-receiving menu
menuGrapher.setActiveMenu("GeneralText");
```
#### Array Dialogs
Dialogs will show as many consecutive lines on "A" press as possible by default.
You can force a "break" in the sections by providing an array of dialog strings.
The dialog will clear any lines on the screen when moving across a break.
```typescript
menuGrapher.addMenuDialog("GeneralText", ["Hello world!", "Me again!"]);
```
### Advanced Commands
It's allowed to provide advanced "commands" to dialogs along with words in the dialogs.
These commands can insert "floating" text or change position offsets or alignments of the dialog text.
Alas, these command types aren't well fleshed out in `IMenuGraphr.ts` and not recommended until documentation is solidified.
See [#52](https://github.com/FullScreenShenanigans/MenuGraphr/issues/52).
## `IMenuSchema`
These options are available on `IMenuSchema` generally, but only useful once the menu is given a dialog.
### `deleteOnFinish`
Whether the menu should be deleted when its dialog finishes.
```typescript
{
deleteOnFinish: true,
}
```
### `finishAutomatically`
Whether the dialog should finish when the last word is displayed,
instead of waiting for user input.
```typescript
{
finishAutomatically: true,
},
```
### `finishAutomaticSpeed`
How many game ticks to delay completion by when `finishAutomatically` is true.
Defaults to `0`.
```typescript
{
finishAutomaticSpeed: 100,
}
```
See [`lists.md`](./lists.md) for examples of lists intermixed with dialogs.
+216
View File
@@ -0,0 +1,216 @@
# Lists
Menus can have scrollable lists of selectable text options in them.
Users can use direction inputs to scroll through the items.
Lists can be one-dimensional or two-dimensional.
This is determined by the computed height of list options within the menu's height.
If enough options are added to a list to pass the bottom, unless the menu specifies `singleColumnList`, they will overflow to a column to the right.
## `IListMenuSchema`
When creating or declaring schemas for list menus, there are some additional properties you can apply to them.
These are all optional.
### `saveIndex`
Whether the last selected index should be saved.
When `true`, the parent GameStartr's ItemsHoldr will save the selected index of the menu under the menu's name.
Recreating the menu will read from that stored index if available.
```typescript
{
saveIndex: true,
},
```
### `clearedIndicesOnDeletion`
Names of menus whose whose selected indices that should be cleared when this menu is deleted.
Use this when there are multiple related list menus open at once, and finishing one clears another.
```typescript
{
clearedIndicesOnDeletion: [
"KeyboardKeys",
"NameCollection",
],
},
```
### `scrollingItems`
How many scrolling items should be visible within the menu vertically.
List menus will by default show all the items at once, which is bad if there are many options and not enough menu height to display them all.
Specify a `scrollingItems` number to hardcode a maximum to display at once.
If the user shifts their selected index to below the lowest displayed item or above the highest displayed item,
the menu will "scroll" items vertically.
It does this by shifting their Things vertically and setting `hidden` on items not allowed to be seen.
```typescript
{
scrollingItems: 10,
},
```
> There is no equivalent for horizontal items.
### `scrollingItemsComputed`
As an alternative to `scrollingItems`, you can have the maximum displayed number of items computed as a function of menu height and expected height per list option.
This will set the `scrollingItems` member of the menu on list creation.
```typescript
{
scrollingItemsComputed: true,
},
```
### `singleColumnList`
Whether the list should always be a single column, rather than auto-flow.
```typescript
{
singleColumnList: true,
},
```
## `addMenuList`
Adds a list of text options to a menu.
Parameters:
* `menuName`: Name of the menu.
* `settings`: Settings for the list, particularly its options.
### `IListMenuOption`
Individual option within a list.
Only `text` is required.
#### `callback`
Callback for when the option is triggered.
Receives just the menu name.
```typescript
{
options: [
{
callback: () => console.log("First!"),
text: "First",
},
],
},
```
#### `position`
Position offsets to shift the option by, allowing top, right, bottom, left.
```typescript
{
options: [
{
position: {
top: 30,
right: -20,
},
text: "First",
},
],
},
```
#### `text`
Text displayed as the option.
This text will be rendered all in one row, similar to dialogs.
### `IListMenuOptions`
Settings to create a new list menu.
Only
#### `bottom`
A bottom option to display underneath displayed options.
If the list is two-dimensional, this will span across all rows.
```typescript
{
bottom: {
callback: () => console.log("Cancelled."),
text: "Cancel",
},
},
```
#### `options`
Options within the menu, or a function to generate them.
This is a flat list of options regarldess of whether the menu is one- or two-dimensional.
```typescript
{
options: [
{
callback: () => console.log("First!"),
text: "First",
},
],
},
```
See `IListMenuOption` above.
#### `selectedIndex`
Each list contains a `selectedIndex: [number, number]` of the position of the currently selected index.
This option overrides the starting selected index.
It defaults to `[0, 0]`.
## Examples
Showing a simple "Yes/No" menu after a general text dialog that stays alive:
```typescript
const finalize = (choice) => {
console.log("Choice:", choice);
menuGrapher.deleteMenu("Yes/No");
};
const createOptions = () => {
menuGrapher.createMenu("Yes/No", {
killOnB: ["GeneralText"],
});
menuGrapher.addMenuList("Yes/No", {
options: [
{
text: "YES",
callback: () => finalize(true),
},
{
text: "NO",
callback: () => finalize(false),
}
],
});
menuGrapher.setActiveMenu("Yes/No");
};
menuGrapher.createMenu("GeneralText", {
finishAutomatically: true,
keepOnBack: true,
});
menuGrapher.addMenuDialog("GeneralText", "Are you sure?", createOptions);
menuGrapher.setActiveMenu("GeneralText");
```
Creating a phone-style keyboard with 0-9, *, and #:
+337
View File
@@ -0,0 +1,337 @@
# Menu Schemas
## `IMenuSchema`
Attributes describing menu appearance and behavior.
These may be specified in the default schemas on a MenuGraphr instance or overriden with `createMenu`.
All properties are optional.
> See [`dialogs.md`](./dialogs.md) for properties specific to menu dialogs.
> See [`lists.md`](./lists.md) for properties specific to menu lists.
> See [`text.md`](./text.md) for how properties around displaying text in dialog and list menus.
### `backMenu`
Name of a menu to set as active when this one is deleted.
```typescript
{
backMenu: "GeneralText",
},
```
### `callback`
Callback for when this menu is set as active.
Called with the menu name.
```typescript
{
callback: (menuName) => {
console.log("Set", menuName, "as active.");
},
},
```
### `childrenSchemas`
Schemas of children to add on creation.
These will be directly passed to `createMenuChild`, which will call `createMenu`, `createMenuWord`, or `createMenuThing` as per the child type.
As with regular menu schemas, these allow all properties as overrides.
```typescript
{
childrenSchemas: [
{
type: "text",
words: ["Hello", "world!"],
},
{
type: "thing",
thing: "PlayerPortrait",
position: {
horizontal: "right",
},
},
{
type: "menu",
name: "PlayerStats",
},
],
},
```
> See `IMenuChildSchema`.
### `container`
Name of a containing menu to position within.
If not provided, this defaults to the entire game canvas.
```typescript
{
container: "GeneralText",
},
```
### `height`
How tall the menu should be, as Thing height.
This will also set the general Thing height of the menu.
```typescript
{
height: 80,
},
```
### `ignoreA`
Whether user selection events should be ignored.
These "A" events normally advance menu dialogs forward or trigger selected items in lists.
```typescript
{
ignoreA: true,
},
```
### `ignoreB`
Whether user deselection events should be ignored.
These "B" events normally exit out of menus.
```typescript
{
ignoreB: true,
},
```
### `ignoreProgressB`
Whether deselection events should count as selection during dialogs.
Menus with "progress" are in the middle of dialog or list creation.
Pressing B during progress would normally advance the menu forward.
```typescript
{
ignoreProgressB: true,
},
```
### `keepOnBack`
Whether this should be kept alive when deselected.
Useful for switching active state between multiple menus on B.
```typescript
{
keepOnBack: true,
},
```
### `killOnB`
Other menus to kill when this is deselected.
Commonly used with "Yes/No"-style dialogs that appear along with text descriptions in other menus.
```typescript
{
killOnB: ["GeneralText", "OtherDecorations"],
},
```
### `onActive`
Callback for when the menu becomes active.
Receives just the menu name.
```typescript
{
onActive: (menuName) => {
console.log("Menu", menuName, "is now active.");
},
},
```
### `onBPress`
Callback for when the "B" button is pressed while the menu is active.
Receives just the menu name.
Does not fire if `ignoreB` is true.
Also does not fire if the menu is mid-progress and `ignoreProgressB` is not true, as that simulates an "A" press.
```typescript
{
onBPress: (menuName) => {
console.log("Menu", menuName, "received a B press.");
},
},
```
### `onDown`
Callback for when the "down" button is pressed.
Receives just the menu name.
```typescript
{
onDown: (menuName) => {
console.log("Menu", menuName, "received a down event.");
},
},
```
### `onInactive`
Callback for when the menu becomes inactive.
Receives just the menu name.
```typescript
{
onActive: (menuName) => {
console.log("Menu", menuName, "is now active.");
},
},
```
### `onLeft`
Callback for when the "left" button is pressed.
Receives just the menu name.
```typescript
{
onLeft: (menuName) => {
console.log("Menu", menuName, "received a left event.");
},
},
```
### `onMenuDelete`
Callback for when the menu is deleted.
Receives just the menu name.
This is called _after_ the menu is deleted, but _before_ menu children are deleted.
```typescript
{
onMenuDelete: (menuName) => {
console.log("Menu", menuName, "was deleted.");
},
},
```
### `onRight`
Callback for when the "right" button is pressed.
Receives just the menu name.
```typescript
{
onRight: (menuName) => {
console.log("Menu", menuName, "received a right event.");
},
},
```
### `onUp`
Callback for when the "up" button is pressed.
Receives just the menu name.
```typescript
{
onUp: (menuName) => {
console.log("Menu", menuName, "received an up event.");
},
},
```
### `size`
Sizing description, including `height` and `width`.
This will override the native Thing `height` and `width` on the Menu.
```typescript
{
size: {
height: 80,
width: 40,
},
},
```
```typescript
{
},
```
> This allows menus to act as containers at a different size from their visual Things.
### `width`
How wide the menu should be, as Thing width.
This will also set the general Thing width of the menu.
```typescript
{
width: 40,
},
```
### `position`
How the menu should be positioned within its container.
Defaults to the menu aligning itself to the top-left corner of its container and no width or height.
#### `horizontal`
Modifies how the schema lays itself out horizontally.
* If `"center"`, aligns to the horizontal midpoint of its container.
* If `"right"`, its right aligns with its container's right.
* If `"stretch"`, stretches to fit its container horizontally.
```typescript
position: {
horizontal: "right",
},
```
#### `offset`
Horizontal and vertical offsets to shift the menu by.
These are allowed to be negative numbers, are calculated relative to the menu's container, and each reduce the menu's size horizontally or vertically.
```typescript
position: {
offset: {
top: -1,
right: 2,
bottom: 3,
left: -4,
},
},
```
#### `vertical`
Modifies how the schema lays itself out vertically.
* If `"center"`, aligns to the vertical midpoint of its container.
* If `"bottom"`, its bottom aligns with its container's bottom.
* If `"stretch"`, stretches to fit its container vertically.
```typescript
position: {
vertical: "bottom",
},
```
+74
View File
@@ -0,0 +1,74 @@
# Text
Text within menu dialogs and lists can be displayed with granular controls over paddings and spacing.
## `IMenuSchema`
These options will be used when the menu has a dialog or list added.
### `textPaddingRight`
How much padding there is between the right of the text and the right side of the box.
Text in dialogs will return to the next line instead of crossing the menu's `right` minus `textPaddingRight`.
Defaults to `0` (none) if not provided.
Allowed to be negative.
```typescript
{
textPaddingRight: 8,
},
```
### `textPaddingX`
How much horizontal padding should be between characters.
Defaults to the `"Text"` Thing prototype's `paddingX` if it exists, or `0` otherwise.
Characters placed next to each other in dialogs and lists will be placed this number of game pixels to the right each subsequent character.
```typescript
{
textPaddingX: 4,
},
```
### `textPaddingY`
How much vertical padding should be between lines of text.
Defaults to the `"Text"` Thing prototype's `paddingY` if it exists, or `0` otherwise.
Lines of text in dialogs and lists will start this number of game pixels lower each line.
```typescript
{
textPaddingY: 12,
},
```
### `textSpeed`
How long to delay between placing characters and words.
If `0` or not provided, characters and words will be placed immediately.
Otherwise, each character will wait a `textSpeed` delay before displaying.
Words will wait a `textSpeed` delay before appearing after each other as well, which gives the illusion of spaces between words also adhering to the delay.
### `textXOffset`
Horizontal offset for the text placement area.
All text will be offset horizontally by this amount.
```typescript
{
textXOffset: 2,
},
```
### `textYOffset`
Vertical offset for the text placement area.
All text will be offset vertically by this amount.
```typescript
{
textYOffset: -2,
},
```
+164 -131
View File
File diff suppressed because it is too large Load Diff
+46 -65
View File
@@ -1,8 +1,8 @@
import { GameStartr, IThing } from "gamestartr";
import {
IAliases, IGridCell, IListMenu, IListMenuOptions, IListMenuProgress,
IMenu, IMenuBase, IMenuChildMenuSchema, IMenuChildSchema,
IAliases, IGridCell, IListMenu, IListMenuOption, IListMenuOptions,
IListMenuProgress, IMenu, IMenuBase, IMenuChildSchema,
IMenuDialogRaw, IMenuGraphr, IMenuGraphrSettings, IMenuSchema,
IMenuSchemaPosition, IMenuSchemaPositionOffset, IMenuSchemas,
IMenuSchemaSize, IMenusContainer, IMenuThingSchema, IMenuWordCommand,
@@ -41,7 +41,7 @@ export class MenuGraphr implements IMenuGraphr {
private readonly schemas: IMenuSchemas;
/**
* A list of sounds that should be played for certain menu actions
* Sounds that should be played for certain menu actions.
*/
private readonly sounds: ISoundNames;
@@ -55,6 +55,11 @@ export class MenuGraphr implements IMenuGraphr {
*/
private readonly replacements: IReplacements;
/**
* Separator for words to replace using replacements.
*/
private readonly replacerKey: string;
/**
* The currently "active" (user-selected) menu.
*/
@@ -66,18 +71,12 @@ export class MenuGraphr implements IMenuGraphr {
* @param settings Settings to be used for initialization.
*/
public constructor(settings: IMenuGraphrSettings) {
if (!settings) {
throw new Error("No settings object given to MenuGraphr.");
}
if (!settings.gameStarter) {
throw new Error("No GameStartr given to MenuGraphr.");
}
this.gameStarter = settings.gameStarter;
this.schemas = settings.schemas || {};
this.aliases = settings.aliases || {};
this.replacements = settings.replacements || {};
this.replacerKey = settings.replacerKey || "%%%%%%%";
this.sounds = settings.sounds || {};
this.menus = {};
@@ -205,16 +204,16 @@ export class MenuGraphr implements IMenuGraphr {
public createMenuChild(name: string, schema: IMenuChildSchema): IThing | IThing[] {
switch (schema.type) {
case "menu":
return this.createMenu((schema as IMenuChildMenuSchema).name, (schema as IMenuChildMenuSchema).attributes);
return this.createMenu(schema.name, schema.attributes);
case "text":
return this.createMenuWord(name, schema as IMenuWordSchema);
return this.createMenuWord(name, schema);
case "thing":
return this.createMenuThing(name, schema as IMenuThingSchema);
return this.createMenuThing(name, schema);
default:
throw new Error(`Unknown schema type: '${schema.type}'.`);
throw new Error(`Unknown schema type: '${(schema as IMenuChildSchema).type}'.`);
}
}
@@ -312,21 +311,21 @@ export class MenuGraphr implements IMenuGraphr {
}
/**
* Adds dialog-style text to a menu. If the text overflows,
* Adds dialog-style text to a menu.
*
* @param name The name of the menu.
* @param menuName Name of the menu.
* @param dialog Raw dialog to add to the menu.
* @param onCompletion An optional callback for when the text is done.
*/
public addMenuDialog(name: string, dialog: IMenuDialogRaw, onCompletion?: () => any): void {
public addMenuDialog(menuName: string, dialog: IMenuDialogRaw, onCompletion?: () => any): void {
const dialogParsed: (string[] | IMenuWordCommand)[][] = this.parseRawDialog(dialog);
let currentLine = 1;
const callback: () => void = (): void => {
// If all dialog has been exhausted, delete the menu and finish
if (currentLine >= dialogParsed.length) {
if (this.menus[name].deleteOnFinish) {
this.deleteMenu(name);
if (this.menus[menuName].deleteOnFinish) {
this.deleteMenu(menuName);
}
if (onCompletion) {
onCompletion();
@@ -338,16 +337,15 @@ export class MenuGraphr implements IMenuGraphr {
// Delete any previous texts. This is only done if continuing
// So that when the dialog is finished, the last text remains
this.deleteMenuChildren(name);
this.deleteMenuChildren(menuName);
// This continues the dialog with the next iteration (word)
this.addMenuText(name, dialogParsed[currentLine - 1], callback);
this.addMenuText(menuName, dialogParsed[currentLine - 1], callback);
};
// This first call to addMenuText shouldn't be the callback, because if
// Being called from a childrenSchema of type "text", it shouldn't delete
// Any other menu children from childrenSchemas.
this.addMenuText(name, dialogParsed[0], callback);
// This first call to addMenuText shouldn't be the callback.
// If called from a childrenSchema of type "text", it shouldn't delete any other menu children from childrenSchemas.
this.addMenuText(menuName, dialogParsed[0], callback);
}
/**
@@ -395,13 +393,12 @@ export class MenuGraphr implements IMenuGraphr {
* Adds a list of text options to a menu.
*
* @param name The name of the menu.
* @param settings Settings for the list, particularly its options, starting
* index, and optional floating bottom.
* @param settings Settings for the list, particularly its options.
*/
public addMenuList(name: string, settings: IListMenuOptions): void {
const menu: IListMenu = this.getExistingMenu(name) as IListMenu;
const options: any[] = settings.options.constructor === Function
? (settings.options as any)()
const options: IListMenuOption[] = typeof settings.options === "function"
? settings.options()
: settings.options;
let left: number = menu.left + (menu.textXOffset || 0);
const top: number = menu.top + (menu.textYOffset || 0);
@@ -424,7 +421,7 @@ export class MenuGraphr implements IMenuGraphr {
let j: number;
let k: number;
menu.options = options;
menu.options = options as any[];
menu.optionChildren = optionChildren;
menu.callback = this.triggerMenuListOption.bind(this);
@@ -467,7 +464,7 @@ export class MenuGraphr implements IMenuGraphr {
menu.children.push(character);
optionChild.things.push(character);
if (!schema.position || !schema.position.relative) {
if (!schema.position) {
this.gameStarter.physics.shiftVert(character, y - menu.top);
}
}
@@ -778,17 +775,17 @@ export class MenuGraphr implements IMenuGraphr {
* Reacts to a user event directing down.
*/
public registerDown(): void {
const menu: IListMenu = this.activeMenu as IListMenu;
const menu = this.activeMenu;
if (!menu) {
return;
}
if (menu.selectedIndex) {
if ((menu as IListMenu).selectedIndex) {
this.shiftSelectedIndex(menu.name, 0, 1);
}
if (menu.onDown) {
menu.onDown(this.gameStarter);
menu.onDown(menu.name);
}
}
@@ -806,7 +803,7 @@ export class MenuGraphr implements IMenuGraphr {
}
if (menu.onLeft) {
menu.onLeft(this.gameStarter);
menu.onLeft(menu.name);
}
}
@@ -861,20 +858,6 @@ export class MenuGraphr implements IMenuGraphr {
}
}
/**
* Reacts to a user event from pressing a start key.
*/
public registerStart(): void {
const menu: IListMenu = this.activeMenu as IListMenu;
if (!menu) {
return;
}
if (menu.startMenu) {
this.setActiveMenu(menu.startMenu);
}
}
/**
* Adds a series of words to a menu.
*
@@ -939,7 +922,6 @@ export class MenuGraphr implements IMenuGraphr {
let textPaddingX: number;
let textPaddingY: number;
let textSpeed: number;
let textWidthMultiplier: number;
let character: IText;
let j: number;
@@ -960,16 +942,15 @@ export class MenuGraphr implements IMenuGraphr {
textSpeed = typeof menu.textSpeed === undefined ? 1 : menu.textSpeed || 0;
textWidth = menu.textWidth || textProperties.width;
textPaddingRight = menu.textPaddingRight || 0;
textPaddingX = menu.textPaddingX || textProperties.paddingX;
textPaddingY = menu.textPaddingY || textProperties.paddingY;
textWidthMultiplier = menu.textWidthMultiplier || 1;
textPaddingX = menu.textPaddingX || textProperties.paddingX || 0;
textPaddingY = menu.textPaddingY || textProperties.paddingY || 0;
// For each character in the word, schedule it appearing in the menu
for (j = 0; j < word.length; j += 1) {
// For non-whitespace characters, add them and move to the right
if (/\S/.test(word[j])) {
character = this.addMenuCharacter(name, word[j], x, y, j * textSpeed);
x += textWidthMultiplier * (character.width + textPaddingX);
x += character.width + textPaddingX;
continue;
}
@@ -979,7 +960,7 @@ export class MenuGraphr implements IMenuGraphr {
x = menu.textX!;
y += textPaddingY;
} else if (word[j] !== " " || x !== menu.textX) {
x += textWidth * textWidthMultiplier;
x += textWidth;
}
}
@@ -1261,13 +1242,13 @@ export class MenuGraphr implements IMenuGraphr {
/**
* Runs the callback for a menu's selected list option.
*
* @param name The name of the menu.
* @param menuName Name of the containing menu.
*/
private triggerMenuListOption(name: string): void {
const selected: IGridCell = this.getMenuSelectedOption(name);
private triggerMenuListOption(menuName: string): void {
const selected: IGridCell = this.getMenuSelectedOption(menuName);
if (selected.callback) {
selected.callback.call(this, name);
selected.callback.call(this, menuName);
}
}
@@ -1337,7 +1318,7 @@ export class MenuGraphr implements IMenuGraphr {
* character itself otherwise.
*/
private getCharacterEquivalent(character: string): string {
if (this.aliases.hasOwnProperty(character)) {
if ({}.hasOwnProperty.call(this.aliases, character)) {
return this.aliases[character];
}
@@ -1435,11 +1416,11 @@ export class MenuGraphr implements IMenuGraphr {
let end: number;
let inside: string | string[];
start = word.indexOf("%%%%%%%", 0);
end = word.indexOf("%%%%%%%", start + 1);
start = word.indexOf(this.replacerKey, 0);
end = word.indexOf(this.replacerKey, start + 1);
if (start !== -1 && end !== -1) {
inside = this.getReplacement(word.substring(start + "%%%%%%%".length, end));
inside = this.getReplacement(word.substring(start + this.replacerKey.length, end));
if (inside.constructor === Number) {
inside = inside.toString().split("");
} else if (inside.constructor === String) {
@@ -1448,7 +1429,7 @@ export class MenuGraphr implements IMenuGraphr {
output.push(...word.substring(0, start).split(""));
output.push(...(inside as string[]));
output.push(...this.filterWord(word.substring(end + "%%%%%%%".length)));
output.push(...this.filterWord(word.substring(end + this.replacerKey.length)));
return output;
}
@@ -1462,7 +1443,7 @@ export class MenuGraphr implements IMenuGraphr {
* @param words The words to filter, as Strings or command Objects.
* @returns The words, with all Strings filtered.
*/
private filterMenuWords(words: (string | IMenuWordCommand)[]): (string[] | IMenuWordCommand)[] {
private filterMenuWords(words: (string | string[] | IMenuWordCommand)[]): (string[] | IMenuWordCommand)[] {
const output: (string[] | IMenuWordCommand)[] = [];
for (const word of words) {