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

feat: #be #fe fully track game events

parent 0fc59b98
No related branches found
No related tags found
No related merge requests found
...@@ -177,7 +177,7 @@ const apiPlugin: FastifyPluginCallback = (fastify, options, next) => { ...@@ -177,7 +177,7 @@ const apiPlugin: FastifyPluginCallback = (fastify, options, next) => {
handler: async (request, reply) => { handler: async (request, reply) => {
const shots = await connection const shots = await connection
.table("shots") .table("shots")
.insert(request.body) .insert({ game_id: request.params.id, ...request.body })
.returning<Types.Shot[]>("*"); .returning<Types.Shot[]>("*");
reply.code(200).send(shots[0]); reply.code(200).send(shots[0]);
......
...@@ -35,7 +35,16 @@ export const Shot = Type.Object({ ...@@ -35,7 +35,16 @@ export const Shot = Type.Object({
final: Type.String(), final: Type.String(),
}); });
export const GameUpdate = Type.Omit(Game, ["id"]); export const GameUpdate = Type.Partial(
export const ClueCreate = Type.Pick(Clue, ["word_id"]); Type.Pick(Game, ["began_at", "ended_at"]),
export const ClueUpdate = Type.Pick(Clue, ["began_at", "ended_at"]); );
export const ClueUpdate = Type.Partial(
Type.Pick(Clue, ["began_at", "ended_at"]),
);
export const ClueCreate = Type.Intersect([
Type.Pick(Clue, ["word_id"]),
ClueUpdate,
]);
export const ShotCreate = Type.Omit(Shot, ["id", "game_id"]); export const ShotCreate = Type.Omit(Shot, ["id", "game_id"]);
...@@ -122,7 +122,6 @@ export default class FightScene extends Phaser.Scene { ...@@ -122,7 +122,6 @@ export default class FightScene extends Phaser.Scene {
this.beGame = ( this.beGame = (
await backend.updateGame(this.beGame.id, { await backend.updateGame(this.beGame.id, {
began_at: new Date().toISOString(), began_at: new Date().toISOString(),
ended_at: null,
}) })
).data; ).data;
...@@ -230,7 +229,6 @@ export default class FightScene extends Phaser.Scene { ...@@ -230,7 +229,6 @@ export default class FightScene extends Phaser.Scene {
async endGame() { async endGame() {
this.beGame = ( this.beGame = (
await backend.updateGame(this.beGame.id, { await backend.updateGame(this.beGame.id, {
began_at: this.beGame.began_at, // TODO: make this optional in the type
ended_at: new Date().toISOString(), ended_at: new Date().toISOString(),
}) })
).data; ).data;
...@@ -238,11 +236,11 @@ export default class FightScene extends Phaser.Scene { ...@@ -238,11 +236,11 @@ export default class FightScene extends Phaser.Scene {
this.scene.start("game_over"); this.scene.start("game_over");
} }
showSubmitFeedback(color: string) { showSubmitFeedback(color: string, input: string) {
const text = this.add.text( const text = this.add.text(
this.cameras.main.width / 2, this.cameras.main.width / 2,
this.cameras.main.height / 2, this.cameras.main.height / 2,
this.hud.input.text, input,
{ {
font: "bold 64px Courier", font: "bold 64px Courier",
color: color, color: color,
...@@ -300,21 +298,29 @@ export default class FightScene extends Phaser.Scene { ...@@ -300,21 +298,29 @@ export default class FightScene extends Phaser.Scene {
} }
submitTranscription(inputStatus: InputStatus) { submitTranscription(inputStatus: InputStatus) {
// NOTE: this ain't async to avoid any UX delay
const { score, match } = this.findMatchingFoe(inputStatus.final); const { score, match } = this.findMatchingFoe(inputStatus.final);
// TODO: visual near misses based on score backend.createShot(this.beGame.id, {
clue_id: match?.beClue?.id || null,
...inputStatus,
});
if (match === null) { if (match === null) {
// NOOP // NOOP
this.showSubmitFeedback("#FFFFFF"); this.showSubmitFeedback("#FFFFFF", inputStatus.final);
} else if (score < 0.9) { } else if (score < 0.9) {
// TODO: visual near misses based on score
this.updateScore(-1); this.updateScore(-1);
match.handleFailure(); match.handleFailure();
this.showSubmitFeedback("#FF0000"); this.showSubmitFeedback("#FF0000", inputStatus.final);
new Spear(this, this.player, undefined); new Spear(this, this.player, undefined);
} else { } else {
backend.updateClue(match.beClue.id, {
ended_at: new Date().toISOString(),
});
this.updateScore(+10); this.updateScore(+10);
this.popFoe(match); this.popFoe(match);
match.handleSuccess(); match.handleSuccess();
this.showSubmitFeedback("#00FF00"); this.showSubmitFeedback("#00FF00", inputStatus.final);
new Spear(this, this.player, match.critter); new Spear(this, this.player, match.critter);
// TODO: increase score // TODO: increase score
} }
...@@ -323,17 +329,17 @@ export default class FightScene extends Phaser.Scene { ...@@ -323,17 +329,17 @@ export default class FightScene extends Phaser.Scene {
createAndBindTypewriter() { createAndBindTypewriter() {
this.typewriter ??= new Typewriter(); this.typewriter ??= new Typewriter();
this.typewriter.setHidden(this.game.device.os.desktop); this.typewriter.setHidden(this.game.device.os.desktop);
this.typewriter.onSubmit = (inputStatus) => { this.typewriter.onSubmit = async (inputStatus) => {
if (inputStatus.began_at === null) return; if (inputStatus.began_at === null) return;
if (inputStatus.ended_at === null) return; if (inputStatus.ended_at === null) return;
if (inputStatus.final === "") return; if (inputStatus.final === "") return;
this.hud.input.text = "";
this.submitTranscription({ this.submitTranscription({
began_at: inputStatus.began_at.toISOString(), began_at: inputStatus.began_at.toISOString(),
ended_at: inputStatus.ended_at.toISOString(), ended_at: inputStatus.ended_at.toISOString(),
typed: inputStatus.typed, typed: inputStatus.typed,
final: inputStatus.final, final: inputStatus.final,
}); });
this.hud.input.text = "";
}; };
this.typewriter.onChange = (inputStatus) => { this.typewriter.onChange = (inputStatus) => {
this.hud.input.text = inputStatus.final; this.hud.input.text = inputStatus.final;
......
...@@ -21,17 +21,12 @@ class Foe { ...@@ -21,17 +21,12 @@ class Foe {
async initialize() { async initialize() {
this.beWord = (await backend.getWord()).data; this.beWord = (await backend.getWord()).data;
if (!this.scene.scene.isActive()) return; if (!this.scene.scene.isActive()) return;
// this.beClue = ( this.beClue = (
// await backend.createClue(this.scene.beGame.id, { await backend.createClue(this.scene.beGame.id, {
// word_id: this.beWord.id, word_id: this.beWord.id,
// }) began_at: new Date().toISOString(),
// ).data; })
// this.beClue = ( ).data;
// await backend.updateClue(this.beClue.id, {
// began_at: new Date().toISOString(),
// ended_at: null,
// })
// ).data;
this.clue = new Clue(this.scene, this.beWord); this.clue = new Clue(this.scene, this.beWord);
this.critter = new Critter(this.scene); this.critter = new Critter(this.scene);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment