diff --git a/src/client/app.tsx b/src/client/app.tsx index 85e6f82..7a806a1 100644 --- a/src/client/app.tsx +++ b/src/client/app.tsx @@ -9,7 +9,19 @@ bridget (happy) "Hi, friends!" board "Given $f: \mathbb{Q} \to \mathbb{R}$ and $x \in \mathbb{Q}$, there is a unique $y \in \mathbb{N}$ such that $f(x)=y$" -axelle (happy) "Wow, did you know that $a^2+b^2=c^2$?" +calvin (happy) "Wow, did you know that $a^2+b^2=c^2$?" + +calvin (happy) "Something else" + +bridget (happy) "Me again" + +kit (happy) "I'm Kit!" + +board "" + +calvin (happy) "I'm back!" + +bridget (happy) "I'm on the right now!" ` diff --git a/src/client/player/Player.tsx b/src/client/player/Player.tsx index 7d73445..a4aa72b 100644 --- a/src/client/player/Player.tsx +++ b/src/client/player/Player.tsx @@ -6,22 +6,40 @@ import { MathText } from "./MathText"; import { characterData } from "./data"; type VisualState = { - characters: {name: string, emotion: string, x: number}[], + turn: number, + characters: {name: string, emotion: string, side: "left" | "right", lastTurn: number}[], board: {text: string}, dialog: {name: string | null, text: string}, } +const otherSide = (side: "left" | "right"): "left" | "right" => { + return ({ + left: "right", + right: "left", + } as const)[side]; +} + const afterStep = (state: VisualState, step: Mathuscript[number]): VisualState => { const newState = structuredClone(state); const {characters, board, dialog} = newState; + newState.turn += 1; if (step.name === "board") { board.text = step.text; } else { + characters.sort((a, b) => a.lastTurn - b.lastTurn); let char = characters.find(c => c.name === step.name); if (!char) { - char = {name: step.name, emotion: "default", x: 0.5}; + char = {name: step.name, emotion: "default", side: "left", lastTurn: -1}; + if (characters.length > 1) { + characters.splice(0, characters.length-1); + } + const otherChar = characters[0]; + if (otherChar) { + char.side = otherSide(otherChar.side); + } characters.push(char); } + char.lastTurn = newState.turn; char.emotion = step.emotion ?? char.emotion; dialog.name = step.name; dialog.text = step.text; @@ -41,7 +59,7 @@ export const MathuscriptPlayer = (props: { script: string }) => { const {script} = props; const parsedScript = useMemo(() => parseMathuscript(script), [script]); const [index, setIndex] = useState(0); - const [visualState, setVisualState] = useState({characters: [], board: {text: ""}, dialog: {name: null, text: ""}}); + const [visualState, setVisualState] = useState({turn: 0, characters: [], board: {text: ""}, dialog: {name: null, text: ""}}); const doStep = useCallback(() => { const step = parsedScript[index]; @@ -105,9 +123,13 @@ export const MathuscriptPlayer = (props: { script: string }) => { return {
{ `}> { speakingChar && <> - {speakingChar.displayName}. {visualState.dialog.text} +
+ {speakingChar.displayName} +
+ {visualState.dialog.text} }
diff --git a/src/client/player/data.ts b/src/client/player/data.ts index 0f72983..558c31d 100644 --- a/src/client/player/data.ts +++ b/src/client/player/data.ts @@ -3,14 +3,18 @@ export const characterData = { displayName: "Bridget", assets: { default: "/assets/bridget.png", - fallback: "/assets/bridget.png", }, }, - axelle: { - displayName: "Axelle", + calvin: { + displayName: "Calvin", assets: { - default: "/assets/bridget.png", - fallback: "/assets/bridget.png", + default: "/assets/calvin.png", }, - } + }, + kit: { + displayName: "Kit", + assets: { + default: "/assets/kit.png", + }, + }, } \ No newline at end of file diff --git a/src/server/public/assets/calvin.png b/src/server/public/assets/calvin.png new file mode 100644 index 0000000..c803b19 Binary files /dev/null and b/src/server/public/assets/calvin.png differ diff --git a/src/server/public/assets/kit.png b/src/server/public/assets/kit.png new file mode 100644 index 0000000..f95304b Binary files /dev/null and b/src/server/public/assets/kit.png differ