Lemonade Stand: browser recreation of the Atari 8-bit BASIC game
Faithful day loop - weather report, cost of lemonade rising over the summer, glasses/signs/price decisions, thunderstorms, heat waves and street crews - with the $$ LEMONSVILLE DAILY FINANCIAL REPORT $$ laid out the way it printed. The simulation is kept out of React so a season can be run headlessly: a careful player compounds $2.00 into roughly $22 over twelve days, while an all-in player goes broke about seven times in ten. Weather scenes are pixel rectangles in SVG and the music is a small chiptune engine on the Web Audio API, so there are no binary assets. The screen is locked to a 4:3 tube and never scrolls.
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import { useState } from 'react'
|
||||
import { MAX_PLAYERS } from '../game/constants'
|
||||
import { Btn, Line } from './Crt'
|
||||
|
||||
export function SetupScreen({
|
||||
onStart,
|
||||
onBlip,
|
||||
}: {
|
||||
onStart: (names: string[]) => void
|
||||
onBlip: () => void
|
||||
}) {
|
||||
const [count, setCount] = useState(1)
|
||||
const [names, setNames] = useState<string[]>(['', '', '', ''])
|
||||
|
||||
const setName = (i: number, v: string) =>
|
||||
setNames((prev) => prev.map((n, j) => (j === i ? v.slice(0, 12) : n)))
|
||||
|
||||
return (
|
||||
<div className="stack">
|
||||
<Line className="center inv-line">LEMONSVILLE BUSINESS LICENCE</Line>
|
||||
<Line />
|
||||
<Line>HOW MANY PEOPLE WILL PLAY?</Line>
|
||||
<div className="row">
|
||||
{Array.from({ length: MAX_PLAYERS }, (_, i) => i + 1).map((n) => (
|
||||
<Btn
|
||||
key={n}
|
||||
kind={count === n ? 'primary' : 'normal'}
|
||||
onClick={() => {
|
||||
onBlip()
|
||||
setCount(n)
|
||||
}}
|
||||
>
|
||||
{n}
|
||||
</Btn>
|
||||
))}
|
||||
</div>
|
||||
<Line />
|
||||
<Line>WHAT ARE THEIR NAMES?</Line>
|
||||
{Array.from({ length: count }, (_, i) => (
|
||||
<label className="field" key={i}>
|
||||
<span className="field-label">STAND {i + 1}</span>
|
||||
<input
|
||||
className="field-input field-input-name"
|
||||
value={names[i]}
|
||||
placeholder={`PLAYER ${i + 1}`}
|
||||
onChange={(e) => setName(i, e.target.value)}
|
||||
maxLength={12}
|
||||
/>
|
||||
</label>
|
||||
))}
|
||||
<Line />
|
||||
<Line className="dim">EVERY STAND OPENS WITH $2.00 IN THE TIN.</Line>
|
||||
<Line />
|
||||
<div className="row center">
|
||||
<Btn kind="primary" onClick={() => onStart(names.slice(0, count))}>
|
||||
OPEN FOR BUSINESS
|
||||
</Btn>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user