Release 2.0.0
Updated display and host
This commit is contained in:
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "jeopardy",
|
"name": "jeopardy",
|
||||||
"version": "1.0.6",
|
"version": "2.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "jeopardy",
|
"name": "jeopardy",
|
||||||
"version": "1.0.6",
|
"version": "2.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.12.2",
|
"axios": "^1.12.2",
|
||||||
"cookie": "^1.0.2"
|
"cookie": "^1.0.2"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "jeopardy",
|
"name": "jeopardy",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.6",
|
"version": "2.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite dev",
|
"dev": "vite dev",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { FullGame, FullWall } from "./games/games";
|
import type { Game, Wall } from "./Types";
|
||||||
|
|
||||||
interface Player {
|
interface Player {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -8,10 +8,9 @@ interface Player {
|
|||||||
const baseRoute = "/connected/display/running";
|
const baseRoute = "/connected/display/running";
|
||||||
let players: Player[] = $state([]);
|
let players: Player[] = $state([]);
|
||||||
let currentPlayer: string = $state("");
|
let currentPlayer: string = $state("");
|
||||||
// eslint-disable-next-line prefer-const
|
let game: Game | undefined = $state();
|
||||||
let game: FullGame | undefined = undefined;
|
|
||||||
let gameIndex: number = -1;
|
let gameIndex: number = -1;
|
||||||
let wall: FullWall | undefined = undefined;
|
let wall: Wall | undefined = $state();
|
||||||
let wallIndex: number = -1;
|
let wallIndex: number = -1;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -29,7 +28,7 @@ export default {
|
|||||||
currentPlayer = str;
|
currentPlayer = str;
|
||||||
},
|
},
|
||||||
baseRoute,
|
baseRoute,
|
||||||
get game(): FullGame | undefined {
|
get game(): Game | undefined {
|
||||||
return game;
|
return game;
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
@@ -42,7 +41,7 @@ export default {
|
|||||||
set gameIndex(i: number) {
|
set gameIndex(i: number) {
|
||||||
gameIndex = i;
|
gameIndex = i;
|
||||||
},
|
},
|
||||||
get wall(): FullWall | undefined {
|
get wall(): Wall | undefined {
|
||||||
return wall;
|
return wall;
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import type {
|
|||||||
SimpleQuestion
|
SimpleQuestion
|
||||||
} from "./games/games";
|
} from "./games/games";
|
||||||
|
|
||||||
export type VisitedQuestions = number[][];
|
export type VisitedQuestions = QuestionId[];
|
||||||
|
|
||||||
export type Directory = {
|
export type Directory = {
|
||||||
name: string;
|
name: string;
|
||||||
|
|||||||
@@ -24,10 +24,6 @@
|
|||||||
isEditor?: boolean;
|
isEditor?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isVisited(catIndex: number, queIndex: number): boolean {
|
|
||||||
return visited[catIndex] && visited[catIndex].includes(queIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
let { wall, onclick, onclickIds, visited, isEditor = false }: Props = $props();
|
let { wall, onclick, onclickIds, visited, isEditor = false }: Props = $props();
|
||||||
|
|
||||||
let categories: Category[] = $state([]);
|
let categories: Category[] = $state([]);
|
||||||
@@ -107,10 +103,10 @@
|
|||||||
>
|
>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#each category.questions as question, queIndex}
|
{#each category.questions as question}
|
||||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||||
<div
|
<div
|
||||||
class="card {isVisited(catIndex, queIndex) ? 'visited' : ''}"
|
class="card {visited.includes(`${question._id}`) ? 'visited' : ''}"
|
||||||
role="button"
|
role="button"
|
||||||
aria-pressed="false"
|
aria-pressed="false"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@@ -125,27 +121,7 @@
|
|||||||
{/each}
|
{/each}
|
||||||
{/each}
|
{/each}
|
||||||
{:else}
|
{:else}
|
||||||
{#each wall.categories as category, catIndex}
|
Legacy Not Supported
|
||||||
<div class="flex items-center justify-center text-3xl font-semibold">
|
|
||||||
<div>{category.name}</div>
|
|
||||||
</div>
|
|
||||||
{#each category.questions as question, queIndex}
|
|
||||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
||||||
<div
|
|
||||||
class="card {isVisited(catIndex, queIndex) ? 'visited' : ''}"
|
|
||||||
role="button"
|
|
||||||
aria-pressed="false"
|
|
||||||
tabindex="0"
|
|
||||||
onclick={() => {
|
|
||||||
if (onclick) onclick(catIndex, queIndex);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div class="text-6xl font-thin">
|
|
||||||
{question.points >= 0 ? question.points : "???"}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
{/each}
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
|
|||||||
@@ -2,29 +2,17 @@
|
|||||||
let { children } = $props();
|
let { children } = $props();
|
||||||
|
|
||||||
import { error } from "@sveltejs/kit";
|
import { error } from "@sveltejs/kit";
|
||||||
import games from "$lib/games/games";
|
// import games from "$lib/games/games";
|
||||||
import { page } from "$app/state";
|
import { page } from "$app/state";
|
||||||
import DisplayStateSvelte from "$lib/DisplayState.svelte";
|
import DisplayStateSvelte from "$lib/DisplayState.svelte";
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
import { fetchGame } from "../../../../editor/fetchers";
|
||||||
|
|
||||||
console.log("game:", page.params.game);
|
onMount(() => {
|
||||||
|
fetchGame(`${page.params.game}`).then((game) => {
|
||||||
let paramGame = page.params.game;
|
|
||||||
if (paramGame === undefined) {
|
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
const gameIndex = parseInt(paramGame);
|
|
||||||
if (isNaN(gameIndex)) {
|
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
if (DisplayStateSvelte.gameIndex !== gameIndex) {
|
|
||||||
const game = games[gameIndex];
|
|
||||||
if (game) {
|
|
||||||
DisplayStateSvelte.game = game;
|
DisplayStateSvelte.game = game;
|
||||||
DisplayStateSvelte.gameIndex = gameIndex;
|
});
|
||||||
} else {
|
});
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex grow flex-col pr-4 pl-4">
|
<div class="flex grow flex-col pr-4 pl-4">
|
||||||
|
|||||||
@@ -6,27 +6,11 @@
|
|||||||
import ws from "$lib/websocket.svelte";
|
import ws from "$lib/websocket.svelte";
|
||||||
import { MessageType } from "$lib/MessageType";
|
import { MessageType } from "$lib/MessageType";
|
||||||
import type { VisitedQuestions } from "$lib/Types";
|
import type { VisitedQuestions } from "$lib/Types";
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
import { fetchWall } from "../../../../../editor/fetchers";
|
||||||
|
|
||||||
console.log("wall:", page.params.wall);
|
console.log("wall:", page.params.wall);
|
||||||
|
|
||||||
let paramWall = page.params.wall;
|
|
||||||
if (paramWall === undefined) {
|
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
const wallIndex = parseInt(paramWall);
|
|
||||||
if (isNaN(wallIndex)) {
|
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
if (DisplayStateSvelte.wallIndex !== wallIndex) {
|
|
||||||
const wall = DisplayStateSvelte.game?.walls[wallIndex];
|
|
||||||
if (wall) {
|
|
||||||
DisplayStateSvelte.wall = wall;
|
|
||||||
DisplayStateSvelte.gameIndex = wallIndex;
|
|
||||||
} else {
|
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let visited: VisitedQuestions = $state([]);
|
let visited: VisitedQuestions = $state([]);
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
@@ -40,6 +24,12 @@
|
|||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
fetchWall(`${page.params.wall}`).then((wall) => {
|
||||||
|
DisplayStateSvelte.wall = wall;
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Wall wall={DisplayStateSvelte.wall} {visited} />
|
<Wall wall={DisplayStateSvelte.wall} {visited} />
|
||||||
|
|||||||
@@ -9,65 +9,22 @@
|
|||||||
isImageMultipleChoiceQuestion,
|
isImageMultipleChoiceQuestion,
|
||||||
isImageQuestion,
|
isImageQuestion,
|
||||||
isMultipleChoiceQuestion,
|
isMultipleChoiceQuestion,
|
||||||
isSimpleQuestion
|
isSimpleQuestion,
|
||||||
|
type Question
|
||||||
} from "$lib/games/games";
|
} from "$lib/games/games";
|
||||||
import ws from "$lib/websocket.svelte";
|
import ws from "$lib/websocket.svelte";
|
||||||
import { MessageType } from "$lib/MessageType";
|
import { MessageType } from "$lib/MessageType";
|
||||||
import { untrack } from "svelte";
|
import { onMount, untrack } from "svelte";
|
||||||
import MultipleChoiceQuestionComponent from "$lib/MultipleChoiceQuestionComponent.svelte";
|
import MultipleChoiceQuestionComponent from "$lib/MultipleChoiceQuestionComponent.svelte";
|
||||||
import ImageQuestionComponent from "$lib/ImageQuestionComponent.svelte";
|
import ImageQuestionComponent from "$lib/ImageQuestionComponent.svelte";
|
||||||
import AudioQuestionComponent from "$lib/AudioQuestionComponent.svelte";
|
import AudioQuestionComponent from "$lib/AudioQuestionComponent.svelte";
|
||||||
import AudioMultipleChoiceQuestionComponent from "$lib/AudioMultipleChoiceQuestionComponent.svelte";
|
import AudioMultipleChoiceQuestionComponent from "$lib/AudioMultipleChoiceQuestionComponent.svelte";
|
||||||
import ImageMultipleChoiceQuestionComponent from "$lib/ImageMultipleChoiceQuestionComponent.svelte";
|
import ImageMultipleChoiceQuestionComponent from "$lib/ImageMultipleChoiceQuestionComponent.svelte";
|
||||||
|
import { fetchCategory, fetchQuestion } from "../../../../../../../editor/fetchers";
|
||||||
|
import type { Category, GeneralQuestion } from "$lib/Types";
|
||||||
|
|
||||||
console.log("wall:", page.params.wall);
|
let category: Category | undefined = $state();
|
||||||
|
let question: GeneralQuestion | undefined = $state();
|
||||||
let paramWall = page.params.wall;
|
|
||||||
if (paramWall === undefined) {
|
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
const wallIndex = parseInt(paramWall);
|
|
||||||
if (isNaN(wallIndex)) {
|
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
if (DisplayStateSvelte.wallIndex !== wallIndex) {
|
|
||||||
const wall = DisplayStateSvelte.game?.walls[wallIndex];
|
|
||||||
if (wall) {
|
|
||||||
DisplayStateSvelte.wall = wall;
|
|
||||||
DisplayStateSvelte.gameIndex = wallIndex;
|
|
||||||
} else {
|
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (page.params.category === undefined) {
|
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
const categoryIndex = parseInt(page.params.category);
|
|
||||||
if (isNaN(categoryIndex)) {
|
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
|
|
||||||
const category = DisplayStateSvelte.wall?.categories[categoryIndex];
|
|
||||||
|
|
||||||
if (category === undefined) {
|
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (page.params.question === undefined) {
|
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
const questionIndex = parseInt(page.params.question);
|
|
||||||
if (isNaN(questionIndex)) {
|
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
|
|
||||||
const question = category.questions[questionIndex];
|
|
||||||
|
|
||||||
console.log(question);
|
|
||||||
|
|
||||||
if (question === undefined) {
|
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
|
|
||||||
let showAnswer = $state(false);
|
let showAnswer = $state(false);
|
||||||
let showQuestion = $state(false);
|
let showQuestion = $state(false);
|
||||||
@@ -118,42 +75,71 @@
|
|||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
fetchCategory(`${page.params.category}`)
|
||||||
|
.then((cat) => {
|
||||||
|
category = cat;
|
||||||
|
return fetchQuestion(`${page.params.question}`);
|
||||||
|
})
|
||||||
|
.then((que) => {
|
||||||
|
question = que;
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="mt-4 flex grow flex-col">
|
{#if category && question}
|
||||||
<div class="mb-4 flex justify-between text-4xl">
|
<div class="mt-4 flex grow flex-col">
|
||||||
<div>{category.name}</div>
|
<div class="mb-4 flex justify-between text-4xl">
|
||||||
<div>
|
<div>{category.name}</div>
|
||||||
{question.points} Punkte
|
<div>
|
||||||
|
{question.points} Punkte
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex grow flex-col">
|
||||||
|
{#if question === undefined}
|
||||||
|
<p>Question is undefined</p>
|
||||||
|
{:else if isSimpleQuestion(question)}
|
||||||
|
<SimpleQuestionComponent {question} {showAnswer} {showQuestion} />
|
||||||
|
{:else if isMultipleChoiceQuestion(question)}
|
||||||
|
<MultipleChoiceQuestionComponent {question} {showAnswer} {showQuestion} />
|
||||||
|
{:else if isImageQuestion(question)}
|
||||||
|
<ImageQuestionComponent
|
||||||
|
{question}
|
||||||
|
{showAnswer}
|
||||||
|
{showQuestion}
|
||||||
|
{isBuzzed}
|
||||||
|
isLegacy={false}
|
||||||
|
/>
|
||||||
|
{:else if isImageMultipleChoiceQuestion(question)}
|
||||||
|
<ImageMultipleChoiceQuestionComponent
|
||||||
|
{question}
|
||||||
|
{showAnswer}
|
||||||
|
{showQuestion}
|
||||||
|
{isBuzzed}
|
||||||
|
isLegacy={false}
|
||||||
|
/>
|
||||||
|
{:else if isAudioQuestion(question)}
|
||||||
|
<AudioQuestionComponent
|
||||||
|
{question}
|
||||||
|
{showAnswer}
|
||||||
|
{showQuestion}
|
||||||
|
showPlayer={false}
|
||||||
|
isLegacy={false}
|
||||||
|
/>
|
||||||
|
{:else if isAudioMultipleChoiceQuestion(question)}
|
||||||
|
<AudioMultipleChoiceQuestionComponent
|
||||||
|
{question}
|
||||||
|
{showAnswer}
|
||||||
|
{showQuestion}
|
||||||
|
showPlayer={false}
|
||||||
|
isLegacy={false}
|
||||||
|
/>
|
||||||
|
{:else}
|
||||||
|
<p>Type of question unknown</p>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex grow flex-col">
|
{:else}
|
||||||
{#if question === undefined}
|
Loading...
|
||||||
<p>Question is undefined</p>
|
{/if}
|
||||||
{:else if isSimpleQuestion(question)}
|
|
||||||
<SimpleQuestionComponent {question} {showAnswer} {showQuestion} />
|
|
||||||
{:else if isMultipleChoiceQuestion(question)}
|
|
||||||
<MultipleChoiceQuestionComponent {question} {showAnswer} {showQuestion} />
|
|
||||||
{:else if isImageQuestion(question)}
|
|
||||||
<ImageQuestionComponent {question} {showAnswer} {showQuestion} {isBuzzed} />
|
|
||||||
{:else if isImageMultipleChoiceQuestion(question)}
|
|
||||||
<ImageMultipleChoiceQuestionComponent
|
|
||||||
{question}
|
|
||||||
{showAnswer}
|
|
||||||
{showQuestion}
|
|
||||||
{isBuzzed}
|
|
||||||
/>
|
|
||||||
{:else if isAudioQuestion(question)}
|
|
||||||
<AudioQuestionComponent {question} {showAnswer} {showQuestion} showPlayer={false} />
|
|
||||||
{:else if isAudioMultipleChoiceQuestion(question)}
|
|
||||||
<AudioMultipleChoiceQuestionComponent
|
|
||||||
{question}
|
|
||||||
{showAnswer}
|
|
||||||
{showQuestion}
|
|
||||||
showPlayer={false}
|
|
||||||
/>
|
|
||||||
{:else}
|
|
||||||
<p>Type of question unknown</p>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
import games from '$lib/games/games';
|
|
||||||
|
|
||||||
export function load() {
|
|
||||||
return {
|
|
||||||
games
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,39 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
let { data } = $props();
|
import type { Game } from "$lib/Types";
|
||||||
|
import { url } from "$lib/util";
|
||||||
|
import axios from "axios";
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
|
let games: Game[] = $state([]);
|
||||||
|
|
||||||
|
function fetchGames() {
|
||||||
|
axios
|
||||||
|
.get(url("/games"), { withCredentials: true })
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
games = response.data;
|
||||||
|
games.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
} else {
|
||||||
|
console.error("Could not fetch games: " + response.status);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
fetchGames();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h1 class="m-4 mb-8 text-7xl font-bold">Games</h1>
|
<h1 class="m-4 mb-8 text-7xl font-bold">Games</h1>
|
||||||
|
|
||||||
<div class="flex flex-col space-y-4">
|
<div class="flex flex-col space-y-4">
|
||||||
{#each data.games as game, i}
|
{#each games as game}
|
||||||
<a
|
<a
|
||||||
class="ms-4 me-4 rounded-xl border-2 p-4 hover:cursor-pointer hover:bg-emerald-200"
|
class="ms-4 me-4 rounded-xl border-2 p-4 hover:cursor-pointer hover:bg-emerald-200"
|
||||||
href="/connected/games/{i}">{game.name}</a
|
href="/connected/games/{game._id}">{game.name}</a
|
||||||
>
|
>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
import { error } from '@sveltejs/kit';
|
|
||||||
import games from '$lib/games/games';
|
|
||||||
|
|
||||||
export function load({ params }) {
|
|
||||||
const index = parseInt(params.game);
|
|
||||||
if (isNaN(index)) {
|
|
||||||
error(404);
|
|
||||||
}
|
|
||||||
const game = games[index];
|
|
||||||
if (game === undefined) error(404);
|
|
||||||
else return game;
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,8 @@
|
|||||||
isAudioQuestion,
|
isAudioQuestion,
|
||||||
isAudioMultipleChoiceQuestion,
|
isAudioMultipleChoiceQuestion,
|
||||||
isImageMultipleChoiceQuestion,
|
isImageMultipleChoiceQuestion,
|
||||||
type FullGame
|
type FullGame,
|
||||||
|
type Question
|
||||||
} from "$lib/games/games";
|
} from "$lib/games/games";
|
||||||
import ws from "$lib/websocket.svelte";
|
import ws from "$lib/websocket.svelte";
|
||||||
import { page } from "$app/state";
|
import { page } from "$app/state";
|
||||||
@@ -18,12 +19,14 @@
|
|||||||
import Scoreboard from "$lib/Scoreboard.svelte";
|
import Scoreboard from "$lib/Scoreboard.svelte";
|
||||||
import SimpleQuestionComponent from "$lib/SimpleQuestionComponent.svelte";
|
import SimpleQuestionComponent from "$lib/SimpleQuestionComponent.svelte";
|
||||||
import PlusMinusButton from "$lib/PlusMinusButton.svelte";
|
import PlusMinusButton from "$lib/PlusMinusButton.svelte";
|
||||||
import type { VisitedQuestions } from "$lib/Types.js";
|
import type { _id, Category, Game, VisitedQuestions, Wall as WallType } from "$lib/Types.js";
|
||||||
import MultipleChoiceQuestionComponent from "$lib/MultipleChoiceQuestionComponent.svelte";
|
import MultipleChoiceQuestionComponent from "$lib/MultipleChoiceQuestionComponent.svelte";
|
||||||
import ImageQuestionComponent from "$lib/ImageQuestionComponent.svelte";
|
import ImageQuestionComponent from "$lib/ImageQuestionComponent.svelte";
|
||||||
import AudioQuestionComponent from "$lib/AudioQuestionComponent.svelte";
|
import AudioQuestionComponent from "$lib/AudioQuestionComponent.svelte";
|
||||||
import AudioMultipleChoiceQuestionComponent from "$lib/AudioMultipleChoiceQuestionComponent.svelte";
|
import AudioMultipleChoiceQuestionComponent from "$lib/AudioMultipleChoiceQuestionComponent.svelte";
|
||||||
import ImageMultipleChoiceQuestionComponent from "$lib/ImageMultipleChoiceQuestionComponent.svelte";
|
import ImageMultipleChoiceQuestionComponent from "$lib/ImageMultipleChoiceQuestionComponent.svelte";
|
||||||
|
import { fetchCategory, fetchGame, fetchQuestion, fetchWall } from "../../../editor/fetchers";
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
interface SaveData {
|
interface SaveData {
|
||||||
players: Player[];
|
players: Player[];
|
||||||
@@ -57,7 +60,7 @@
|
|||||||
|
|
||||||
class GameManager {
|
class GameManager {
|
||||||
public state: GameState = $state(GameState.INIT);
|
public state: GameState = $state(GameState.INIT);
|
||||||
public game: FullGame;
|
public game: Game | undefined = $state();
|
||||||
public players: Player[] = $state([
|
public players: Player[] = $state([
|
||||||
{
|
{
|
||||||
name: "Player 1",
|
name: "Player 1",
|
||||||
@@ -74,37 +77,42 @@
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
public currentPlayer = $state(0);
|
public currentPlayer = $state(0);
|
||||||
public currentWall = $state(0);
|
public currentWallIndex = $state(0);
|
||||||
|
public currentWall: WallType | undefined = $state();
|
||||||
public visitedQuestions: VisitedQuestions = $state([]);
|
public visitedQuestions: VisitedQuestions = $state([]);
|
||||||
public currentCategory = $state(0);
|
public currentCategoryId = $state("");
|
||||||
public currentQuestion = $state(0);
|
public currentCategory: Category | undefined = $state();
|
||||||
|
public currentQuestionId = $state("");
|
||||||
|
public currentQuestion: Question | undefined = $state();
|
||||||
|
|
||||||
public answerIsShowing = $state(false);
|
public answerIsShowing = $state(false);
|
||||||
public questionIsShowing = $state(false);
|
public questionIsShowing = $state(false);
|
||||||
public isBuzzed = $state(false);
|
public isBuzzed = $state(false);
|
||||||
|
|
||||||
constructor(game: FullGame) {
|
setGame(game: Game) {
|
||||||
this.game = game;
|
this.game = game;
|
||||||
}
|
}
|
||||||
|
|
||||||
save(): void {
|
save(): void {
|
||||||
|
if (!this.game) return;
|
||||||
const saveData = {
|
const saveData = {
|
||||||
players: this.players,
|
players: this.players,
|
||||||
currentPlayer: this.currentPlayer,
|
currentPlayer: this.currentPlayer,
|
||||||
currentWall: this.currentWall,
|
currentWall: this.currentWallIndex,
|
||||||
visitedQuestions: this.visitedQuestions
|
visitedQuestions: this.visitedQuestions
|
||||||
};
|
};
|
||||||
localStorage.setItem(`saveGame-${this.game.name}`, JSON.stringify(saveData));
|
localStorage.setItem(`saveGame-${this.game._id}`, JSON.stringify(saveData));
|
||||||
}
|
}
|
||||||
|
|
||||||
load(): void {
|
load(): void {
|
||||||
const saveDataString = localStorage.getItem(`saveGame-${this.game.name}`);
|
if (!this.game) return;
|
||||||
|
const saveDataString = localStorage.getItem(`saveGame-${this.game._id}`);
|
||||||
if (saveDataString === null) return;
|
if (saveDataString === null) return;
|
||||||
try {
|
try {
|
||||||
const saveData: SaveData = JSON.parse(saveDataString);
|
const saveData: SaveData = JSON.parse(saveDataString);
|
||||||
this.players = saveData.players;
|
this.players = saveData.players;
|
||||||
this.currentPlayer = saveData.currentPlayer;
|
this.currentPlayer = saveData.currentPlayer;
|
||||||
this.currentWall = saveData.currentWall;
|
this.currentWallIndex = saveData.currentWall;
|
||||||
this.visitedQuestions = saveData.visitedQuestions;
|
this.visitedQuestions = saveData.visitedQuestions;
|
||||||
console.log(saveData);
|
console.log(saveData);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -113,10 +121,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
startGame(): void {
|
startGame(): void {
|
||||||
|
if (!this.game) return;
|
||||||
this.currentPlayer = Math.floor(Math.random() * this.players.length);
|
this.currentPlayer = Math.floor(Math.random() * this.players.length);
|
||||||
this.state = GameState.CHOOSING_QUESTION;
|
this.state = GameState.CHOOSING_QUESTION;
|
||||||
this.sendStart();
|
fetchWall(this.game.walls[this.currentWallIndex]).then((wall) => {
|
||||||
this.sendCurrentState();
|
this.currentWall = wall;
|
||||||
|
this.sendStart();
|
||||||
|
this.sendCurrentState();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sendStart(): void {
|
sendStart(): void {
|
||||||
@@ -136,7 +148,7 @@
|
|||||||
sendWall(): void {
|
sendWall(): void {
|
||||||
ws.sendMessage({
|
ws.sendMessage({
|
||||||
type: MessageType.GOTO,
|
type: MessageType.GOTO,
|
||||||
route: `/${page.params.game}/${this.currentWall}`
|
route: `/${page.params.game}/${this.currentWall?._id}`
|
||||||
});
|
});
|
||||||
this.sendVisited();
|
this.sendVisited();
|
||||||
}
|
}
|
||||||
@@ -154,30 +166,39 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
sendCurrentQuestion(): void {
|
sendCurrentQuestion(): void {
|
||||||
|
if (!this.game) return;
|
||||||
ws.sendMessage({
|
ws.sendMessage({
|
||||||
type: MessageType.GOTO,
|
type: MessageType.GOTO,
|
||||||
route: `/${page.params.game}/${this.currentWall}/${this.currentCategory}/${this.currentQuestion}`
|
route: `/${this.game._id}/${this.currentWall?._id}/${this.currentCategoryId}/${this.currentQuestionId}`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sendEnd(): void {
|
sendEnd(): void {
|
||||||
ws.sendMessage({
|
ws.sendMessage({
|
||||||
type: MessageType.GOTO,
|
type: MessageType.GOTO,
|
||||||
route: `/${page.params.game}/${this.currentWall}/end`
|
route: `/${page.params.game}/${this.currentWall?._id}/end`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
tileClicked(categoryIndex: number, questionIndex: number) {
|
tileClicked(catId: _id, queId: _id) {
|
||||||
console.log("Cat", categoryIndex, "Que", questionIndex);
|
console.log("Cat", catId, "Que", queId);
|
||||||
console.log(gameManager.wall.categories[categoryIndex]?.questions[questionIndex]);
|
|
||||||
|
|
||||||
this.currentCategory = categoryIndex;
|
this.currentCategoryId = catId;
|
||||||
this.currentQuestion = questionIndex;
|
this.currentQuestionId = queId;
|
||||||
this.answerIsShowing = false;
|
this.answerIsShowing = false;
|
||||||
|
|
||||||
this.sendCurrentQuestion();
|
fetchCategory(this.currentCategoryId)
|
||||||
|
.then((category) => {
|
||||||
|
this.currentCategory = category;
|
||||||
|
|
||||||
this.state = GameState.SHOW_QUESTION;
|
return fetchQuestion(this.currentQuestionId);
|
||||||
|
})
|
||||||
|
.then((question) => {
|
||||||
|
this.currentQuestion = question;
|
||||||
|
|
||||||
|
this.sendCurrentQuestion();
|
||||||
|
this.state = GameState.SHOW_QUESTION;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addPlayer() {
|
addPlayer() {
|
||||||
@@ -236,20 +257,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
plus(player: Player) {
|
plus(player: Player) {
|
||||||
if (!this.answerIsShowing) return;
|
if (!this.answerIsShowing || !this.currentQuestion) return;
|
||||||
if (player.name === this.currentPlayerToName()) {
|
if (player.name === this.currentPlayerToName()) {
|
||||||
player.points += this.question.points * 2;
|
player.points += this.currentQuestion.points * 2;
|
||||||
} else {
|
} else {
|
||||||
player.points += this.question.points;
|
player.points += this.currentQuestion.points;
|
||||||
}
|
}
|
||||||
this.sendPlayers();
|
this.sendPlayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
minus(player: Player) {
|
minus(player: Player) {
|
||||||
|
if (!this.currentQuestion) return;
|
||||||
if (player.name === this.currentPlayerToName()) {
|
if (player.name === this.currentPlayerToName()) {
|
||||||
player.points -= this.question.points * 2;
|
player.points -= this.currentQuestion.points * 2;
|
||||||
} else {
|
} else {
|
||||||
player.points -= this.question.points;
|
player.points -= this.currentQuestion.points;
|
||||||
}
|
}
|
||||||
this.sendPlayers();
|
this.sendPlayers();
|
||||||
}
|
}
|
||||||
@@ -267,12 +289,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
finishQuestion(): void {
|
finishQuestion(): void {
|
||||||
if (this.visitedQuestions[this.currentCategory] == undefined) {
|
if (!this.visitedQuestions.includes(this.currentQuestionId)) {
|
||||||
this.visitedQuestions[this.currentCategory] = [this.currentQuestion];
|
this.visitedQuestions.push(this.currentQuestionId);
|
||||||
} else if (
|
|
||||||
!this.visitedQuestions[this.currentCategory].includes(this.currentQuestion)
|
|
||||||
) {
|
|
||||||
this.visitedQuestions[this.currentCategory].push(this.currentQuestion);
|
|
||||||
}
|
}
|
||||||
this.setupGoingBack();
|
this.setupGoingBack();
|
||||||
this.nextPlayer();
|
this.nextPlayer();
|
||||||
@@ -286,28 +304,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
wallIsDone(): boolean {
|
wallIsDone(): boolean {
|
||||||
let visitedNum = 0;
|
return this.visitedQuestions.length >= 25;
|
||||||
for (const questions of this.visitedQuestions) {
|
|
||||||
if (questions != undefined) {
|
|
||||||
visitedNum += questions.length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let totalNum = 0;
|
|
||||||
for (const category of this.wall.categories) {
|
|
||||||
totalNum += category.questions.length;
|
|
||||||
}
|
|
||||||
console.log(`${visitedNum} >= ${totalNum}`);
|
|
||||||
return visitedNum >= totalNum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
goToNextWall(): void {
|
goToNextWall(): void {
|
||||||
if (this.currentWall + 1 >= this.game.walls.length) {
|
if (!this.game) return;
|
||||||
|
if (this.currentWallIndex + 1 >= this.game.walls.length) {
|
||||||
this.goToEndScreen();
|
this.goToEndScreen();
|
||||||
} else {
|
} else {
|
||||||
this.currentWall += 1;
|
this.currentWallIndex += 1;
|
||||||
this.visitedQuestions = [];
|
this.visitedQuestions = [];
|
||||||
this.sendWall();
|
fetchWall(this.game.walls[this.currentWallIndex]).then((wall) => {
|
||||||
this.state = GameState.CHOOSING_QUESTION;
|
this.currentWall = wall;
|
||||||
|
this.sendWall();
|
||||||
|
this.state = GameState.CHOOSING_QUESTION;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,169 +335,175 @@
|
|||||||
currentPlayerToName(): string {
|
currentPlayerToName(): string {
|
||||||
return this.players[this.currentPlayer].name;
|
return this.players[this.currentPlayer].name;
|
||||||
}
|
}
|
||||||
|
|
||||||
get wall() {
|
|
||||||
return this.game.walls[this.currentWall];
|
|
||||||
}
|
|
||||||
|
|
||||||
get category() {
|
|
||||||
return this.wall.categories[this.currentCategory];
|
|
||||||
}
|
|
||||||
|
|
||||||
get question() {
|
|
||||||
return this.category.questions[this.currentQuestion];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let { data } = $props();
|
let gameManager = new GameManager();
|
||||||
|
|
||||||
let gameManager = new GameManager(data);
|
onMount(() => {
|
||||||
|
fetchGame(`${page.params.game}`).then((game) => {
|
||||||
|
gameManager.game = game;
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex h-full flex-col">
|
{#if gameManager.game}
|
||||||
<h1 class="ms-4 text-7xl font-bold">{gameManager.game.name}</h1>
|
<div class="flex h-full flex-col">
|
||||||
{#if gameManager.state === GameState.INIT}
|
<h1 class="ms-4 text-7xl font-bold">{gameManager.game.name}</h1>
|
||||||
<div class="p-4">
|
{#if gameManager.state === GameState.INIT}
|
||||||
<div class="flex items-center">
|
<div class="p-4">
|
||||||
<h2 class="grow pb-4 text-5xl">Spieler</h2>
|
<div class="flex items-center">
|
||||||
<button class="btn me-4" onclick={() => gameManager.load()}>Load SaveGame</button>
|
<h2 class="grow pb-4 text-5xl">Spieler</h2>
|
||||||
<button
|
<button class="btn me-4" onclick={() => gameManager.load()}
|
||||||
class="btn"
|
>Load SaveGame</button
|
||||||
disabled={!startDisabled}
|
>
|
||||||
onclick={() => gameManager.startGame()}>Start</button
|
<button
|
||||||
|
class="btn"
|
||||||
|
disabled={!startDisabled}
|
||||||
|
onclick={() => gameManager.startGame()}>Start</button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col space-y-2 pb-4">
|
||||||
|
{#each gameManager.players as player, i}
|
||||||
|
<div class="flex items-center">
|
||||||
|
<input class="inputField grow" type="text" bind:value={player.name} />
|
||||||
|
<button class="btn" onclick={() => gameManager.removePlayer(i)}
|
||||||
|
>Löschen</button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
<button class="btn" onclick={() => gameManager.addPlayer()}
|
||||||
|
>Spieler hinzufügen</button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col space-y-2 pb-4">
|
{:else}
|
||||||
{#each gameManager.players as player, i}
|
<div class="flex grow">
|
||||||
<div class="flex items-center">
|
<Scoreboard
|
||||||
<input class="inputField grow" type="text" bind:value={player.name} />
|
players={gameManager.players}
|
||||||
<button class="btn" onclick={() => gameManager.removePlayer(i)}
|
currentPlayer={gameManager.currentPlayerToName()}
|
||||||
>Löschen</button
|
editable={true}
|
||||||
>
|
onReload={() => gameManager.sendPlayers()}
|
||||||
</div>
|
/>
|
||||||
{/each}
|
{#if gameManager.state === GameState.SHOW_QUESTION}
|
||||||
</div>
|
<div class="flex grow flex-col">
|
||||||
<button class="btn" onclick={() => gameManager.addPlayer()}>Spieler hinzufügen</button>
|
<div class="m-4 flex justify-between text-4xl">
|
||||||
</div>
|
<div>{gameManager.currentCategory?.name}</div>
|
||||||
{:else}
|
<div>
|
||||||
<div class="flex grow">
|
{gameManager.currentQuestion?.points} Punkte
|
||||||
<Scoreboard
|
</div>
|
||||||
players={gameManager.players}
|
</div>
|
||||||
currentPlayer={gameManager.currentPlayerToName()}
|
<div class="flex grow ps-4 pe-4">
|
||||||
editable={true}
|
{#if gameManager.currentQuestion === undefined}
|
||||||
onReload={() => gameManager.sendPlayers()}
|
<p>Question is undefined</p>
|
||||||
/>
|
{:else if isSimpleQuestion(gameManager.currentQuestion)}
|
||||||
{#if gameManager.state === GameState.SHOW_QUESTION}
|
<SimpleQuestionComponent
|
||||||
<div class="flex grow flex-col">
|
question={gameManager.currentQuestion}
|
||||||
<div class="m-4 flex justify-between text-4xl">
|
showAnswer={true}
|
||||||
<div>{gameManager.category.name}</div>
|
showQuestion={true}
|
||||||
<div>
|
/>
|
||||||
{gameManager.question.points} Punkte
|
{:else if isMultipleChoiceQuestion(gameManager.currentQuestion)}
|
||||||
|
<MultipleChoiceQuestionComponent
|
||||||
|
question={gameManager.currentQuestion}
|
||||||
|
showAnswer={true}
|
||||||
|
showQuestion={true}
|
||||||
|
/>
|
||||||
|
{:else if isImageQuestion(gameManager.currentQuestion)}
|
||||||
|
<ImageQuestionComponent
|
||||||
|
question={gameManager.currentQuestion}
|
||||||
|
showAnswer={true}
|
||||||
|
showQuestion={true}
|
||||||
|
isBuzzed={false}
|
||||||
|
isLegacy={false}
|
||||||
|
/>
|
||||||
|
{:else if isImageMultipleChoiceQuestion(gameManager.currentQuestion)}
|
||||||
|
<ImageMultipleChoiceQuestionComponent
|
||||||
|
question={gameManager.currentQuestion}
|
||||||
|
showAnswer={true}
|
||||||
|
showQuestion={true}
|
||||||
|
isBuzzed={false}
|
||||||
|
isLegacy={false}
|
||||||
|
/>
|
||||||
|
{:else if isAudioQuestion(gameManager.currentQuestion)}
|
||||||
|
<AudioQuestionComponent
|
||||||
|
question={gameManager.currentQuestion}
|
||||||
|
showAnswer={true}
|
||||||
|
showPlayer={true}
|
||||||
|
showQuestion={true}
|
||||||
|
isLegacy={false}
|
||||||
|
/>
|
||||||
|
{:else if isAudioMultipleChoiceQuestion(gameManager.currentQuestion)}
|
||||||
|
<AudioMultipleChoiceQuestionComponent
|
||||||
|
question={gameManager.currentQuestion}
|
||||||
|
showAnswer={true}
|
||||||
|
showPlayer={true}
|
||||||
|
showQuestion={true}
|
||||||
|
isLegacy={false}
|
||||||
|
/>
|
||||||
|
{:else}
|
||||||
|
<p>Type of question unknown</p>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="m-4 flex flex-wrap items-center gap-4">
|
||||||
|
<button class="btn" onclick={() => gameManager.goBack()}>Zurück</button>
|
||||||
|
{#if gameManager.questionIsShowing}
|
||||||
|
<button class="btn" onclick={() => gameManager.hideQuestion()}
|
||||||
|
>Frage verstecken</button
|
||||||
|
>
|
||||||
|
{:else}
|
||||||
|
<button class="btn" onclick={() => gameManager.showQuestion()}
|
||||||
|
>Frage aufdecken</button
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
|
{#if gameManager.answerIsShowing}
|
||||||
|
<button class="btn" onclick={() => gameManager.hideAnswer()}
|
||||||
|
>Antwort verstecken</button
|
||||||
|
>
|
||||||
|
{:else}
|
||||||
|
<button class="btn" onclick={() => gameManager.showAnswer()}
|
||||||
|
>Antwort aufdecken</button
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
|
{#if gameManager.isBuzzed}
|
||||||
|
<button class="btn" onclick={() => gameManager.buzzerReleased()}
|
||||||
|
>Entbuzzern</button
|
||||||
|
>
|
||||||
|
{:else}
|
||||||
|
<button class="btn" onclick={() => gameManager.buzzerPressed()}
|
||||||
|
>Buzzern</button
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
|
{#each gameManager.players as player}
|
||||||
|
<PlusMinusButton
|
||||||
|
label={player.name}
|
||||||
|
plus={() => gameManager.plus(player)}
|
||||||
|
minus={() => gameManager.minus(player)}
|
||||||
|
showPlus={gameManager.answerIsShowing}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
<div class="grow"></div>
|
||||||
|
{#if gameManager.answerIsShowing}
|
||||||
|
<button class="btn" onclick={() => gameManager.finishQuestion()}
|
||||||
|
>Abschließen</button
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex grow ps-4 pe-4">
|
{:else if gameManager.state === GameState.END}
|
||||||
{#if gameManager.question === undefined}
|
<div class="flex grow items-center justify-center text-7xl">
|
||||||
<p>Question is undefined</p>
|
<div>ENDE</div>
|
||||||
{:else if isSimpleQuestion(gameManager.question)}
|
|
||||||
<SimpleQuestionComponent
|
|
||||||
question={gameManager.question}
|
|
||||||
showAnswer={true}
|
|
||||||
showQuestion={true}
|
|
||||||
/>
|
|
||||||
{:else if isMultipleChoiceQuestion(gameManager.question)}
|
|
||||||
<MultipleChoiceQuestionComponent
|
|
||||||
question={gameManager.question}
|
|
||||||
showAnswer={true}
|
|
||||||
showQuestion={true}
|
|
||||||
/>
|
|
||||||
{:else if isImageQuestion(gameManager.question)}
|
|
||||||
<ImageQuestionComponent
|
|
||||||
question={gameManager.question}
|
|
||||||
showAnswer={true}
|
|
||||||
showQuestion={true}
|
|
||||||
isBuzzed={false}
|
|
||||||
/>
|
|
||||||
{:else if isImageMultipleChoiceQuestion(gameManager.question)}
|
|
||||||
<ImageMultipleChoiceQuestionComponent
|
|
||||||
question={gameManager.question}
|
|
||||||
showAnswer={true}
|
|
||||||
showQuestion={true}
|
|
||||||
isBuzzed={false}
|
|
||||||
/>
|
|
||||||
{:else if isAudioQuestion(gameManager.question)}
|
|
||||||
<AudioQuestionComponent
|
|
||||||
question={gameManager.question}
|
|
||||||
showAnswer={true}
|
|
||||||
showPlayer={true}
|
|
||||||
showQuestion={true}
|
|
||||||
/>
|
|
||||||
{:else if isAudioMultipleChoiceQuestion(gameManager.question)}
|
|
||||||
<AudioMultipleChoiceQuestionComponent
|
|
||||||
question={gameManager.question}
|
|
||||||
showAnswer={true}
|
|
||||||
showPlayer={true}
|
|
||||||
showQuestion={true}
|
|
||||||
/>
|
|
||||||
{:else}
|
|
||||||
<p>Type of question unknown</p>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="m-4 flex flex-wrap items-center gap-4">
|
{:else}
|
||||||
<button class="btn" onclick={() => gameManager.goBack()}>Zurück</button>
|
<div class="grow ps-4 pe-4">
|
||||||
{#if gameManager.questionIsShowing}
|
<Wall
|
||||||
<button class="btn" onclick={() => gameManager.hideQuestion()}
|
wall={gameManager.currentWall}
|
||||||
>Frage verstecken</button
|
onclickIds={(cat, que) => gameManager.tileClicked(cat, que)}
|
||||||
>
|
visited={gameManager.visitedQuestions}
|
||||||
{:else}
|
/>
|
||||||
<button class="btn" onclick={() => gameManager.showQuestion()}
|
|
||||||
>Frage aufdecken</button
|
|
||||||
>
|
|
||||||
{/if}
|
|
||||||
{#if gameManager.answerIsShowing}
|
|
||||||
<button class="btn" onclick={() => gameManager.hideAnswer()}
|
|
||||||
>Antwort verstecken</button
|
|
||||||
>
|
|
||||||
{:else}
|
|
||||||
<button class="btn" onclick={() => gameManager.showAnswer()}
|
|
||||||
>Antwort aufdecken</button
|
|
||||||
>
|
|
||||||
{/if}
|
|
||||||
{#if gameManager.isBuzzed}
|
|
||||||
<button class="btn" onclick={() => gameManager.buzzerReleased()}
|
|
||||||
>Entbuzzern</button
|
|
||||||
>
|
|
||||||
{:else}
|
|
||||||
<button class="btn" onclick={() => gameManager.buzzerPressed()}
|
|
||||||
>Buzzern</button
|
|
||||||
>
|
|
||||||
{/if}
|
|
||||||
{#each gameManager.players as player}
|
|
||||||
<PlusMinusButton
|
|
||||||
label={player.name}
|
|
||||||
plus={() => gameManager.plus(player)}
|
|
||||||
minus={() => gameManager.minus(player)}
|
|
||||||
showPlus={gameManager.answerIsShowing}
|
|
||||||
/>
|
|
||||||
{/each}
|
|
||||||
<div class="grow"></div>
|
|
||||||
{#if gameManager.answerIsShowing}
|
|
||||||
<button class="btn" onclick={() => gameManager.finishQuestion()}
|
|
||||||
>Abschließen</button
|
|
||||||
>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
{:else if gameManager.state === GameState.END}
|
</div>
|
||||||
<div class="flex grow items-center justify-center text-7xl"><div>ENDE</div></div>
|
{/if}
|
||||||
{:else}
|
</div>
|
||||||
<div class="grow ps-4 pe-4">
|
{:else}
|
||||||
<Wall
|
Loading Game...
|
||||||
wall={gameManager.game.walls[gameManager.currentWall]}
|
{/if}
|
||||||
onclick={(cat, que) => gameManager.tileClicked(cat, que)}
|
|
||||||
visited={gameManager.visitedQuestions}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|||||||
@@ -218,8 +218,15 @@
|
|||||||
<option value="AUDIO_MULTIPLE_CHOICE">AUDIO_MULTIPLE_CHOICE</option>
|
<option value="AUDIO_MULTIPLE_CHOICE">AUDIO_MULTIPLE_CHOICE</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="ms-4 me-4">
|
<div class="ms-4 me-4">
|
||||||
<Textfield type="number" bind:value={question.points} label="Punkte"
|
<div class="flex items-center gap-2">
|
||||||
></Textfield>
|
<Textfield type="number" bind:value={question.points} label="Punkte"
|
||||||
|
></Textfield>
|
||||||
|
<Button
|
||||||
|
onclick={() => {
|
||||||
|
if (question) question.points *= -1;
|
||||||
|
}}><i class="fa-solid fa-plus-minus"></i></Button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ms-4 me-4 grow">
|
<div class="ms-4 me-4 grow">
|
||||||
{#if isSimpleQuestion(question)}
|
{#if isSimpleQuestion(question)}
|
||||||
|
|||||||
Reference in New Issue
Block a user