From 12da6ddd6c136cf63b51bfc2cc47a39567aaa37f Mon Sep 17 00:00:00 2001 From: kharhamel Date: Wed, 26 May 2021 17:07:07 +0200 Subject: [PATCH] FEATURE: improved the display of player names, with the font-family 'Press start 2P' and gray outlines --- CHANGELOG.md | 5 +++++ front/dist/index.tmpl.html | 1 - front/dist/resources/fonts/fonts.css | 5 +++++ front/package.json | 1 + front/src/Connexion/LocalUser.ts | 5 ++--- front/src/Phaser/Entity/Character.ts | 10 +++++----- front/src/Phaser/Game/GameScene.ts | 8 ++++++++ front/src/index.ts | 9 ++++++++- front/src/rex-plugins.d.ts | 4 ++++ front/style/fonts.scss | 1 + front/style/index.scss | 3 ++- front/tests/Phaser/Connexion/LocalUserTest.ts | 10 ++++++++-- front/webpack.config.ts | 10 +++++++++- front/yarn.lock | 5 +++++ 14 files changed, 63 insertions(+), 14 deletions(-) create mode 100644 front/dist/resources/fonts/fonts.css create mode 100644 front/style/fonts.scss diff --git a/CHANGELOG.md b/CHANGELOG.md index dec14540..d9afd71e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,11 @@ - The emote menu can be opened by clicking on your character. - Clicking on one of its element will close the menu and play an emote above your character. - This emote can be seen by other players. +- Player names were improved. (@Kharhamel) + - We now create a GameObject.Text instead of GameObject.BitmapText + - now use the 'Press Start 2P' font family and added an outline + - As a result, we can now allow non-standard letters like french accents or chinese characters! + - Mobile support has been improved - WorkAdventure automatically sets the zoom level based on the viewport size to ensure a sensible size of the map is visible, whatever the viewport used - Mouse wheel support to zoom in / out diff --git a/front/dist/index.tmpl.html b/front/dist/index.tmpl.html index 7ef44116..01dd58d0 100644 --- a/front/dist/index.tmpl.html +++ b/front/dist/index.tmpl.html @@ -29,7 +29,6 @@ - WorkAdventure diff --git a/front/dist/resources/fonts/fonts.css b/front/dist/resources/fonts/fonts.css new file mode 100644 index 00000000..a3d3cf71 --- /dev/null +++ b/front/dist/resources/fonts/fonts.css @@ -0,0 +1,5 @@ +/*This file is a workaround to allow phaser to load directly this font */ +@font-face { + font-family: "Press Start 2P"; + src: url("/fonts/press-start-2p-latin-400-normal.woff2") format('woff2'); +} \ No newline at end of file diff --git a/front/package.json b/front/package.json index e64c0816..6cf0ee97 100644 --- a/front/package.json +++ b/front/package.json @@ -34,6 +34,7 @@ "webpack-dev-server": "^3.11.2" }, "dependencies": { + "@fontsource/press-start-2p": "^4.3.0", "@types/simple-peer": "^9.6.0", "@types/socket.io-client": "^1.4.32", "axios": "^0.21.1", diff --git a/front/src/Connexion/LocalUser.ts b/front/src/Connexion/LocalUser.ts index 0793a938..43b184cf 100644 --- a/front/src/Connexion/LocalUser.ts +++ b/front/src/Connexion/LocalUser.ts @@ -9,9 +9,8 @@ export interface CharacterTexture { export const maxUserNameLength: number = MAX_USERNAME_LENGTH; -export function isUserNameValid(value: string): boolean { - const regexp = new RegExp('^[A-Za-z0-9]{1,'+maxUserNameLength+'}$'); - return regexp.test(value); +export function isUserNameValid(value: unknown): boolean { + return typeof value === "string" && value.length > 0 && value.length < maxUserNameLength && value.indexOf(' ') === -1; } export function areCharacterLayersValid(value: string[] | null): boolean { diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index b1a85943..9c3273ec 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -1,6 +1,6 @@ import {PlayerAnimationDirections, PlayerAnimationTypes} from "../Player/Animation"; import {SpeechBubble} from "./SpeechBubble"; -import BitmapText = Phaser.GameObjects.BitmapText; +import Text = Phaser.GameObjects.Text; import Container = Phaser.GameObjects.Container; import Sprite = Phaser.GameObjects.Sprite; import {TextureError} from "../../Exception/TextureError"; @@ -23,7 +23,7 @@ const interactiveRadius = 35; export abstract class Character extends Container { private bubble: SpeechBubble|null = null; - private readonly playerName: BitmapText; + private readonly playerName: Text; public PlayerValue: string; public sprites: Map; private lastDirection: PlayerAnimationDirections = PlayerAnimationDirections.Down; @@ -55,9 +55,9 @@ export abstract class Character extends Container { this.addTextures(textures, frame); this.invisible = false }) - - this.playerName = new BitmapText(scene, 0, playerNameY, 'main_font', name, 7); - this.playerName.setOrigin(0.5).setCenterAlign().setDepth(DEPTH_INGAME_TEXT_INDEX); + + this.playerName = new Text(scene, 0, playerNameY, name, {fontFamily: '"Press Start 2P"', fontSize: '8px', strokeThickness: 2, stroke: "gray"}); + this.playerName.setOrigin(0.5).setDepth(DEPTH_INGAME_TEXT_INDEX); this.add(this.playerName); if (this.isClickable()) { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 4de5ffd9..91286ba9 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -279,6 +279,14 @@ export class GameScene extends DirtyScene implements CenterListener { this.load.spritesheet('layout_modes', 'resources/objects/layout_modes.png', {frameWidth: 32, frameHeight: 32}); this.load.bitmapFont('main_font', 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml'); + //eslint-disable-next-line @typescript-eslint/no-explicit-any + (this.load as any).rexWebFont({ + custom: { + families: ['Press Start 2P'], + urls: ['/resources/fonts/fonts.css'], + testString: 'abcdefg' + }, + }); //this function must stay at the end of preload function addLoader(this); diff --git a/front/src/index.ts b/front/src/index.ts index 2cdcaa19..f9017c24 100644 --- a/front/src/index.ts +++ b/front/src/index.ts @@ -9,7 +9,7 @@ import {SelectCharacterScene} from "./Phaser/Login/SelectCharacterScene"; import {SelectCompanionScene} from "./Phaser/Login/SelectCompanionScene"; import {EnableCameraScene} from "./Phaser/Login/EnableCameraScene"; import {CustomizeScene} from "./Phaser/Login/CustomizeScene"; -import {ResizableScene} from "./Phaser/Login/ResizableScene"; +import WebFontLoaderPlugin from 'phaser3-rex-plugins/plugins/webfontloader-plugin.js'; import {EntryScene} from "./Phaser/Login/EntryScene"; import {coWebsiteManager} from "./WebRtc/CoWebsiteManager"; import {MenuScene} from "./Phaser/Menu/MenuScene"; @@ -107,6 +107,13 @@ const config: GameConfig = { roundPixels: true, antialias: false }, + plugins: { + global: [{ + key: 'rexWebFontLoader', + plugin: WebFontLoaderPlugin, + start: true + }] + }, physics: { default: "arcade", arcade: { diff --git a/front/src/rex-plugins.d.ts b/front/src/rex-plugins.d.ts index d5457702..2e160315 100644 --- a/front/src/rex-plugins.d.ts +++ b/front/src/rex-plugins.d.ts @@ -7,6 +7,10 @@ declare module 'phaser3-rex-plugins/plugins/gestures-plugin.js' { const content: any; // eslint-disable-line export default content; } +declare module 'phaser3-rex-plugins/plugins/webfontloader-plugin.js' { + const content: any; // eslint-disable-line + export default content; +} declare module 'phaser3-rex-plugins/plugins/gestures.js' { export const Pinch: any; // eslint-disable-line } diff --git a/front/style/fonts.scss b/front/style/fonts.scss new file mode 100644 index 00000000..5ef9b9b4 --- /dev/null +++ b/front/style/fonts.scss @@ -0,0 +1 @@ +@import "~@fontsource/press-start-2p/index.css"; \ No newline at end of file diff --git a/front/style/index.scss b/front/style/index.scss index 67e85c5b..47f13c3b 100644 --- a/front/style/index.scss +++ b/front/style/index.scss @@ -1,4 +1,5 @@ @import "cowebsite.scss"; @import "cowebsite-mobile.scss"; @import "style.css"; -@import "mobile-style.scss"; \ No newline at end of file +@import "mobile-style.scss"; +@import "fonts.scss"; \ No newline at end of file diff --git a/front/tests/Phaser/Connexion/LocalUserTest.ts b/front/tests/Phaser/Connexion/LocalUserTest.ts index 25b54005..4ba20745 100644 --- a/front/tests/Phaser/Connexion/LocalUserTest.ts +++ b/front/tests/Phaser/Connexion/LocalUserTest.ts @@ -19,8 +19,14 @@ describe("isUserNameValid()", () => { it("should not validate spaces", () => { expect(isUserNameValid(' ')).toBe(false); }); - it("should not validate special characters", () => { - expect(isUserNameValid('a&-')).toBe(false); + it("should validate special characters", () => { + expect(isUserNameValid('%&-')).toBe(true); + }); + it("should validate accents", () => { + expect(isUserNameValid('éàëè')).toBe(true); + }); + it("should validate chinese characters", () => { + expect(isUserNameValid('中文鍵盤')).toBe(true); }); }); diff --git a/front/webpack.config.ts b/front/webpack.config.ts index cc87572a..6ebf907f 100644 --- a/front/webpack.config.ts +++ b/front/webpack.config.ts @@ -102,9 +102,17 @@ module.exports = { } }, { - test: /\.(ttf|eot|svg|png|gif|jpg)$/, + test: /\.(eot|svg|png|gif|jpg)$/, exclude: /node_modules/, type: 'asset' + }, + { + test: /\.(woff(2)?|ttf)$/, + type: 'asset', + generator: { + filename: 'fonts/[name][ext]' + } + } ], }, diff --git a/front/yarn.lock b/front/yarn.lock index bbdf0e06..180c82bf 100644 --- a/front/yarn.lock +++ b/front/yarn.lock @@ -50,6 +50,11 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@fontsource/press-start-2p@^4.3.0": + version "4.3.0" + resolved "https://registry.yarnpkg.com/@fontsource/press-start-2p/-/press-start-2p-4.3.0.tgz#37124387f7fbfe7792b5fc9a1906b80d9aeda4c6" + integrity sha512-gmS4070EoZp5/6NUJ+tBnvtDiSmFcR+S+ClAOJ8NGFXDWOkO12yMnyGJEJaDCNCAMX0s2TQCcmr6qWKx5ad3RQ== + "@nodelib/fs.scandir@2.1.4": version "2.1.4" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69"