AGHHH, now finaly the actual playing of the game works! now time to add a leader board!
This commit is contained in:
parent
f83f50d9b2
commit
9ac813c699
11 changed files with 381 additions and 62 deletions
|
@ -3,4 +3,4 @@ import { createClient } from '@supabase/supabase-js';
|
|||
export const supabase = createClient(
|
||||
import.meta.env.VITE_SUPABASE_URL,
|
||||
import.meta.env.VITE_SUPABASE_ANON_KEY
|
||||
);
|
||||
);
|
|
@ -1,13 +1,14 @@
|
|||
<script>
|
||||
import { supabase } from '$lib/supabase';
|
||||
import { goto } from '$app/navigation';
|
||||
let questions = [
|
||||
let questions = $state([
|
||||
{
|
||||
name: '',
|
||||
answers: ['', '', '', ''],
|
||||
correctAnswer: undefined
|
||||
correctAnswer: undefined,
|
||||
playersCompelted: 0
|
||||
}
|
||||
];
|
||||
]);
|
||||
|
||||
async function startGame() {
|
||||
if (questions.some((q) => q.name === '')) return alert('Please fill all questions');
|
||||
|
@ -22,7 +23,7 @@
|
|||
const { error } = await supabase.from('games').insert({
|
||||
gamePIN: gamePin,
|
||||
gameStatus: 'lobby',
|
||||
questions: questions,
|
||||
questions: $state.snapshot(questions),
|
||||
players: []
|
||||
});
|
||||
|
||||
|
@ -37,6 +38,43 @@
|
|||
|
||||
<div class="bg-grey-900 flex justify-center p-5">
|
||||
<div class="flex flex-col items-center justify-center gap-1 rounded-lg bg-gray-900 p-8 shadow-lg">
|
||||
<button
|
||||
onclick={() => {
|
||||
questions = [
|
||||
{
|
||||
name: 'Is hack club awesome?',
|
||||
answers: ['its ok', 'its the BEST place in the world', 'nahh its bad', 'Gu Gu Ga Ga'],
|
||||
correctAnswer: 1,
|
||||
playersCompelted: 0
|
||||
},
|
||||
{
|
||||
name: 'Who is the best programer in the world?',
|
||||
answers: ['Sundar Pichai', 'Bill Gates', 'RezHackXYZ', 'Elon musk'],
|
||||
correctAnswer: 2,
|
||||
playersCompelted: 0
|
||||
},
|
||||
{
|
||||
name: 'What was the 5/11 incident?',
|
||||
answers: [
|
||||
'mass pings of @/birds',
|
||||
'twin towers getting blasted by planes',
|
||||
'the opening ceremony of the store of 7/11 on the 5/11 date',
|
||||
'the opening ceremony of the competitor store of 7/11'
|
||||
],
|
||||
correctAnswer: 0,
|
||||
playersCompelted: 0
|
||||
}
|
||||
];
|
||||
}}
|
||||
class="-mt-5 mb-3 flex h-fit cursor-pointer items-center justify-center rounded-xl bg-green-700 p-2 transition-all hover:scale-110 hover:-rotate-10"
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height="24px"
|
||||
viewBox="0 -960 960 960"
|
||||
width="24px"
|
||||
fill="#FFFFFF"><path d="M440-440H200v-80h240v-240h80v240h240v80H520v240h-80v-240Z" /></svg
|
||||
>Use demo questions</button
|
||||
>
|
||||
{#each questions as question, i}
|
||||
<div class="flex items-center gap-3">
|
||||
<div
|
||||
|
@ -77,10 +115,16 @@
|
|||
<div class="flex flex-col gap-2">
|
||||
{#each question.answers as answer, i2}
|
||||
<div class="flex items-center gap-2">
|
||||
<input type="radio" value={i2} name={i} bind:group={question.correctAnswer} /><input
|
||||
<input
|
||||
type="radio"
|
||||
value={i2}
|
||||
name={i}
|
||||
bind:group={question.correctAnswer}
|
||||
class="input"
|
||||
/><input
|
||||
placeholder="Option {i2 + 1}"
|
||||
bind:value={question.answers[i2]}
|
||||
class="rounded-lg bg-gray-800 p-1 text-center text-white"
|
||||
class="w-[500px] rounded-lg bg-gray-800 p-1 text-center text-white"
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
|
@ -94,7 +138,8 @@
|
|||
questions.push({
|
||||
name: '',
|
||||
answers: ['', '', '', ''],
|
||||
correctAnswer: undefined
|
||||
correctAnswer: undefined,
|
||||
playersCompelted: 0
|
||||
});
|
||||
}}
|
||||
class="flex h-fit cursor-pointer items-center justify-center rounded-xl bg-green-700 p-2 transition-all hover:scale-110 hover:-rotate-10"
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
import { onMount } from 'svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { supabase } from '$lib/supabase';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
export let data;
|
||||
const gamePin = data.gamePin;
|
||||
const name = $page.state?.name;
|
||||
|
||||
let players = [];
|
||||
|
||||
|
@ -63,11 +63,14 @@
|
|||
</div>
|
||||
<button
|
||||
class="mt-5 cursor-pointer rounded-2xl bg-green-700 p-2 text-4xl transition-all hover:scale-110 hover:-rotate-10"
|
||||
on:click={() => {
|
||||
on:click={async () => {
|
||||
if (players.length > 0) {
|
||||
if (confirm('Are you sure you want to start the game?')) {
|
||||
// Logic to start the game
|
||||
alert('Game started!'); // Replace with actual game start logic
|
||||
await supabase
|
||||
.from('games')
|
||||
.update({ gameStatus: 'started' })
|
||||
.eq('gamePIN', Number(data.gamePin));
|
||||
goto(`/hostgame/${gamePin}`);
|
||||
}
|
||||
} else {
|
||||
alert('You need at least one player to start the game.');
|
||||
|
|
6
src/routes/hostgame/[gamePin]/+page.js
Normal file
6
src/routes/hostgame/[gamePin]/+page.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
// Example of what your +page.js or +page.server.js might need
|
||||
export function load({ params }) {
|
||||
return {
|
||||
gamePin: params.gamePin
|
||||
};
|
||||
}
|
100
src/routes/hostgame/[gamePin]/+page.svelte
Normal file
100
src/routes/hostgame/[gamePin]/+page.svelte
Normal file
|
@ -0,0 +1,100 @@
|
|||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { supabase } from '$lib/supabase';
|
||||
|
||||
export let data;
|
||||
const gamePin = data.gamePin;
|
||||
|
||||
let totalQuetions = 3;
|
||||
let currentQuestion = 0;
|
||||
|
||||
let PeopleAwnseredQ = 2;
|
||||
let Totalplayers = 3;
|
||||
|
||||
let questions = [];
|
||||
|
||||
async function NewUpdate(question) {
|
||||
if (question[currentQuestion].playersCompelted == Totalplayers) {
|
||||
currentQuestion++;
|
||||
await supabase
|
||||
.from('games')
|
||||
.update({ gameStatus: `${currentQuestion}` })
|
||||
.eq('gamePIN', Number(data.gamePin));
|
||||
PeopleAwnseredQ = 0;
|
||||
} else {
|
||||
PeopleAwnseredQ = question[currentQuestion].playersCompelted;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
const channel = supabase
|
||||
.channel(`game-${gamePin}`)
|
||||
.on(
|
||||
'postgres_changes',
|
||||
{
|
||||
event: 'UPDATE',
|
||||
schema: 'public',
|
||||
table: 'games',
|
||||
filter: `gamePIN=eq.${gamePin}`
|
||||
},
|
||||
(payload) => {
|
||||
if (payload.new.questions != questions) {
|
||||
questions = payload.new.questions;
|
||||
currentQuestion = Number(payload.new.gameStatus);
|
||||
NewUpdate(questions);
|
||||
}
|
||||
}
|
||||
)
|
||||
.subscribe();
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('games')
|
||||
.select('players')
|
||||
.eq('gamePIN', Number(gamePin))
|
||||
.single();
|
||||
|
||||
Totalplayers = data.players.length;
|
||||
|
||||
const { data: data2, error: error2 } = await supabase
|
||||
.from('games')
|
||||
.select('questions')
|
||||
.eq('gamePIN', Number(gamePin))
|
||||
.single();
|
||||
|
||||
questions = data2.questions;
|
||||
totalQuetions = questions.length;
|
||||
|
||||
currentQuestion = 0;
|
||||
await supabase
|
||||
.from('games')
|
||||
.update({ gameStatus: currentQuestion.toString() })
|
||||
.eq('gamePIN', Number(gamePin));
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="bg-grey-900 flex h-full items-center justify-center">
|
||||
<div
|
||||
class="flex max-w-[700px] flex-col items-center justify-center gap-1 rounded-lg bg-gray-900 p-8 shadow-lg"
|
||||
>
|
||||
<h1 class="m-[0] text-7xl">HOSTING</h1>
|
||||
<div class="mt-1 mb-3 flex w-full flex-col rounded-2xl border-2 border-green-400 p-2">
|
||||
<h3>Question {currentQuestion + 1} of {totalQuetions} is beeing awnsered</h3>
|
||||
<div class="flex-1 rounded-full border-2 border-gray-600">
|
||||
<div
|
||||
class="h-4 rounded-full bg-green-600 transition-all duration-700"
|
||||
style="width: {(currentQuestion / totalQuetions) * 100}%;"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-1 mb-3 flex w-full flex-col rounded-2xl border-2 border-green-400 p-2">
|
||||
<h3>{PeopleAwnseredQ} out of {Totalplayers} have awnsered the quetion</h3>
|
||||
<div class="flex-1 rounded-full border-2 border-gray-600">
|
||||
<div
|
||||
class="h-4 rounded-full bg-green-600 transition-all duration-700"
|
||||
style="width: {(PeopleAwnseredQ / Totalplayers) * 100}%;"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -32,7 +32,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
goto('/play/' + pin, {
|
||||
goto('/play-lobby/' + pin, {
|
||||
state: {
|
||||
name
|
||||
}
|
||||
|
|
6
src/routes/play-lobby/[gamePin]/+page.js
Normal file
6
src/routes/play-lobby/[gamePin]/+page.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
// Example of what your +page.js or +page.server.js might need
|
||||
export function load({ params }) {
|
||||
return {
|
||||
gamePin: params.gamePin
|
||||
};
|
||||
}
|
112
src/routes/play-lobby/[gamePin]/+page.svelte
Normal file
112
src/routes/play-lobby/[gamePin]/+page.svelte
Normal file
|
@ -0,0 +1,112 @@
|
|||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { supabase } from '$lib/supabase';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
export let data;
|
||||
const gamePin = data.gamePin;
|
||||
const name = $page.state?.name;
|
||||
|
||||
let players = [];
|
||||
|
||||
async function addPlayer() {
|
||||
const { data: gameData, error } = await supabase
|
||||
.from('games')
|
||||
.select('players')
|
||||
.eq('gamePIN', Number(gamePin))
|
||||
.maybeSingle();
|
||||
|
||||
let updatedPlayers = gameData.players || [];
|
||||
|
||||
const alreadyExists = updatedPlayers.some((p) => p.name === name);
|
||||
if (!alreadyExists) {
|
||||
updatedPlayers.push({ name: name, score: 0 });
|
||||
|
||||
const { error: updateError } = await supabase
|
||||
.from('games')
|
||||
.update({ players: updatedPlayers })
|
||||
.eq('gamePIN', Number(gamePin));
|
||||
}
|
||||
}
|
||||
|
||||
// Subscribe to realtime changes in players
|
||||
function subscribeToPlayers() {
|
||||
const channel = supabase
|
||||
.channel(`game-${gamePin}`)
|
||||
.on(
|
||||
'postgres_changes',
|
||||
{
|
||||
event: 'UPDATE',
|
||||
schema: 'public',
|
||||
table: 'games',
|
||||
filter: `gamePIN=eq.${gamePin}`
|
||||
},
|
||||
(payload) => {
|
||||
players = payload.new.players || [];
|
||||
}
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
function subscribeToGameStatus() {
|
||||
supabase
|
||||
.channel(`status-${gamePin}`)
|
||||
.on(
|
||||
'postgres_changes',
|
||||
{
|
||||
event: 'UPDATE',
|
||||
schema: 'public',
|
||||
table: 'games',
|
||||
filter: `gamePIN=eq.${gamePin}`
|
||||
},
|
||||
(payload) => {
|
||||
if (payload.new.gameStatus === 'started') {
|
||||
goto(`/play/${gamePin}`, {
|
||||
state: {
|
||||
name
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
onMount(async () => {
|
||||
await addPlayer();
|
||||
|
||||
const { data: gameData } = await supabase
|
||||
.from('games')
|
||||
.select('players')
|
||||
.eq('gamePIN', Number(gamePin))
|
||||
.maybeSingle();
|
||||
|
||||
if (gameData?.players) {
|
||||
players = gameData.players;
|
||||
}
|
||||
|
||||
subscribeToPlayers();
|
||||
subscribeToGameStatus();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="bg-grey-900 flex h-full items-center justify-center">
|
||||
<div
|
||||
class="flex max-w-[700px] flex-col items-center justify-center gap-1 rounded-lg bg-gray-900 p-8 shadow-lg"
|
||||
>
|
||||
<h1 class="m-[0] text-9xl">PLAYING</h1>
|
||||
<h1 class="m-[0] text-7xl">Game Pin:</h1>
|
||||
<h1 class="m-[0] rounded-2xl bg-gray-700 pt-1.5 pr-2 pb-0 pl-2 font-mono text-5xl">
|
||||
{gamePin}
|
||||
</h1>
|
||||
<h1 class="m-[0] mt-10 text-6xl">Players Joined:</h1>
|
||||
<h1 class="m-[0] text-4xl text-gray-400">(Total Players: {players.length})</h1>
|
||||
<div class="mt-2 flex flex-wrap justify-center gap-2">
|
||||
{#each players as player}
|
||||
<span class="m-[0] rounded-xl bg-gray-700 pt-1 pr-2 pb-0 pl-2 font-mono text-3xl"
|
||||
>{player.name}</span
|
||||
>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,4 +1,3 @@
|
|||
// Example of what your +page.js or +page.server.js might need
|
||||
export function load({ params }) {
|
||||
return {
|
||||
gamePin: params.gamePin
|
||||
|
|
|
@ -1,36 +1,19 @@
|
|||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { supabase } from '$lib/supabase';
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
export let data;
|
||||
const gamePin = data.gamePin;
|
||||
import { page } from '$app/stores';
|
||||
const name = $page.state?.name;
|
||||
|
||||
let question = [];
|
||||
let Selected = null;
|
||||
let currentQuestion = 0;
|
||||
let isWait = true;
|
||||
let gameStatus = '';
|
||||
let players = [];
|
||||
|
||||
async function addPlayer() {
|
||||
const { data: gameData, error } = await supabase
|
||||
.from('games')
|
||||
.select('players')
|
||||
.eq('gamePIN', Number(gamePin))
|
||||
.maybeSingle();
|
||||
|
||||
let updatedPlayers = gameData.players || [];
|
||||
|
||||
const alreadyExists = updatedPlayers.some((p) => p.name === name);
|
||||
if (!alreadyExists) {
|
||||
updatedPlayers.push({ name: name, score: 0 });
|
||||
|
||||
const { error: updateError } = await supabase
|
||||
.from('games')
|
||||
.update({ players: updatedPlayers })
|
||||
.eq('gamePIN', Number(gamePin));
|
||||
}
|
||||
}
|
||||
|
||||
// Subscribe to realtime changes in players
|
||||
function subscribeToPlayers() {
|
||||
onMount(async () => {
|
||||
const channel = supabase
|
||||
.channel(`game-${gamePin}`)
|
||||
.on(
|
||||
|
@ -42,46 +25,110 @@
|
|||
filter: `gamePIN=eq.${gamePin}`
|
||||
},
|
||||
(payload) => {
|
||||
players = payload.new.players || [];
|
||||
if (payload.new.gameStatus != gameStatus) {
|
||||
gameStatus = payload.new.gameStatus;
|
||||
isWait = false;
|
||||
Selected = null;
|
||||
currentQuestion = Number(gameStatus);
|
||||
}
|
||||
}
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
await addPlayer();
|
||||
const { data, error } = await supabase
|
||||
.from('games')
|
||||
.select('questions')
|
||||
.eq('gamePIN', Number(gamePin))
|
||||
.single();
|
||||
|
||||
const { data: gameData } = await supabase
|
||||
if (!error && data) {
|
||||
question = data.questions || [];
|
||||
}
|
||||
});
|
||||
|
||||
async function SubmitAnswer() {
|
||||
isWait = true;
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('games')
|
||||
.select('players')
|
||||
.eq('gamePIN', Number(gamePin))
|
||||
.maybeSingle();
|
||||
.single();
|
||||
players = data.players;
|
||||
|
||||
if (gameData?.players) {
|
||||
players = gameData.players;
|
||||
if (question[currentQuestion].correctAnswer == Selected) {
|
||||
players.forEach((player) => {
|
||||
if (player.name == name) {
|
||||
player.score += 1;
|
||||
}
|
||||
});
|
||||
await supabase.from('games').update({ players: players }).eq('gamePIN', Number(gamePin));
|
||||
}
|
||||
|
||||
subscribeToPlayers();
|
||||
});
|
||||
const { data: data2 } = await supabase
|
||||
.from('games')
|
||||
.select('questions')
|
||||
.eq('gamePIN', Number(gamePin))
|
||||
.single();
|
||||
|
||||
question = data2.questions;
|
||||
|
||||
question[currentQuestion].playersCompelted++;
|
||||
console.log('Players Completed:', question[currentQuestion].playersCompelted);
|
||||
|
||||
await supabase.from('games').update({ questions: question }).eq('gamePIN', Number(gamePin));
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="bg-grey-900 flex h-full items-center justify-center">
|
||||
<div
|
||||
class="flex max-w-[700px] flex-col items-center justify-center gap-1 rounded-lg bg-gray-900 p-8 shadow-lg"
|
||||
>
|
||||
<h1 class="m-[0] text-9xl">PLAYING</h1>
|
||||
<h1 class="m-[0] text-7xl">Game Pin:</h1>
|
||||
<h1 class="m-[0] rounded-2xl bg-gray-700 pt-1.5 pr-2 pb-0 pl-2 font-mono text-5xl">
|
||||
{gamePin}
|
||||
</h1>
|
||||
<h1 class="m-[0] mt-10 text-6xl">Players Joined:</h1>
|
||||
<h1 class="m-[0] text-4xl text-gray-400">(Total Players: {players.length})</h1>
|
||||
<div class="mt-2 flex flex-wrap justify-center gap-2">
|
||||
{#each players as player}
|
||||
<span class="m-[0] rounded-xl bg-gray-700 pt-1 pr-2 pb-0 pl-2 font-mono text-3xl"
|
||||
>{player.name}</span
|
||||
>
|
||||
{/each}
|
||||
<div class="mb-5 flex w-full items-center justify-center gap-3">
|
||||
<h3>Question {currentQuestion + 1} of {question.length}</h3>
|
||||
<div class="flex-1 rounded-full border-2 border-gray-600">
|
||||
<div
|
||||
class="h-4 rounded-full bg-green-600 transition-all duration-700"
|
||||
style="width: {(currentQuestion / question.length) * 100}%;"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
{#if isWait != true}
|
||||
<h1 class="m-[0] text-center text-5xl">
|
||||
Q{currentQuestion + 1}. {question[currentQuestion].name}
|
||||
</h1>
|
||||
<div class="mt-5 grid grid-cols-2 gap-5 gap-x-3">
|
||||
{#each question[currentQuestion].answers as answer, index}
|
||||
<div class="flex">
|
||||
<input
|
||||
type="radio"
|
||||
id="O{index}"
|
||||
name="question"
|
||||
class="peer sr-only"
|
||||
value={index}
|
||||
bind:group={Selected}
|
||||
/>
|
||||
<label
|
||||
class="w-full cursor-pointer rounded-lg border-3 border-gray-600 bg-gray-600 pt-1 pr-2 pb-1 pl-2 text-center text-3xl transition-all peer-checked:border-blue-600 peer-checked:bg-blue-600 hover:border-blue-600"
|
||||
for="O{index}">{answer}</label
|
||||
>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{#if Selected != null}
|
||||
<button
|
||||
class="mt-4 cursor-pointer gap-0 rounded-lg bg-green-700 p-2 text-3xl transition-all hover:scale-110 hover:-rotate-10"
|
||||
onclick={SubmitAnswer}
|
||||
>submit answer
|
||||
</button>
|
||||
{:else}
|
||||
<button
|
||||
class="mt-4 cursor-pointer gap-0 rounded-lg bg-gray-700 p-2 text-3xl transition-all hover:scale-110"
|
||||
>select an answer to submit!
|
||||
</button>
|
||||
{/if}
|
||||
{:else}<h1 class="m-[0] text-center text-5xl">
|
||||
Please wait for everyone else to answer the question.
|
||||
</h1>{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue