Skip to content

Commit

Permalink
improve choices and input
Browse files Browse the repository at this point in the history
  • Loading branch information
lajbel committed Sep 11, 2023
1 parent f78ad0c commit f87a353
Show file tree
Hide file tree
Showing 12 changed files with 189 additions and 64 deletions.
2 changes: 1 addition & 1 deletion doc.json

Large diffs are not rendered by default.

57 changes: 49 additions & 8 deletions example/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ const m = mandarina({
height: 540,
textbox: {
sprite: "textbox",
offset: [0, 4],
offset: [ 0, 4 ],
textFont: "sans-serif",
textSize: 24,
textOffset: [3, 3],
textOffset: [ 3, 3 ],
},
choice: {
sprite: "choice",
Expand All @@ -29,7 +29,7 @@ m.loadImage("code1", "assets/characters/code/code1.png", {
});

// Some variables
m.setVar("name", "PlayerUnknown");
const setName = m.setVar("name", "PlayerUnknown");

// We define our characters.
m.character("t", "Deffy", {
Expand All @@ -55,15 +55,56 @@ m.chapter("start", () => [
m.show("t", "normal").fadeIn().appearFrom("left"),
// Say something.
m.say("t", "Hi, I'm Deffy!"),
m.say("t", "Welcome to this example! I wan't to know you better!"),

// Jump to another chapter.
m.jump("presentation"),
]);

m.chapter("presentation", () => [
m.say("t", "What's your name?"),
m.input("name"),
m.input("Write your name: ", setName),

m.say("t", "Oh, cool name [name]"),
m.say("t", "And what's your pronoun?"),
m.say("t", "And which pronoun do you use?"),

// Display a set of choices.
m.choice(
{
// The choice's text.
"he/him": {
// The choice's value.
value: 0,
// The choice's actions to add to the story.
actions: () => [ m.say("t", "Okay, he") ],
},
"she/her": {
value: 1,
actions: () => [ m.say("t", "Okay, she") ],
},
"they/them": {
value: 2,
actions: () => [ m.say("t", "Okay, they") ],
},
},
// The variable to store the choice's value.
m.setPronoun,
),

m.jump("usercheck"),
]);

m.chapter("usercheck", () => [
m.say("t", "So, your pronoun is [they], and your name is [name]"),
m.say("t", "Is that correct?"),

m.choice({
"he/him": () => [m.say("t", "Okay, he")],
"she/her": () => [m.say("t", "Okay, she")],
"they/them": () => [m.say("t", "Okay, they")],
yes: {
actions: () => [ m.say("t", "Okay, let's go!") ],
},
no: {
actions: () => [ m.say("Oh, will return"), m.jump("presentation") ],
},
}),
]);

Expand Down
4 changes: 2 additions & 2 deletions src/actions/character.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type {
} from "../components/visual";
import { createAction, getGameData } from "../game";
import { getAlignment } from "utils/getDimensions";
import { visual } from "../components/visual";
import { visualComponent } from "../components/visual";

export function showCharacter(
characterId: string,
Expand Down Expand Up @@ -44,7 +44,7 @@ export function showCharacter(
k.opacity(1),
k.anchor("center"),
k.pos(0),
visual({
visualComponent({
sprite: expressionSprite,
visualObj: "character_sprite",
startEffects: [ ...Object.keys(effects) ],
Expand Down
22 changes: 16 additions & 6 deletions src/actions/textbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,22 @@ export function say(...args: string[]) {
});
}

export function choice(choices: Record<string, () => Action[]>) {
export function choice(
choices: Record<
string,
{
actions: () => Action[];
value?: any;
}
>,
setter?: (value: any) => void,
) {
return createAction({
id: "choice",
type: "normal",
start() {
addChoices(choices);
canSkip: false,
async start() {
addChoices(choices, setter);
},
skip() {
return;
Expand All @@ -99,7 +109,7 @@ export function choice(choices: Record<string, () => Action[]>) {
});
}

export function input(v: string) {
export function input(text: string, setter: (value: any) => void) {
const { m } = getGameData();

return createAction({
Expand All @@ -108,8 +118,8 @@ export function input(v: string) {
canSkip: false,
async start() {
const textbox = m._textbox;
const inputText = await textbox?.getInput();
m.setVar(v, inputText);
const inputText = await textbox?.getInput(text);
setter(inputText);
},
skip() {
return;
Expand Down
10 changes: 7 additions & 3 deletions src/components/choice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,23 @@ import type { Action } from "types";
import { getGameData, insertActions } from "game";

export interface ChoiceComp extends KA.Comp {
actions: () => Action[];
actions: (v: string) => Action[];
}

export function choice(actions: () => Action[]): ChoiceComp {
export function choiceComponent(
value: any,
actions: (v: string) => Action[],
setter?: (value: any) => void,
): ChoiceComp {
return {
id: "mandarina_choice",
require: [ "area" ],
actions: actions,
add(this: KA.GameObj) {
const { k } = getGameData();
this.onClick(() => {
insertActions(this.actions());
this.parent?.destroy();
setter?.(value);
});
},
};
Expand Down
23 changes: 17 additions & 6 deletions src/components/textbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ export interface TextboxComp extends KA.Comp {
/** Change the namebox's text. */
changeName(this: Textbox, text: string, color?: KA.Color): void;
/** Get user input in textbox. */
getInput(this: Textbox): Promise<string>;
getInput(this: Textbox, text: string): Promise<string>;
}

function formatText(text: string) {
const { m, opt, variables } = getGameData();
const pronoun = m.getVar("pronoun") as number;
const pronoun = m.getVar<number>("pronoun");
const pronounData = pronouns[opt.language ?? "english"];

let formattedText = text
.replace("[they]", pronounData.their[pronoun])
.replace("[they]", pronounData.they[pronoun])
.replace("[them]", pronounData.them[pronoun])
.replace("[their]", pronounData.their[pronoun])
.replace("[theirs]", pronounData.theirs[pronoun])
Expand All @@ -53,7 +53,7 @@ function formatText(text: string) {
return formattedText;
}

export function textbox(): TextboxComp {
export function textboxComponent(): TextboxComp {
const data = getGameData();
const k = data.k;
let textbox: KA.GameObj;
Expand Down Expand Up @@ -114,6 +114,7 @@ export function textbox(): TextboxComp {
},
clear() {
textbox.text = "";
namebox.text = "";
},
skip() {
if (!this.skipped) this.skipped = true;
Expand Down Expand Up @@ -152,26 +153,36 @@ export function textbox(): TextboxComp {
),
);
},
getInput() {
async getInput(text: string) {
const events: KA.EventController[] = [];
let value = "";
this.clear();

await this.write(text);

const inputPromise = new Promise<string>((resolve) => {
const enterPressEvent = k.onKeyPress("enter", () => {
resolve(textbox.text);
resolve(value);
});

const charInputEvent = k.onCharInput((ch) => {
if (ch == " " && value.length == 0) return;
if (k.isKeyDown("shift")) ch = ch.toUpperCase();

textbox.text += ch;
value += ch;
});

const backspacePressEvent = k.onKeyPressRepeat(
"backspace",
() => {
if (value.length == 0) return;

textbox.text = textbox.text.substring(
0,
textbox.text.length - 1,
);
value = value.substring(0, value.length - 1);
},
);

Expand Down
4 changes: 3 additions & 1 deletion src/components/visual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ export interface VisualCompOpt<TEffect extends VisualEffect[] = any> {
duration?: number;
}

export function visual<T extends VisualEffect[] | undefined = undefined>(
export function visualComponent<
T extends VisualEffect[] | undefined = undefined
>(
opt: T extends VisualEffect[]
? VisualCompOpt<T> & OptByEffects<T>
: VisualCompOpt,
Expand Down
9 changes: 7 additions & 2 deletions src/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,13 @@ export function loadImage(
}

// Variables
export function setVar<T>(name: string, value: T) {
export function setVar<T>(name: string, value: T): (value: T) => void {
const data = getGameData();
data.variables[name] = value;
return data.variables[name];

return (value) => {
data.variables[name] = value;
};
}

export function getVar(name: string): any {
Expand Down Expand Up @@ -164,6 +167,7 @@ function previousAction() {

function skipAction() {
if (getCurrentAction().canSkip === false) return;

getCurrentAction().skip?.();
getGameData().processingAction = false;
getGameData().currentAction++;
Expand All @@ -184,6 +188,7 @@ export function startNovel() {
// User input
// TODO: Add support for customize keys
k.onUpdate(() => {
k.debug.log(isProcessingAction());
if (
k.isKeyPressed("space") ||
k.isKeyPressed("right") ||
Expand Down
25 changes: 17 additions & 8 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type * as KA from "kaboom";
import type { MandarinaOpt, MandarinaPlugin } from "types";
import type { MandarinaOpt, MandarinaPlugin } from "./types";
import kaboom from "kaboom";
import {
startNovel,
Expand All @@ -9,13 +9,19 @@ import {
loadImage,
setVar,
getVar,
} from "game";
import { jump } from "actions/chapters";
import { LayerPlugin, layerPlugin } from "plugins/layer";
import { showCharacter, hideCharacter } from "actions/character";
import { showBackground } from "actions/background";
import { playAudio } from "actions/audio";
import { say, showTextbox, hideTextbox, choice, input } from "actions/textbox";
} from "./game";
import { jump } from "./actions/chapters";
import { LayerPlugin, layerPlugin } from "./plugins/layer";
import { showCharacter, hideCharacter } from "./actions/character";
import { showBackground } from "./actions/background";
import { playAudio } from "./actions/audio";
import {
say,
showTextbox,
hideTextbox,
choice,
input,
} from "./actions/textbox";

export function mandarinaPlugin(
opt: MandarinaOpt,
Expand All @@ -35,6 +41,9 @@ export function mandarinaPlugin(
chapter: addChapter,
setVar,
getVar,
setPronoun: (value: number) => {
setVar("pronoun", value);
},
start() {
k.go("mandarina");
},
Expand Down
Loading

0 comments on commit f87a353

Please sign in to comment.