Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* This game challenges players to click and hold a button for as long as possible.
* It uses React for the UI, SQLite for storing high scores, and includes a leaderboard.
* The game features vibrant colors and a pre-game explanation.
*/
/** @jsxImportSource https://esm.sh/react */
import React, { useState, useEffect, useRef } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
function App() {
const [showLeaderboard, setShowLeaderboard] = useState(false);
const toggleLeaderboard = () => {
setShowLeaderboard(!showLeaderboard);
};
const [gameState, setGameState] = useState('intro'); // 'intro', 'name', 'game', 'end'
const [playerName, setPlayerName] = useState('');
const [timer, setTimer] = useState(0);
const [isHolding, setIsHolding] = useState(false);
const [leaderboard, setLeaderboard] = useState([]);
const intervalRef = useRef(null);
useEffect(() => {
fetchLeaderboard();
}, []);
useEffect(() => {
if (isHolding) {
intervalRef.current = setInterval(() => {
setTimer(prev => prev + 0.1);
}, 100);
} else if (intervalRef.current) {
clearInterval(intervalRef.current);
}
return () => {
if (intervalRef.current) clearInterval(intervalRef.current);
};
}, [isHolding]);
const fetchLeaderboard = async () => {
const response = await fetch('/leaderboard');
const data = await response.json();
setLeaderboard(data);
};
const startHolding = () => setIsHolding(true);
const stopHolding = async () => {
setIsHolding(false);
setGameState('end');
await submitScore();
await fetchLeaderboard();
};
const submitScore = async () => {
await fetch('/submit-score', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: playerName, score: timer.toFixed(1) })
});
};
const restartGame = () => {
setTimer(0);
setGameState('name');
};
return (
<div className="page-container">
{gameState === 'intro' && (
<div className="intro">
<h1>🕰️ Hold The Clock 🕰️</h1>
<div className="intro-text">
<p>How long can you hold the button? Test your endurance and compete with others!</p>
<p>Click and hold the button for as long as you can. The longer you hold, the higher your score!</p>
</div>
<button onClick={() => setGameState('name')}>Start</button>
</div>
)}
{gameState === 'name' && (
<div className="name-input">
<h2>Enter Your Name</h2>
<input
type="text"
value={playerName}
onChange={(e) => setPlayerName(e.target.value)}
placeholder="Your Name"
/>
<button onClick={() => setGameState('game')}>Let's Play!</button>
</div>
)}
{gameState === 'game' && (
<div className="game">
<h2>Hold The Button!</h2>
<div className="timer">{timer.toFixed(1)}s</div>
<button
className={`hold-button ${isHolding ? 'holding' : ''}`}
onMouseDown={startHolding}
onMouseUp={stopHolding}
onTouchStart={startHolding}
onTouchEnd={stopHolding}
ankitkr0-successivevioletgrouse.web.val.run
September 10, 2024