Skip to content
Snippets Groups Projects
Commit 0aaf0b87 authored by Paolo Brasolin's avatar Paolo Brasolin
Browse files

feat: #fe refactor clue payloads and streamline sizing

parent 8beb9732
No related branches found
No related tags found
No related merge requests found
...@@ -2,120 +2,28 @@ import "phaser"; ...@@ -2,120 +2,28 @@ import "phaser";
import FightScene from "./fight_scene"; import FightScene from "./fight_scene";
import * as Types from "../../../backend/src/types"; import * as Types from "../../../backend/src/types";
import { FONTS } from "./assets"; import { SpriteCluePayload, TextCluePayload } from "./clue_payloads";
// const HYPERASCENDERS = /[ÄÖÜ]/;
const ASCENDERS = /[ABCDEFGHIJKLMNOPQRSTUVWXYZbdfhijklstäöüß]/;
const DESCENDERS = /[AFHJPQYZÄfghjpqsyzß]/;
const CONCEAL_TINT = 0xaaaaaa; const CONCEAL_TINT = 0xaaaaaa;
interface CluePayload {
word: Types.Word;
loadWord: (word: Types.Word) => void;
delete: () => void;
}
class TextCluePayload extends Phaser.GameObjects.Text implements CluePayload {
word: Types.Word;
constructor(scene: FightScene) {
super(scene, 0, 0, "", {
fontSize: "48px",
fontFamily: FONTS.FRAK,
fontStyle: "bold",
color: "white",
stroke: "black",
strokeThickness: 8,
});
scene.add.existing(this);
this.setAlpha(0);
}
loadWord(word: Types.Word) {
this.word = word;
this.setText(this.word.ocr_transcript);
this.emit("CLUE_PAYLOAD_READY");
}
delete() {
this.destroy();
}
}
class SpriteCluePayload
extends Phaser.GameObjects.Sprite
implements CluePayload
{
word: Types.Word;
textureKey: string;
baseHeight: number;
constructor(scene: FightScene) {
super(scene, 0, 0, "__MISSING");
scene.add.existing(this);
this.setAlpha(0);
this.baseHeight = Math.max(this.scene.cameras.main.width * 0.035, 30); // max(3.5vw,32px)
}
loadWord(word: Types.Word) {
this.word = word;
// TODO: we could be smarter and fully leverage caching, but meh.
this.textureKey = `${word.id}-${Date.now()}`;
this.loadTexture();
}
loadTexture() {
// this.scene.textures.remove()
this.scene.textures.addBase64(this.textureKey, this.word.image);
this.scene.textures.once(
"addtexture",
() => {
this.applyTexture();
this.emit("CLUE_PAYLOAD_READY");
},
this.scene,
);
}
estimateWordHeight() {
let height = 1.0;
// if (this.word.ocr_transcript.match(HYPERASCENDERS)) height += 0.2;
if (this.word.ocr_transcript.match(ASCENDERS)) height += 0.2;
if (this.word.ocr_transcript.match(DESCENDERS)) height += 0.2;
return height;
}
applyTexture() {
this.setTexture(this.textureKey);
const scale =
(this.estimateWordHeight() * this.baseHeight) /
this.texture.getSourceImage().height;
this.setScale(scale);
}
delete() {
this.texture.destroy();
this.destroy();
}
}
class Clue { class Clue {
scene: FightScene; scene: FightScene;
word: Types.Word; word: Types.Word;
duration: number; duration: number;
payload: TextCluePayload | SpriteCluePayload; payload: SpriteCluePayload | TextCluePayload;
constructor(scene: FightScene, word: Types.Word, duration: number) { constructor(scene: FightScene, word: Types.Word, duration: number) {
this.scene = scene; this.scene = scene;
this.word = word; this.word = word;
this.duration = duration; this.duration = duration;
// this.payload = new TextCluePayload(this.scene); // TODO: is this size really ok?
this.payload = new SpriteCluePayload(this.scene); const baseHeight = Math.max(this.scene.cameras.main.width * 0.035, 30); // max(3.5vw,32px)
this.payload =
Math.random() < 0.5
? new TextCluePayload(this.scene, baseHeight)
: new SpriteCluePayload(this.scene, baseHeight);
this.payload.once("CLUE_PAYLOAD_READY", this.showTexture.bind(this)); this.payload.once("addedtoscene", this.showTexture.bind(this));
this.payload.loadWord(word); this.payload.loadWord(word);
} }
......
import "phaser";
import FightScene from "./fight_scene";
import * as Types from "../../../backend/src/types";
interface CluePayload {
baseHeight: number;
loadWord: (word: Types.Word) => void;
delete: () => void;
}
//=[ Text clues ]===============================================================
import { FONTS } from "./assets";
const GERMAN_ALPHABET =
"ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜẞ" + "abcdefghijklmnopqrstuvwxyzäöüß";
const TEXT_STYLE: {
[key: string]: (height: number) => Phaser.Types.GameObjects.Text.TextStyle;
} = {
TYPEWRITER: (height) => {
return {
fontSize: `${height * 1.4}px`,
fontFamily: FONTS.MONO,
fontStyle: "bold",
color: "white",
stroke: "black",
strokeThickness: 8,
testString: GERMAN_ALPHABET,
};
},
TRAINING: (height) => {
return {
fontSize: `${height * 1.4}px`,
fontFamily: FONTS.FRAK,
color: "white",
stroke: "black",
strokeThickness: 8,
testString: GERMAN_ALPHABET,
};
},
NEWSPAPER: (height) => {
return {
fontSize: `${height * 1.4}px`,
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;
constructor(scene: FightScene, baseHeight: number) {
super(scene, 0, 0, "", TEXT_STYLE.TYPEWRITER(baseHeight));
this.setAlpha(0);
this.baseHeight = baseHeight;
}
loadWord(word: Types.Word) {
this.setText(word.ocr_transcript);
this.scene.add.existing(this);
}
delete() {
this.destroy();
}
}
//=[ Sprite clues ]=============================================================
// const HYPERASCENDERS = /[ÄÖÜ]/;
const ASCENDERS = /[ABCDEFGHIJKLMNOPQRSTUVWXYZbdfhijklstäöüß]/;
const DESCENDERS = /[AFHJPQYZÄfghjpqsyzß]/;
export class SpriteCluePayload
extends Phaser.GameObjects.Sprite
implements CluePayload
{
baseHeight: number;
constructor(scene: FightScene, baseHeight: number) {
super(scene, 0, 0, "__MISSING");
this.setAlpha(0);
this.baseHeight = baseHeight;
}
loadWord(word: Types.Word) {
// NOTE: this is a throwaway key, we're not leveraging cache
const textureKey = `${word.id}-${Date.now()}`;
this.scene.textures.addBase64(textureKey, word.image);
this.scene.textures.once("addtexture", () => {
this.setTexture(textureKey);
this.adjustTextureScale(word);
this.scene.add.existing(this);
});
}
adjustTextureScale(word: Types.Word) {
const fullHeight = this.estimateRelativeFullHeight(word) * this.baseHeight;
const scale = fullHeight / this.texture.getSourceImage().height;
this.setScale(scale);
}
estimateRelativeFullHeight(word: Types.Word) {
let height = 1.0;
// if (word.ocr_transcript.match(HYPERASCENDERS)) height += 0.2;
if (word.ocr_transcript.match(ASCENDERS)) height += 0.2;
if (word.ocr_transcript.match(DESCENDERS)) height += 0.2;
return height;
}
delete() {
this.texture.destroy();
this.destroy();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment