From 58ed29fc17bdf504d004f7965631542c431a3808 Mon Sep 17 00:00:00 2001 From: Jon Eugster Date: Sun, 23 Jul 2023 16:31:54 +0200 Subject: [PATCH] colorise world-tree dependent of completion of levels --- client/src/components/landing_page.tsx | 1 - client/src/components/welcome.tsx | 65 +++++++++++++++++++------- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/client/src/components/landing_page.tsx b/client/src/components/landing_page.tsx index 0427eae..08c1e75 100644 --- a/client/src/components/landing_page.tsx +++ b/client/src/components/landing_page.tsx @@ -26,7 +26,6 @@ function GithubIcon({url='https://github.com'}) { return
diff --git a/client/src/components/welcome.tsx b/client/src/components/welcome.tsx index 1d13fbb..ab4c120 100644 --- a/client/src/components/welcome.tsx +++ b/client/src/components/welcome.tsx @@ -18,26 +18,26 @@ import WorldSelectionMenu from './world_selection_menu'; import {PrivacyPolicy} from './privacy_policy'; import { Button } from './button'; import { Documentation, Inventory } from './inventory'; +import { store } from '../state/store'; cytoscape.use( klay ); -const N = 24 // max number of levels per world +const N = 18 // max number of levels per world const R = 800 // radius of a world -const r = 110 // radius of a level -const s = 100 // global scale +const r = 160 // radius of a level +const s = 120 // global scale const padding = 2000 // padding of the graphic (on a different scale) -function LevelIcon({ worldId, levelId, position }) { +function LevelIcon({ worldId, levelId, position, completed, available }) { const gameId = React.useContext(GameIdContext) - const completed = useSelector(selectCompleted(gameId, worldId,levelId)) - const x = s * position.x + Math.sin(levelId * 2 * Math.PI / N) * (R + 1.2*r + 2*Math.floor((levelId - 1)/N)) - const y = s * position.y - Math.cos(levelId * 2 * Math.PI / N) * (R + 1.2*r + 2*Math.floor((levelId - 1)/N)) + const x = s * position.x + Math.sin(levelId * 2 * Math.PI / N) * (R + 1.2*r + 2.4*r*Math.floor((levelId - 1)/N)) + const y = s * position.y - Math.cos(levelId * 2 * Math.PI / N) * (R + 1.2*r + 2.4*r*Math.floor((levelId - 1)/N)) // TODO: relative positioning? return ( - + ) } @@ -72,35 +72,64 @@ function Welcome() { const svgElements = [] + // For each `worldId` as index, this contains a list of booleans with indices + // 0, 1, …, n. Index `0` will be set to `false` if any dependency is not completely solved. + // Indices `1, …, n` indicate if the corresponding level is completed + var completed = {} + if (gameInfo.data) { + + // Fill `completed` with the level data. + for (let worldId in nodes) { + let position: cytoscape.Position = nodes[worldId].position + let state = store.getState() + + completed[worldId] = Array.from({ length: gameInfo.data.worldSize[worldId] + 1 }, (_, i) => { + // Index `0` might be set to `false` in the loop over the edges + if (!i) {return true} + return selectCompleted(gameId, worldId, i)(state) + }) + } + for (let i in gameInfo.data.worlds.edges) { const edge = gameInfo.data.worlds.edges[i] + + // If the origin world is not completed, mark the target world as non-playable + let unlocked = completed[edge[0]].slice(1).every(Boolean) + if (!unlocked) {completed[edge[1]][0] = false} + + // Draw the connection edges svgElements.push( + x2={s*nodes[edge[1]].position.x} y2={s*nodes[edge[1]].position.y} + stroke={unlocked ? "green" : "#bbb"} strokeWidth={s}/> ) } - for (let id in nodes) { - let position: cytoscape.Position = nodes[id].position - - for (let i = 1; i <= gameInfo.data.worldSize[id]; i++) { + for (let worldId in nodes) { + // Draw the level bubbles + let position: cytoscape.Position = nodes[worldId].position + for (let i = 1; i <= gameInfo.data.worldSize[worldId]; i++) { svgElements.push( + key={`/${gameId}/world/${worldId}/level/${i}`} + position={position} worldId={worldId} levelId={i} + completed={completed[worldId][i]} available={completed[worldId][i-1]}/> ) } + // Draw the worlds + let worldUnlocked = completed[worldId][0] + let worldCompleted = completed[worldId].slice(1).every(Boolean) svgElements.push( - + + fill={worldCompleted ? "green" : worldUnlocked ? "#1976d2": "#999"}/>

- {nodes[id].data.title ? nodes[id].data.title : id} + {nodes[worldId].data.title ? nodes[worldId].data.title : worldId}