#app
View Compiled
* {
box-sizing: border-box;
}
:root {
--control: #e69119;
--color: #fff;
}
button {
background: var(--control);
color: var(--color);
padding: 1rem 2rem;
border-radius: 1rem;
border: 4px solid var(--color);
font-family: 'Fredoka One', cursive;
font-size: 1.2rem;
}
body {
background: linear-gradient(#d1e9fa 0 40%, #86c270 40%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
font-family: 'Fredoka One', cursive;
}
import React, { Fragment, useEffect, useRef, useState } from 'https://cdn.skypack.dev/react'
import { render } from 'https://cdn.skypack.dev/react-dom'
const Moles = ({ children }) => <div>{children}</div>
const Mole = () => <button>Mole</button>
const Score = () => <div>Score: 0</div>
const TIME_LIMIT = 30000
const Timer = ({ time, interval = 1000, onEnd }) => {
const [internalTime, setInternalTime] = useState(time)
const timerRef = useRef(time)
const timeRef = useRef(time)
useEffect(() => {
timerRef.current = setInterval(
() => setInternalTime((timeRef.current -= interval)),
interval
)
return () => {
clearInterval(timerRef.current)
}
}, [interval])
return <div>{`Time: ${internalTime / 1000}s`}</div>
}
const Game = () => {
const [playing, setPlaying] = useState(false)
return (
<Fragment>
{!playing && <h1>Whac a Mole</h1>}
<button onClick={() => setPlaying(!playing)}>{playing ? 'Stop' : 'Start'}</button>
{playing &&
<Fragment>
<Score/>
<Timer
time={TIME_LIMIT}
onEnd={() => setPlaying(false)}
/>
<Moles>
<Mole/>
<Mole/>
<Mole/>
<Mole/>
<Mole/>
</Moles>
</Fragment>
}
</Fragment>
)
}
render(<Game/>, document.getElementById('app'))
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.