From 21d4deca7c8d3b760f4fa3a2321cdf830bc31cc5 Mon Sep 17 00:00:00 2001 From: Paolo Brasolin <paolo.brasolin@gmail.com> Date: Wed, 18 May 2022 12:18:26 +0200 Subject: [PATCH] refactor: #fe centralize font handling --- frontend/src/js/clue_payloads.ts | 46 +------------- frontend/src/js/game_over_scene.ts | 41 ++++-------- frontend/src/js/hud.ts | 24 ++----- frontend/src/js/leaderboard_scene.ts | 66 +++++-------------- frontend/src/js/loading_scene.ts | 9 +-- frontend/src/js/pause_scene.ts | 49 ++++++-------- frontend/src/js/rewards_scene.ts | 79 ++++++++--------------- frontend/src/js/text_styles.ts | 95 ++++++++++++++++++++++++++++ frontend/src/js/tutorial_scene.ts | 28 ++------ frontend/src/js/tutorial_steps.ts | 92 ++++++++++++--------------- frontend/src/js/welcome_scene.ts | 56 ++++------------ 11 files changed, 236 insertions(+), 349 deletions(-) create mode 100644 frontend/src/js/text_styles.ts diff --git a/frontend/src/js/clue_payloads.ts b/frontend/src/js/clue_payloads.ts index 4c7bc35..c6488a9 100644 --- a/frontend/src/js/clue_payloads.ts +++ b/frontend/src/js/clue_payloads.ts @@ -1,6 +1,7 @@ import "phaser"; import { Word } from "../../../backend/src/types"; +import TEXT_STYLES from "./text_styles"; interface CluePayload { baseHeight: number; @@ -10,55 +11,12 @@ interface CluePayload { //=[ Text clues ]=============================================================== -import { FONTS } from "./assets"; - -const GERMAN_ALPHABET = - "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜẞ" + "abcdefghijklmnopqrstuvwxyzäöüß"; - -export const TEXT_STYLE: { - [key: string]: Phaser.Types.GameObjects.Text.TextStyle; -} = { - TYPEWRITER: { - fontFamily: FONTS.MONO, - fontStyle: "bold", - color: "white", - stroke: "black", - strokeThickness: 8, - testString: GERMAN_ALPHABET, - }, - TRAINING: { - fontFamily: FONTS.FRAK, - color: "white", - stroke: "black", - strokeThickness: 8, - testString: GERMAN_ALPHABET, - }, - MONO_NEWSPAPER: { - fontFamily: FONTS.MONO, - color: "#333333", - stroke: "#666666", - strokeThickness: 4, - testString: GERMAN_ALPHABET, - backgroundColor: "#aaaaaa", - padding: { x: 8 }, - }, - FRAK_NEWSPAPER: { - fontFamily: FONTS.FRAK, - color: "#333333", - stroke: "#666666", - strokeThickness: 4, - testString: GERMAN_ALPHABET, - backgroundColor: "#aaaaaa", - padding: { x: 8 }, - }, -}; - export class TextCluePayload extends Phaser.GameObjects.Text implements CluePayload { baseHeight: number; - textStyle = TEXT_STYLE.TYPEWRITER; + textStyle = TEXT_STYLES.CLUE_DEFAULT; constructor(scene: Phaser.Scene, baseHeight: number) { super(scene, 0, 0, "", TextCluePayload.prototype.textStyle); diff --git a/frontend/src/js/game_over_scene.ts b/frontend/src/js/game_over_scene.ts index 802f9b8..f02c993 100644 --- a/frontend/src/js/game_over_scene.ts +++ b/frontend/src/js/game_over_scene.ts @@ -1,9 +1,7 @@ import "phaser"; -import { FONTS } from "./assets"; import BackgroundScene from "./background_scene"; import { formatTime, ICONS } from "./hud"; - -const BUTTON_HIGHLIGHT_COLOR = "darkorange"; +import TEXT_STYLES from "./text_styles"; const SS_KEYS = { BEST_WORDS: "OETZIT/BEST_WORDS", @@ -11,19 +9,6 @@ const SS_KEYS = { BEST_TIMER: "OETZIT/BEST_TIMER", }; -const TEXT_STYLE: { - [key: string]: Phaser.Types.GameObjects.Text.TextStyle; -} = { - BUTTON: { - fontFamily: FONTS.MONO, - fontStyle: "bold", - color: "white", - stroke: "black", - strokeThickness: 8, - testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", - }, -}; - export default class GameOverScene extends Phaser.Scene { music!: Phaser.Sound.BaseSound; continueButton!: Phaser.GameObjects.Text; @@ -87,10 +72,10 @@ export default class GameOverScene extends Phaser.Scene { drawTitle() { const text = "GAME OVER"; const title = this.add.text(0, 0, text, { + ...TEXT_STYLES.BASE, fontSize: "48px", - fontFamily: FONTS.MONO, - fontStyle: "bold", color: "#ff0000", + testString: text, }); title.setOrigin(0.5, 0); title.setPosition( @@ -102,11 +87,9 @@ export default class GameOverScene extends Phaser.Scene { drawSubtitle() { const text = `You contributed\n${ICONS.HEALTH} to our research! ${ICONS.HEALTH}\nThank you!`; // const subtitle = this.add.text(0, 0, text, { + ...TEXT_STYLES.BASE, fontSize: "28px", - fontFamily: FONTS.MONO, - fontStyle: "bold", color: "#aaff00", - align: "center", testString: text, }); subtitle.setOrigin(0.5, 0); @@ -141,10 +124,8 @@ export default class GameOverScene extends Phaser.Scene { ) { const text = this.formatResult(words, score, time); const title = this.add.text(0, 0, text, { + ...TEXT_STYLES.BASE, fontSize: "28px", - fontFamily: FONTS.MONO, - fontStyle: "bold", - color: "#ffffff", testString: text, }); title.setOrigin(0.5, 0); @@ -154,10 +135,8 @@ export default class GameOverScene extends Phaser.Scene { ); if (this.beatScore || this.beatTimer || this.beatWords) { const newPB = this.add.text(0, 0, "You set new records!", { + ...TEXT_STYLES.BASE, fontSize: "28px", - fontFamily: FONTS.MONO, - fontStyle: "bold", - color: "#ffffff", testString: text, }); newPB.setOrigin(0.5, 0); @@ -173,17 +152,19 @@ export default class GameOverScene extends Phaser.Scene { const text = `${verb} to continue`; this.continueButton = this.add .text(this.cameras.main.centerX, this.cameras.main.height * 0.9, text, { - ...TEXT_STYLE.BUTTON, + ...TEXT_STYLES.BUTTON, fontSize: "32px", }) .setOrigin(0.5, 1) .setPadding(4) .setInteractive({ useHandCursor: true }) .on("pointerover", () => - this.continueButton.setStyle({ stroke: BUTTON_HIGHLIGHT_COLOR }), + this.continueButton.setStyle({ + stroke: TEXT_STYLES.BUTTON_HOVER.stroke, + }), ) .on("pointerout", () => - this.continueButton.setStyle({ stroke: TEXT_STYLE.BUTTON.stroke }), + this.continueButton.setStyle({ stroke: TEXT_STYLES.BUTTON.stroke }), ); } diff --git a/frontend/src/js/hud.ts b/frontend/src/js/hud.ts index 7f41876..7dc8dd9 100644 --- a/frontend/src/js/hud.ts +++ b/frontend/src/js/hud.ts @@ -1,4 +1,4 @@ -import { FONTS } from "./assets"; +import TEXT_STYLES from "./text_styles"; export const ICONS = { SCORE: "ï¸âï¸", @@ -8,22 +8,6 @@ export const ICONS = { export const THIN_SPACE = "\u2009"; -const STATS_BASE_TEXT_STYLE = { - fontFamily: FONTS.MONO, - fontStyle: "bold", - color: "white", - testString: `${Object.values(ICONS).join("")}1234567890:.`, - stroke: "black", - strokeThickness: 4, -} as Phaser.Types.GameObjects.Text.TextStyle; - -const INPUT_BASE_TEXT_STYLE = { - fontFamily: FONTS.MONO, - fontStyle: "bold", - color: "white", - testString: `ABCDEFGHIJKLMNOPQRSTUVWXYZÄÜÖẞabcdefghijklmnopqrstuvwxyzäüöß `, -} as Phaser.Types.GameObjects.Text.TextStyle; - interface HudOptions { statsPadding: number; statsFontSize: string; @@ -81,7 +65,8 @@ export default class HUD { inputTextStyle(): Phaser.Types.GameObjects.Text.TextStyle { return { - ...INPUT_BASE_TEXT_STYLE, + ...TEXT_STYLES.HUD_INPUT, + testString: `ABCDEFGHIJKLMNOPQRSTUVWXYZÄÜÖẞabcdefghijklmnopqrstuvwxyzäüöß`, fontSize: this.options.inputFontSize, padding: { x: this.options.inputPadding, @@ -92,7 +77,8 @@ export default class HUD { statsTextStyle(): Phaser.Types.GameObjects.Text.TextStyle { return { - ...STATS_BASE_TEXT_STYLE, + ...TEXT_STYLES.HUD_STAT, + testString: `${Object.values(ICONS).join("")}1234567890:.`, fontSize: this.options.statsFontSize, padding: { x: this.options.statsPadding, diff --git a/frontend/src/js/leaderboard_scene.ts b/frontend/src/js/leaderboard_scene.ts index 244d64a..34697b8 100644 --- a/frontend/src/js/leaderboard_scene.ts +++ b/frontend/src/js/leaderboard_scene.ts @@ -1,5 +1,4 @@ import "phaser"; -import { FONTS } from "./assets"; import { uniqueNamesGenerator, names } from "unique-names-generator"; import backend from "./backend"; @@ -9,42 +8,10 @@ import { } from "../../../backend/src/types"; import Game from "./game"; import { sha256 } from "./utils"; +import TEXT_STYLES from "./text_styles"; const MEDALS = ["🥇", "🥈", "🥉"]; -const BUTTON_HIGHLIGHT_COLOR = "darkorange"; - -const TEXT_STYLE: { - [key: string]: Phaser.Types.GameObjects.Text.TextStyle; -} = { - LIST: { - fontSize: "28px", - fontFamily: FONTS.MONO, - fontStyle: "bold", - color: "#ffffff", - stroke: "black", - strokeThickness: 4, - }, - MESSAGE: { - fontFamily: FONTS.MONO, - fontStyle: "bold", - color: "#ffffff", - fontSize: "32px", - testString: - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890", - align: "center", - }, - BUTTON: { - fontFamily: FONTS.MONO, - fontStyle: "bold", - color: "white", - stroke: "black", - strokeThickness: 8, - testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", - fontSize: "32px", - }, -}; - export default class LeaderboardScene extends Phaser.Scene { game!: Game; music!: Phaser.Sound.BaseSound; @@ -87,12 +54,13 @@ export default class LeaderboardScene extends Phaser.Scene { async createRankings() { const renderedRankings = this.renderRankings(this.leaderboardView); - + const fontSize = Math.min(this.cameras.main.height * 0.25, 24); this.rankings = this.add .text(0, 0, renderedRankings, { - ...TEXT_STYLE.LIST, + ...TEXT_STYLES.BASE, testString: renderedRankings, }) + .setFontSize(fontSize) .setOrigin(0.5, 0) .setPosition(this.cameras.main.centerX, this.cameras.main.height * 0.1); } @@ -152,14 +120,15 @@ export default class LeaderboardScene extends Phaser.Scene { createMessage() { const renderedMessage = this.renderMessage(); + const fontSize = Math.min(this.cameras.main.height * 0.25, 24); this.message = this.add - .text( + .text(0, 0, renderedMessage, TEXT_STYLES.BASE) + .setOrigin(0.5, 0) + .setFontSize(fontSize) + .setPosition( this.cameras.main.centerX, this.rankings.getBounds().bottom + 32, - renderedMessage, - TEXT_STYLE.MESSAGE, - ) - .setOrigin(0.5, 0); + ); } renderMessage() { @@ -171,20 +140,19 @@ export default class LeaderboardScene extends Phaser.Scene { } createBackBtn() { - const verb = this.game.device.os.desktop ? "Click" : "Tap"; - const text = `${verb} to continue`; + const text = "Back to menu"; + const fontSize = Math.min(this.cameras.main.height * 0.25, 32); this.backBtn = this.add - .text(this.cameras.main.centerX, this.cameras.main.height * 0.9, text, { - ...TEXT_STYLE.BUTTON, - }) + .text(0, 0, text, TEXT_STYLES.BUTTON) .setOrigin(0.5, 1) - .setPadding(4) + .setFontSize(fontSize) + .setPosition(this.cameras.main.centerX, this.cameras.main.height * 0.95) .setInteractive({ useHandCursor: true }) .on("pointerover", () => - this.backBtn.setStyle({ stroke: BUTTON_HIGHLIGHT_COLOR }), + this.backBtn.setStyle({ stroke: TEXT_STYLES.BUTTON_HOVER.stroke }), ) .on("pointerout", () => - this.backBtn.setStyle({ stroke: TEXT_STYLE.BUTTON.stroke }), + this.backBtn.setStyle({ stroke: TEXT_STYLES.BUTTON.stroke }), ); } diff --git a/frontend/src/js/loading_scene.ts b/frontend/src/js/loading_scene.ts index 01ad60d..f714ac3 100644 --- a/frontend/src/js/loading_scene.ts +++ b/frontend/src/js/loading_scene.ts @@ -1,13 +1,13 @@ import "phaser"; import { BackgroundImages, - FONTS, MusicEffects, RexWebFontLoaderConfig, RexWebFontLoaderPluginFileConfig, SoundEffects, SpriteSheets, } from "./assets"; +import TEXT_STYLES from "./text_styles"; export default class LoadingScene extends Phaser.Scene { progressBar!: Phaser.GameObjects.Graphics; @@ -71,12 +71,7 @@ export default class LoadingScene extends Phaser.Scene { origin: 0.5, text: "LOADING: 0%", style: { - fontFamily: FONTS.MONO, - fontStyle: "bold", - fontSize: "32px", - color: "white", - stroke: "black", - strokeThickness: 4, + ...TEXT_STYLES.LOADING, testString: "LOADING: 0123456789%", }, }); diff --git a/frontend/src/js/pause_scene.ts b/frontend/src/js/pause_scene.ts index 97b015c..919a56b 100644 --- a/frontend/src/js/pause_scene.ts +++ b/frontend/src/js/pause_scene.ts @@ -1,5 +1,5 @@ import "phaser"; -import { FONTS } from "./assets"; +import TEXT_STYLES from "./text_styles"; export default class PauseScene extends Phaser.Scene { enabled = true; @@ -31,20 +31,15 @@ export default class PauseScene extends Phaser.Scene { drawTitle() { const text = "PAUSED"; - const title = this.add.text(0, 0, text, { - fontFamily: FONTS.MONO, - fontSize: "64px", - fontStyle: "bold", - color: "white", - stroke: "black", - strokeThickness: 4, - testString: text, - }); - title.setOrigin(0.5, 1); - title.setPosition( - this.cameras.main.width * 0.5, - this.cameras.main.height * 0.475, - ); + const fontSize = Math.min(this.cameras.main.height * 0.25, 64); + this.add + .text(0, 0, text, TEXT_STYLES.BASE) + .setFontSize(fontSize) + .setOrigin(0.5, 1) + .setPosition( + this.cameras.main.width * 0.5, + this.cameras.main.height * 0.475, + ); } drawCTA() { @@ -54,21 +49,15 @@ export default class PauseScene extends Phaser.Scene { ? "ESC" : "tap"; const text = `TAKE A BREATH\n${verb} to resume`; - const title = this.add.text(0, 0, text, { - fontFamily: FONTS.MONO, - fontSize: "32px", - fontStyle: "bold", - color: "white", - stroke: "black", - strokeThickness: 4, - testString: text, - align: "center", - }); - title.setOrigin(0.5, 0); - title.setPosition( - this.cameras.main.width * 0.5, - this.cameras.main.height * 0.525, - ); + const fontSize = Math.min(this.cameras.main.height * 0.125, 32); + this.add + .text(0, 0, text, TEXT_STYLES.BASE) + .setFontSize(fontSize) + .setOrigin(0.5, 0) + .setPosition( + this.cameras.main.width * 0.5, + this.cameras.main.height * 0.525, + ); } focusPause(manual: boolean) { diff --git a/frontend/src/js/rewards_scene.ts b/frontend/src/js/rewards_scene.ts index f35fd20..e9f3b82 100644 --- a/frontend/src/js/rewards_scene.ts +++ b/frontend/src/js/rewards_scene.ts @@ -1,40 +1,15 @@ import "phaser"; -import { FONTS } from "./assets"; import backend from "./backend"; import Game from "./game"; import PauseScene from "./pause_scene"; - -const BUTTON_HIGHLIGHT_COLOR = "darkorange"; +import TEXT_STYLES from "./text_styles"; // NOTE: see https://stackoverflow.com/a/26989421 const RFC_5322 = new RegExp( /^([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\[[\t -Z^-~]*])$/, ); -const TEXT_STYLE: { - [key: string]: Phaser.Types.GameObjects.Text.TextStyle; -} = { - MESSAGE: { - fontFamily: FONTS.MONO, - fontStyle: "bold", - color: "#ffffff", - fontSize: "32px", - testString: - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890", - align: "center", - }, - BUTTON: { - fontFamily: FONTS.MONO, - fontStyle: "bold", - color: "white", - stroke: "black", - strokeThickness: 8, - testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", - fontSize: "32px", - }, -}; - export default class RewardsScene extends Phaser.Scene { game!: Game; music!: Phaser.Sound.BaseSound; @@ -60,73 +35,75 @@ export default class RewardsScene extends Phaser.Scene { } createExplanation() { - const text = "We reward top players weekly! Enter your email to compete:"; + const text = "We reward top players weekly!\nEnter your email to compete:"; + const fontSize = Math.min(this.cameras.main.height * 0.125, 24); this.explanation = this.add - .text(this.cameras.main.centerX, this.cameras.main.height * 0.1, text, { - ...TEXT_STYLE.MESSAGE, - testString: text, - wordWrap: { width: this.cameras.main.width * 0.6 }, - }) - .setOrigin(0.5, 0); + .text(0, 0, text, TEXT_STYLES.BASE) + .setFontSize(fontSize) + .setOrigin(0.5, 0) + .setPosition(this.cameras.main.centerX, this.cameras.main.height * 0.05); } createMailBox() { this.mailBox = this.add - .text(this.cameras.main.centerX, this.cameras.main.centerY, "", { - ...TEXT_STYLE.BUTTON, - padding: { x: 16, y: 16 }, - }) + .text( + this.cameras.main.centerX, + this.cameras.main.centerY, + "", + TEXT_STYLES.BUTTON, + ) .setOrigin(0.5, 1) + .setPadding(16) .setInteractive({ useHandCursor: true }) .on("pointerover", () => - this.mailBox.setStyle({ stroke: BUTTON_HIGHLIGHT_COLOR }), + this.mailBox.setStyle({ stroke: TEXT_STYLES.BUTTON_HOVER.stroke }), ) .on("pointerout", () => - this.mailBox.setStyle({ stroke: TEXT_STYLE.BUTTON.stroke }), + this.mailBox.setStyle({ stroke: TEXT_STYLES.BUTTON.stroke }), ); this.refreshMailBox(); } createPrivacyNotice() { const text = - "By filling the input you agree to our privacy policy. You can read it HERE 🖋ï¸ðŸ¤“"; + "By filling the input you agree to our privacy policy.\nYou can read it HERE 🖋ï¸ðŸ¤“"; + const fontSize = Math.min(this.cameras.main.height * 0.125, 16); this.privacy = this.add .text( this.cameras.main.centerX, this.mailBox.getBounds().bottom + 16, text, { - ...TEXT_STYLE.BUTTON, - fontSize: "24px", + ...TEXT_STYLES.BUTTON, testString: text, - wordWrap: { width: this.cameras.main.width * 0.6 }, align: "center", }, ) + .setFontSize(fontSize) .setOrigin(0.5, 0) .setInteractive({ useHandCursor: true }) .on("pointerover", () => - this.privacy.setStyle({ stroke: BUTTON_HIGHLIGHT_COLOR }), + this.privacy.setStyle({ stroke: TEXT_STYLES.BUTTON_HOVER.stroke }), ) .on("pointerout", () => - this.privacy.setStyle({ stroke: TEXT_STYLE.BUTTON.stroke }), + this.privacy.setStyle({ stroke: TEXT_STYLES.BUTTON.stroke }), ); } createBackBtn() { const text = "Back to menu"; + const fontSize = Math.min(this.cameras.main.height * 0.25, 32); this.backBtn = this.add - .text(this.cameras.main.centerX, this.cameras.main.height * 0.9, text, { - ...TEXT_STYLE.BUTTON, - }) + .text(0, 0, text, TEXT_STYLES.BUTTON) + .setFontSize(fontSize) .setOrigin(0.5, 1) - .setPadding(4) + .setPosition(this.cameras.main.centerX, this.cameras.main.height * 0.95) .setInteractive({ useHandCursor: true }) .on("pointerover", () => - this.backBtn.setStyle({ stroke: BUTTON_HIGHLIGHT_COLOR }), + this.backBtn.setStyle({ stroke: TEXT_STYLES.BUTTON_HOVER.stroke }), ) .on("pointerout", () => - this.backBtn.setStyle({ stroke: TEXT_STYLE.BUTTON.stroke }), + this.backBtn.setStyle({ stroke: TEXT_STYLES.BUTTON.stroke }), ); } diff --git a/frontend/src/js/text_styles.ts b/frontend/src/js/text_styles.ts new file mode 100644 index 0000000..bd0679a --- /dev/null +++ b/frontend/src/js/text_styles.ts @@ -0,0 +1,95 @@ +import { FONTS } from "./assets"; + +const TEXT_STYLES: { + [key: string]: Phaser.Types.GameObjects.Text.TextStyle; +} = { + BASE: { + align: "center", + color: "white", + fontFamily: FONTS.MONO, + fontStyle: "bold", + stroke: "black", + strokeThickness: 8, + testString: + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 !?;:,.-()", + }, + BUTTON: { + color: "white", + fontFamily: FONTS.MONO, + fontSize: "32px", + fontStyle: "bold", + stroke: "black", + strokeThickness: 8, + testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", + padding: { x: 8, y: 8 }, + }, + BUTTON_HOVER: { + stroke: "darkorange", + }, + CHEATSHEET: { + color: "#ffffff", + fontFamily: FONTS.FRAK, + stroke: "black", + strokeThickness: 4, + }, + CLUE_DEFAULT: { + color: "white", + fontFamily: FONTS.MONO, + fontStyle: "bold", + stroke: "black", + strokeThickness: 8, + testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜẞabcdefghijklmnopqrstuvwxyzäöüß", + }, + CLUE_NEWSPAPER_FRAK: { + backgroundColor: "#aaaaaa", + color: "#333333", + fontFamily: FONTS.FRAK, + padding: { + x: 8, + }, + stroke: "#666666", + strokeThickness: 4, + testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜẞabcdefghijklmnopqrstuvwxyzäöüß", + }, + CLUE_NEWSPAPER_MONO: { + backgroundColor: "#aaaaaa", + color: "#333333", + fontFamily: FONTS.MONO, + padding: { + x: 8, + }, + stroke: "#666666", + strokeThickness: 4, + testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜẞabcdefghijklmnopqrstuvwxyzäöüß", + }, + HUD_INPUT: { + color: "white", + fontFamily: FONTS.MONO, + fontStyle: "bold", + }, + HUD_STAT: { + color: "white", + fontFamily: FONTS.MONO, + fontStyle: "bold", + stroke: "black", + strokeThickness: 4, + }, + LOADING: { + color: "white", + fontFamily: FONTS.MONO, + fontSize: "32px", + fontStyle: "bold", + stroke: "black", + strokeThickness: 4, + }, + VERSION_TAG: { + color: "#888888", + fontFamily: FONTS.MONO, + fontSize: "16px", + fontStyle: "bold", + testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.", + padding: { x: 8, y: 8 }, + }, +}; + +export default TEXT_STYLES; diff --git a/frontend/src/js/tutorial_scene.ts b/frontend/src/js/tutorial_scene.ts index c029a6c..106fc67 100644 --- a/frontend/src/js/tutorial_scene.ts +++ b/frontend/src/js/tutorial_scene.ts @@ -1,26 +1,12 @@ import "phaser"; -import { FONTS } from "./assets"; import MainScene, { InputStatus } from "./main_scene"; import Spear from "./spear"; +import TEXT_STYLES from "./text_styles"; import { STEPS } from "./tutorial_steps"; import { nthFibonacci } from "./utils"; -const BUTTON_HIGHLIGHT_COLOR = "darkorange"; - -const TEXT_STYLE: { - [key: string]: Phaser.Types.GameObjects.Text.TextStyle; -} = { - TUTORIAL: { - fontFamily: FONTS.MONO, - fontStyle: "bold", - color: "white", - stroke: "black", - strokeThickness: 8, - }, -}; - export interface TutorialStep { setup: (scene: TutorialScene) => void; teardown: (scene: TutorialScene) => void; @@ -72,17 +58,15 @@ export default class TutorialScene extends MainScene { } createText(options: CreateTextOptions) { + const fontSize = Math.min(this.cameras.main.width * 0.125, 32); const text = this.add .text( options.positionX ?? this.cameras.main.centerX, options.positionY ?? this.cameras.main.centerY, options.text, - { - ...TEXT_STYLE.TUTORIAL, - fontSize: `${Math.min(this.cameras.main.width * 0.125, 32)}px`, - align: "center", - }, + TEXT_STYLES.BASE, ) + .setFontSize(fontSize) .setOrigin(options.originX ?? 0.5, options.originY ?? 0.5) .setPadding(16); @@ -90,10 +74,10 @@ export default class TutorialScene extends MainScene { text .setInteractive({ useHandCursor: true }) .on("pointerover", () => - text.setStyle({ stroke: BUTTON_HIGHLIGHT_COLOR }), + text.setStyle({ stroke: TEXT_STYLES.BUTTON_HOVER.stroke }), ) .on("pointerout", () => - text.setStyle({ stroke: TEXT_STYLE.TUTORIAL.stroke }), + text.setStyle({ stroke: TEXT_STYLES.BASE.stroke }), ) .on("pointerup", () => this.nextStep()); return text; diff --git a/frontend/src/js/tutorial_steps.ts b/frontend/src/js/tutorial_steps.ts index 72995cb..b98a5d3 100644 --- a/frontend/src/js/tutorial_steps.ts +++ b/frontend/src/js/tutorial_steps.ts @@ -4,8 +4,8 @@ import TutorialScene, { TutorialStep } from "./tutorial_scene"; import Critter from "./critter"; import Spear from "./spear"; import Foe from "./foe"; -import { FONTS } from "./assets"; -import { TextCluePayload, TEXT_STYLE } from "./clue_payloads"; +import { TextCluePayload } from "./clue_payloads"; +import TEXT_STYLES from "./text_styles"; interface TrialRoundOptions { scene: TutorialScene; @@ -215,10 +215,9 @@ export const STEPS: TutorialStep[] = [ }, { setup: (scene) => { - const text = scene.createText({ - text: `Nice job ${scene.userName}! 👑ðŸ‘\nNow, the real thing...`, - positionY: scene.uiDimensions.cluesBounds.centerY, - }); + const text = scene.createSimpleText( + `Nice job ${scene.userName}! 👑ðŸ‘\nNow, the real thing...`, + ); scene.bucket.push(text); }, teardown: (scene) => scene.emptyBucket(), @@ -226,7 +225,7 @@ export const STEPS: TutorialStep[] = [ { setup: (scene) => { scene.setTypewriterEnabled(true); - TextCluePayload.prototype.textStyle = TEXT_STYLE.MONO_NEWSPAPER; + TextCluePayload.prototype.textStyle = TEXT_STYLES.CLUE_NEWSPAPER_MONO; trialRound({ scene: scene, words: ["i", "am", scene.userName], @@ -244,20 +243,18 @@ export const STEPS: TutorialStep[] = [ }, { setup: (scene) => { - const text = scene.createText({ - text: `â†–ï¸ ðŸ’ªðŸ…\nGreat! You scored\n${scene.score} points`, - positionY: scene.uiDimensions.cluesBounds.centerY, - }); + const text = scene.createSimpleText( + `â†–ï¸ ðŸ’ªðŸ…\nGreat! You scored\n${scene.score} points`, + ); scene.bucket.push(text); }, teardown: (scene) => scene.emptyBucket(), }, { setup: (scene) => { - const text = scene.createText({ - text: "Speed and good\nCapiTaliZation\nare worth more", - positionY: scene.uiDimensions.cluesBounds.centerY, - }); + const text = scene.createSimpleText( + "Speed and good\nCapiTaliZation\nare worth more", + ); scene.bucket.push(text); }, teardown: (scene) => scene.emptyBucket(), @@ -265,7 +262,7 @@ export const STEPS: TutorialStep[] = [ { setup: (scene) => { scene.setTypewriterEnabled(true); - TextCluePayload.prototype.textStyle = TEXT_STYLE.MONO_NEWSPAPER; + TextCluePayload.prototype.textStyle = TEXT_STYLES.CLUE_NEWSPAPER_MONO; trialRound({ scene: scene, words: "no way you will catch all of these lol".split(" "), @@ -283,40 +280,36 @@ export const STEPS: TutorialStep[] = [ }, { setup: (scene) => { - const text = scene.createText({ - text: "Words glow red when\nÖtzi is in danger\n🅰ï¸âš ï¸", - positionY: scene.uiDimensions.cluesBounds.centerY, - }); + const text = scene.createSimpleText( + "Words glow red when\nÖtzi is in danger\n🅰ï¸âš ï¸", + ); scene.bucket.push(text); }, teardown: (scene) => scene.emptyBucket(), }, { setup: (scene) => { - const text = scene.createText({ - text: "Longer words are worth\n(and will hurt) more\nðŸ˜âš ï¸", - positionY: scene.uiDimensions.cluesBounds.centerY, - }); + const text = scene.createSimpleText( + "Longer words are worth\n(and will hurt) more\nðŸ˜âš ï¸", + ); scene.bucket.push(text); }, teardown: (scene) => scene.emptyBucket(), }, { setup: (scene) => { - const text = scene.createText({ - text: "â²ï¸ â¬†ï¸ âš ï¸\nAlso, as time passes,\nthings will get harder", - positionY: scene.uiDimensions.cluesBounds.centerY, - }); + const text = scene.createSimpleText( + "â²ï¸ â¬†ï¸ âš ï¸\nAlso, as time passes,\nthings will get harder", + ); scene.bucket.push(text); }, teardown: (scene) => scene.emptyBucket(), }, { setup: (scene) => { - const text = scene.createText({ - text: "By the way, we'll\nuse Fraktur script!\n😖â“", - positionY: scene.uiDimensions.cluesBounds.centerY, - }); + const text = scene.createSimpleText( + "By the way, we'll\nuse Fraktur script!\n😖â“", + ); scene.bucket.push(text); }, teardown: (scene) => scene.emptyBucket(), @@ -363,12 +356,9 @@ export const STEPS: TutorialStep[] = [ (p + h) * j + p + h * 0.5, letter + letter.toLocaleLowerCase(), { - fontFamily: FONTS.FRAK, + ...TEXT_STYLES.CHEATSHEET, fontSize: `${h / 1.4}px`, testString: alphabet + alphabet.toLowerCase(), - color: "#ffffff", - stroke: "black", - strokeThickness: 4, }, ) .setOrigin(0.5, 0.5); @@ -379,10 +369,9 @@ export const STEPS: TutorialStep[] = [ }, { setup: (scene) => { - const text = scene.createText({ - text: "Yup, that's a handful.\nBrace yourself...\n😅😱", - positionY: scene.uiDimensions.cluesBounds.centerY, - }); + const text = scene.createSimpleText( + "Yup, that's a handful.\nBrace yourself...\n😅😱", + ); scene.bucket.push(text); }, teardown: (scene) => scene.emptyBucket(), @@ -390,10 +379,9 @@ export const STEPS: TutorialStep[] = [ { setup: (scene) => { const verb = scene.game.device.os.desktop ? "hit ESC" : "tap twice"; - const text = scene.createText({ - text: `Oh! And remember:\n${verb} to pause\nðŸ™â¸ï¸`, - positionY: scene.uiDimensions.cluesBounds.centerY, - }); + const text = scene.createSimpleText( + `Oh! And remember:\n${verb} to pause\nðŸ™â¸ï¸`, + ); scene.bucket.push(text); }, teardown: (scene) => scene.emptyBucket(), @@ -402,7 +390,7 @@ export const STEPS: TutorialStep[] = [ setup: (scene) => { scene.setTypewriterEnabled(true); scene.tapoutEnabled = true; - TextCluePayload.prototype.textStyle = TEXT_STYLE.FRAK_NEWSPAPER; + TextCluePayload.prototype.textStyle = TEXT_STYLES.CLUE_NEWSPAPER_FRAK; trialRound({ scene: scene, words: "Ãœben von Xylophon und Querflöte ist ja zweckmäßig".split(" "), @@ -425,20 +413,18 @@ export const STEPS: TutorialStep[] = [ "Pretty good!\n😊🥈", // 3 4 5 "Very impressive!\n🤩🥇", // 6 7 8 ][Math.floor((3 * scene.acceptedWords) / (8 + 1))]; - const text = scene.createText({ - text: `You got ${scene.acceptedWords} out of 8.\n${comment}`, - positionY: scene.uiDimensions.cluesBounds.centerY, - }); + const text = scene.createSimpleText( + `You got ${scene.acceptedWords} out of 8.\n${comment}`, + ); scene.bucket.push(text); }, teardown: (scene) => scene.emptyBucket(), }, { setup: (scene) => { - const text = scene.createText({ - text: `That's it, ${scene.userName}.\nTime to play!\n😋🕹ï¸`, - positionY: scene.uiDimensions.cluesBounds.centerY, - }); + const text = scene.createSimpleText( + `That's it, ${scene.userName}.\nTime to play!\n😋🕹ï¸`, + ); scene.bucket.push(text); }, teardown: (scene) => scene.emptyBucket(), diff --git a/frontend/src/js/welcome_scene.ts b/frontend/src/js/welcome_scene.ts index ce2bf28..c099633 100644 --- a/frontend/src/js/welcome_scene.ts +++ b/frontend/src/js/welcome_scene.ts @@ -1,34 +1,5 @@ import "phaser"; -import { FONTS } from "./assets"; - -const BUTTON_HIGHLIGHT_COLOR = "darkorange"; - -const TEXT_STYLE: { - [key: string]: Phaser.Types.GameObjects.Text.TextStyle; -} = { - TITLE: { - fontFamily: FONTS.MONO, - fontStyle: "bold", - color: "white", - stroke: "black", - strokeThickness: 8, - }, - BUTTON: { - fontFamily: FONTS.MONO, - fontStyle: "bold", - color: "white", - stroke: "black", - strokeThickness: 8, - testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", - }, - VERSION: { - fontFamily: FONTS.MONO, - fontSize: "16px", - fontStyle: "bold", - color: "#888888", - testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.", - }, -}; +import TEXT_STYLES from "./text_styles"; export default class WelcomeScene extends Phaser.Scene { music!: Phaser.Sound.BaseSound; @@ -70,37 +41,35 @@ export default class WelcomeScene extends Phaser.Scene { } createMainButton(text: string, index: number) { - const size = Math.min(this.cameras.main.width * 0.125, 48); + const fontSize = Math.min((this.cameras.main.height * 0.5) / 4 / 1.4, 48); const button = this.add .text( this.cameras.main.centerX, - this.cameras.main.centerY + index * size * 1.4, + this.cameras.main.centerY + index * fontSize * 1.4, text, - { - ...TEXT_STYLE.BUTTON, - fontSize: `${size}px`, - }, + TEXT_STYLES.BUTTON, ) - .setOrigin(0.5, 0.5) - .setPadding(4) + .setFontSize(fontSize) + .setOrigin(0.5, 1) .setInteractive({ useHandCursor: true }) .on("pointerover", () => - button.setStyle({ stroke: BUTTON_HIGHLIGHT_COLOR }), + button.setStyle({ stroke: TEXT_STYLES.BUTTON_HOVER.stroke }), ) .on("pointerout", () => - button.setStyle({ stroke: TEXT_STYLE.BUTTON.stroke }), + button.setStyle({ stroke: TEXT_STYLES.BUTTON.stroke }), ); return button; } createTitleText() { const text = "ÖTZIT!"; + const fontSize = Math.min(this.cameras.main.height * 0.25, 128); this.titleText = this.add .text(0, 0, text, { - ...TEXT_STYLE.TITLE, - fontSize: `${Math.min(this.cameras.main.width * 0.125, 128)}px`, + ...TEXT_STYLES.BASE, testString: text, }) + .setFontSize(fontSize) .setOrigin(0.5, 1) .setPosition(this.cameras.main.centerX, this.cameras.main.height * 0.3); } @@ -108,9 +77,8 @@ export default class WelcomeScene extends Phaser.Scene { createVersionText() { const text = process.env.APP_VERSION || "unknown"; this.versionText = this.add - .text(0, 0, text.toUpperCase(), TEXT_STYLE.VERSION) + .text(0, 0, text.toUpperCase(), TEXT_STYLES.VERSION_TAG) .setOrigin(0.5, 1) - .setPadding(8) .setPosition(this.cameras.main.centerX, this.cameras.main.height); } -- GitLab