From 333447f64f70a206c6b2c8f41b9c82d3056eb63d Mon Sep 17 00:00:00 2001 From: caedenph Date: Mon, 19 Aug 2024 22:30:59 +0100 Subject: [PATCH] feat: Implement results-table [WIP] --- src/routes/game.ts | 4 +- src/routes/results.ts | 24 +++++--- src/routes/start.ts | 2 +- src/ui/handler.ts | 126 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 144 insertions(+), 12 deletions(-) diff --git a/src/routes/game.ts b/src/routes/game.ts index 305f715..33e44b0 100644 --- a/src/routes/game.ts +++ b/src/routes/game.ts @@ -527,8 +527,10 @@ export class CogSpeedGame { */ public async start(time: number | null = null) { this.ui?.setupGame(this); - + this.stop(0); this.startTime = time === null ? performance.now() : time; + return; + this.maxTestTimeout = setTimeout(this.stop.bind(this), this.config.timeouts.max_test_duration); this.nextRound(); } diff --git a/src/routes/results.ts b/src/routes/results.ts index eadd83b..51768c4 100644 --- a/src/routes/results.ts +++ b/src/routes/results.ts @@ -278,10 +278,17 @@ export class ProcessResultsPage { normalizedLocation, }; + data.sleepData.fatigueLevel = 2; + data.cognitiveProcessingIndex = 20; + data.blockingRoundDuration = 3000; + + // Add table to top of page + const resultsTableContainer = this.ui.createResultsTable(data.sleepData.fatigueLevel, data.cognitiveProcessingIndex, data.blockingRoundDuration, this.app.screen.height * 0.15); + const summaryPageButtonContainer = this.ui.createButton( - "View test summary", + "Test summary", this.app.screen.width * 0.5, - this.app.screen.height * 0.3, + this.app.screen.height * 0.40, this.app.screen.width * 0.6, this.app.screen.height * 0.2 ); @@ -294,9 +301,9 @@ export class ProcessResultsPage { delete responseData["answerLogs"]; const viewTestLogsButtonContainer = this.ui.createButton( - "View test logs", + "Test logs", this.app.screen.width * 0.5, - this.app.screen.height * 0.45, + this.app.screen.height * 0.53, this.app.screen.width * 0.6, this.app.screen.height * 0.2 ); @@ -306,9 +313,9 @@ export class ProcessResultsPage { ); const restartTestButtonContainer = this.ui.createButton( - "Restart test", + "Restart", this.app.screen.width * 0.5, - this.app.screen.height * 0.6, + this.app.screen.height * 0.7, this.app.screen.width * 0.6, this.app.screen.height * 0.2 ); @@ -319,9 +326,9 @@ export class ProcessResultsPage { }); const homeButton = this.ui.createButton( - "Go back to home", + "Home", this.app.screen.width * 0.5, - this.app.screen.height * 0.80, + this.app.screen.height * 0.83, this.app.screen.width * 0.6, this.app.screen.height * 0.2 ); @@ -336,6 +343,7 @@ export class ProcessResultsPage { loadingContainer.destroy(); } + this.app.stage.addChild(resultsTableContainer); this.app.stage.addChild(summaryPageButtonContainer); this.app.stage.addChild(viewTestLogsButtonContainer); this.app.stage.addChild(restartTestButtonContainer); diff --git a/src/routes/start.ts b/src/routes/start.ts index a1271cd..4f819dc 100644 --- a/src/routes/start.ts +++ b/src/routes/start.ts @@ -169,7 +169,7 @@ export class StartPage { }); // Version text - this.createText(`Version ${this.config.version}`, this.app.screen.width * 0.5, this.app.screen.height * 0.03, 11, {wordWrap: true}); + this.createText(`Version ${this.config.version}`, this.app.screen.width * 0.5, this.app.screen.height * 0.03, 14, {wordWrap: true}); await this.waitForKeyPress(testNowContainer); } diff --git a/src/ui/handler.ts b/src/ui/handler.ts index 45cb611..241be42 100644 --- a/src/ui/handler.ts +++ b/src/ui/handler.ts @@ -1,4 +1,4 @@ -import { Application, Container, Point, Rectangle, Sprite, Text, Texture } from "pixi.js"; +import { Application, Container, Graphics, Point, Rectangle, Sprite, Text, Texture } from "pixi.js"; import buttonTextureImage from "../assets/button.png"; import invertedButtonTextureImage from "../assets/button_inverted.png"; @@ -119,10 +119,132 @@ export class CogSpeedGraphicsHandler { } public async emulateLoadingTime() { - const loadingTime = process.env.NODE_ENV === "development" ? 100 : 3000; + const loadingTime = process.env.NODE_ENV === "development" ? 0 : 3000; await new Promise((resolve) => setTimeout(resolve, loadingTime)); } + private _getMapValue(map: Record, value: number, inverse=false): number { + let v = null; + for (const [key, value_] of Object.entries(map)) { + if (inverse) { + if (value < Number.parseInt(key)) v = value_; + } else { + if (value > Number.parseInt(key)) v = value_; + } + } + if (v == null) { + return inverse ? 0xF4B4B4 : 0x7CE8FF; + } + return v; + } + + public createResultsTable(spfScore: 1 | 2 | 3 | 4 | 5 | 6 | 7, cpiScore: number, blockingRoundDuration: number, yPos: number): Container { + const _spfScoreMap = { + 1: 0xF4B4B4, + 2: 0xff644e, + 3: 0xFFB05C, + 4: 0xFFEE67, + 5: 0xC1F46A, + 6: 0xA7EA63, + 7: 0x7CE8FF + }; + + // COGSPEED Score Mapping + const _cogspeedScoreMap = { + 0: 0xF4B4B4, // 0 - < 0 + 1: 0xff644e, // 10 - 1 + 11: 0xFFB05C, // 25 - 11 + 26: 0xFFEE67, // 50 - 26 + 51: 0xC1F46A, // 75 - 51 + 76: 0xA7EA63, // 90 - 76 + 91: 0x7CE8FF // 100 - 91 + }; + + // Blocking Round Duration Mapping + const _blockingRoundDurationMap = { + 1800: 0xF4B4B4, // >1800 ms + 1690: 0xff644e, // 1690-1789 ms + 1525: 0xFFB05C, // 1525-1668 ms + 1250: 0xFFEE67, // 1250-1514 ms + 975: 0xC1F46A, // 975-1239 ms + 810: 0xA7EA63, // 810-964 ms + 700: 0x7CE8FF // 700-799 ms + }; + + const container = new Container(); + + + const screenWidth = this.app.screen.width; + const screenHeight = this.app.screen.height; + + const width = screenWidth * 0.28; + const height = screenHeight * 0.05; + + const marginLeft = screenWidth * 0.08; + + // First column, SPF + const headerBoxSPF = new Graphics(); + headerBoxSPF.beginFill(0xffffff); + headerBoxSPF.lineStyle(2, 0xafafaf); + headerBoxSPF.drawRect(marginLeft, yPos, width, height); + + const headerTextSPF = new Text("S-P-F Score", {fill: 0x00000, fontSize: 14}) + headerTextSPF.position.set(screenWidth * 0.135, yPos + 8); + + const valueBoxSPF = new Graphics(); + let colour = _spfScoreMap[spfScore]; + valueBoxSPF.beginFill(colour); + valueBoxSPF.lineStyle(2, 0xafafaf); + valueBoxSPF.drawRect(marginLeft, yPos + height, width, height); + + + // Second column, CPI + const headerBoxCPI = new Graphics(); + headerBoxCPI.beginFill(0xffffff); + headerBoxCPI.lineStyle(2, 0xafafaf); + headerBoxCPI.drawRect(marginLeft + width, yPos, width, height); + + const headerTextCPI = new Text("Cogspeed Score", {fill: 0x00000, fontSize: 14}) + headerTextCPI.position.set(screenWidth * 0.105 + width, yPos + 8); + + const valueBoxCPI = new Graphics(); + colour = this._getMapValue(_cogspeedScoreMap, cpiScore); + valueBoxCPI.beginFill(colour); + valueBoxCPI.lineStyle(2, 0xafafaf); + valueBoxCPI.drawRect(marginLeft + width, yPos + height, width, height); + + // Third column, BRD + const headerBoxBRD = new Graphics(); + headerBoxBRD.beginFill(0xffffff); + headerBoxBRD.lineStyle(2, 0xafafaf); + headerBoxBRD.drawRect(marginLeft + width * 2, yPos, width, height); + + const headerTextBRD = new Text("BRD Duration", {fill: 0x00000, fontSize: 14}) + headerTextBRD.position.set(screenWidth * 0.12 + width * 2, yPos + 8); + + const valueBoxBRD = new Graphics(); + colour = this._getMapValue(_blockingRoundDurationMap, blockingRoundDuration); + valueBoxBRD.beginFill(colour); + valueBoxBRD.lineStyle(2, 0xafafaf); + valueBoxBRD.drawRect(marginLeft + width * 2, yPos + height, width, height); + + + container.addChild(headerBoxSPF); + container.addChild(valueBoxSPF); + container.addChild(headerBoxCPI); + container.addChild(valueBoxCPI); + container.addChild(headerBoxBRD); + container.addChild(valueBoxBRD); + + container.addChild(headerTextSPF); + container.addChild(headerTextCPI); + container.addChild(headerTextBRD); + + + + return container; + } + public createButton(content: string, x: number, y: number, width: number, height: number, fontSize: number = 24): Container { const container = new Container(); container.eventMode = "dynamic";