small improvements
This commit is contained in:
parent
c393582978
commit
fd91fe1d31
@ -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$"
|
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!"
|
||||||
|
|
||||||
`
|
`
|
||||||
|
|
||||||
|
@ -6,22 +6,40 @@ import { MathText } from "./MathText";
|
|||||||
import { characterData } from "./data";
|
import { characterData } from "./data";
|
||||||
|
|
||||||
type VisualState = {
|
type VisualState = {
|
||||||
characters: {name: string, emotion: string, x: number}[],
|
turn: number,
|
||||||
|
characters: {name: string, emotion: string, side: "left" | "right", lastTurn: number}[],
|
||||||
board: {text: string},
|
board: {text: string},
|
||||||
dialog: {name: string | null, 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 afterStep = (state: VisualState, step: Mathuscript[number]): VisualState => {
|
||||||
const newState = structuredClone(state);
|
const newState = structuredClone(state);
|
||||||
const {characters, board, dialog} = newState;
|
const {characters, board, dialog} = newState;
|
||||||
|
newState.turn += 1;
|
||||||
if (step.name === "board") {
|
if (step.name === "board") {
|
||||||
board.text = step.text;
|
board.text = step.text;
|
||||||
} else {
|
} else {
|
||||||
|
characters.sort((a, b) => a.lastTurn - b.lastTurn);
|
||||||
let char = characters.find(c => c.name === step.name);
|
let char = characters.find(c => c.name === step.name);
|
||||||
if (!char) {
|
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);
|
characters.push(char);
|
||||||
}
|
}
|
||||||
|
char.lastTurn = newState.turn;
|
||||||
char.emotion = step.emotion ?? char.emotion;
|
char.emotion = step.emotion ?? char.emotion;
|
||||||
dialog.name = step.name;
|
dialog.name = step.name;
|
||||||
dialog.text = step.text;
|
dialog.text = step.text;
|
||||||
@ -41,7 +59,7 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
|||||||
const {script} = props;
|
const {script} = props;
|
||||||
const parsedScript = useMemo(() => parseMathuscript(script), [script]);
|
const parsedScript = useMemo(() => parseMathuscript(script), [script]);
|
||||||
const [index, setIndex] = useState(0);
|
const [index, setIndex] = useState(0);
|
||||||
const [visualState, setVisualState] = useState<VisualState>({characters: [], board: {text: ""}, dialog: {name: null, text: ""}});
|
const [visualState, setVisualState] = useState<VisualState>({turn: 0, characters: [], board: {text: ""}, dialog: {name: null, text: ""}});
|
||||||
|
|
||||||
const doStep = useCallback(() => {
|
const doStep = useCallback(() => {
|
||||||
const step = parsedScript[index];
|
const step = parsedScript[index];
|
||||||
@ -105,9 +123,13 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
|||||||
return <img
|
return <img
|
||||||
className={css`
|
className={css`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -20%;
|
${
|
||||||
|
c.side === "left" ? css`left: -20%;` : css`right: -20%; transform: scaleX(-1);`
|
||||||
|
}
|
||||||
height: 90%;
|
height: 90%;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
--outline-color: black;
|
||||||
|
filter: drop-shadow(1px 1px 0 var(--outline-color)) drop-shadow(-1px 1px 0 var(--outline-color)) drop-shadow(1px -1px 0 var(--outline-color)) drop-shadow(-1px -1px 0 var(--outline-color));
|
||||||
`}
|
`}
|
||||||
key={c.name}
|
key={c.name}
|
||||||
src={char.assets["default"]}
|
src={char.assets["default"]}
|
||||||
@ -126,6 +148,7 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
|||||||
<div className={css`
|
<div className={css`
|
||||||
flex-basis: 0;
|
flex-basis: 0;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
position: relative;
|
||||||
background-color: hsla(220, 50%, 40%, 0.85);
|
background-color: hsla(220, 50%, 40%, 0.85);
|
||||||
border: 2px solid hsla(220, 30%, 60%, 0.85);
|
border: 2px solid hsla(220, 30%, 60%, 0.85);
|
||||||
border-radius: 0.25em;
|
border-radius: 0.25em;
|
||||||
@ -134,7 +157,18 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
|||||||
`}>
|
`}>
|
||||||
{
|
{
|
||||||
speakingChar && <>
|
speakingChar && <>
|
||||||
<strong>{speakingChar.displayName}.</strong> <MathText>{visualState.dialog.text}</MathText>
|
<div className={css`
|
||||||
|
position: absolute;
|
||||||
|
bottom: 100%;
|
||||||
|
left: 0;
|
||||||
|
background-color: hsla(220, 50%, 40%, 0.85);
|
||||||
|
border: 2px solid hsla(220, 30%, 60%, 0.85);
|
||||||
|
border-radius: 0.25em;
|
||||||
|
padding: 0.25em 0.75em;
|
||||||
|
`}>
|
||||||
|
<strong>{speakingChar.displayName}</strong>
|
||||||
|
</div>
|
||||||
|
<MathText>{visualState.dialog.text}</MathText>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,14 +3,18 @@ export const characterData = {
|
|||||||
displayName: "Bridget",
|
displayName: "Bridget",
|
||||||
assets: {
|
assets: {
|
||||||
default: "/assets/bridget.png",
|
default: "/assets/bridget.png",
|
||||||
fallback: "/assets/bridget.png",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
axelle: {
|
calvin: {
|
||||||
displayName: "Axelle",
|
displayName: "Calvin",
|
||||||
assets: {
|
assets: {
|
||||||
default: "/assets/bridget.png",
|
default: "/assets/calvin.png",
|
||||||
fallback: "/assets/bridget.png",
|
},
|
||||||
|
},
|
||||||
|
kit: {
|
||||||
|
displayName: "Kit",
|
||||||
|
assets: {
|
||||||
|
default: "/assets/kit.png",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
|
BIN
src/server/public/assets/calvin.png
Normal file
BIN
src/server/public/assets/calvin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 411 KiB |
BIN
src/server/public/assets/kit.png
Normal file
BIN
src/server/public/assets/kit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 856 KiB |
Loading…
x
Reference in New Issue
Block a user