From 404a0807facf505bcdfe026cb99948e7d7f72cc8 Mon Sep 17 00:00:00 2001 From: Jason Reed Date: Sun, 15 Oct 2023 10:05:48 -0400 Subject: [PATCH] Add some stubs for instructions (##36) --- src/app.tsx | 57 ++++++++++++++++++++++++++++++++-------------- src/core/reduce.ts | 29 +++++++++++------------ src/core/state.ts | 7 ++++-- 3 files changed, 60 insertions(+), 33 deletions(-) diff --git a/src/app.tsx b/src/app.tsx index 79eb2b6..029a97e 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -24,26 +24,49 @@ type CanvasProps = { }; +function Instructions(props: { dispatch: Dispatch }): JSX.Element { + const { dispatch } = props; + function mouseDownListener(e: MouseEvent) { + dispatch({ t: 'setSceneState', state: { t: 'menu' } }); + e.preventDefault(); + e.stopPropagation(); + } + + useEffect(() => { + document.addEventListener('mousedown', mouseDownListener); + return () => { + document.removeEventListener('mousedown', mouseDownListener); + } + }); + return Instructions go here; +} + export function App(props: {}): JSX.Element { const [state, dispatch] = useEffectfulReducer(mkSceneState(), reduce, doEffect); - if (state.t == 'menu') { - const style: React.CSSProperties = { - backgroundColor: 'white', - padding: 15, - border: '1px solid gray', - borderRadius: 10, - fontFamily: 'sans-serif', - fontWeight: 'bold', - cursor: 'pointer', - }; - return
- Wordlike

- -

; - } - else { - return ; + switch (state.t) { + case 'menu': { + const style: React.CSSProperties = { + backgroundColor: 'white', + padding: 15, + border: '1px solid gray', + borderRadius: 10, + fontFamily: 'sans-serif', + fontWeight: 'bold', + cursor: 'pointer', + }; + return
+ Wordlike

+ +

+ +

; + } + case 'game': + return ; + case 'instructions': { + return ; + } } } diff --git a/src/core/reduce.ts b/src/core/reduce.ts index 1291e73..bc6be3f 100644 --- a/src/core/reduce.ts +++ b/src/core/reduce.ts @@ -6,7 +6,7 @@ import { compose, composen, inverse, scale, translate } from '../util/se2'; import { Point } from '../util/types'; import { vequal, vm, vscale } from '../util/vutil'; import { getPanicFraction } from './clock'; -import { Action, Effect, GameState, SceneState, mkGameSceneState, mkGameState } from './state'; +import { Action, Effect, GameAction, GameState, SceneState, mkGameSceneState, mkGameState } from './state'; import { checkValid, drawOfState, is_occupied, killTileOfState } from './state-helpers'; function resolveDrag(state: GameState): GameState { @@ -166,7 +166,7 @@ export function reduceMouseDown(state: GameState, wp: WidgetPoint, button: numbe } } -export function reduceGameAction(state: GameState, action: Action): effectful.Result { +export function reduceGameAction(state: GameState, action: GameAction): effectful.Result { function gs(state: GameState): effectful.Result { return { state: { t: 'game', gameState: state, revision: 0 }, effects: [] }; } @@ -200,7 +200,6 @@ export function reduceGameAction(state: GameState, action: Action): effectful.Re case 'mouseMove': return gs(produce(state, s => { s.mouseState.p = action.p; })); - case 'resize': return gs(state); // XXX maybe stash viewdata this in state somewhere? case 'repaint': if (state.panic !== undefined) { if (getPanicFraction(state.panic) > 1) { @@ -211,22 +210,24 @@ export function reduceGameAction(state: GameState, action: Action): effectful.Re else { return gs(state); } - case 'newGame': - throw new Error('lifecycle error'); } } export function reduce(scState: SceneState, action: Action): effectful.Result { - switch (scState.t) { - case 'game': - return reduceGameAction(scState.gameState, action); - case 'menu': - switch (action.t) { - case 'newGame': - return { state: mkGameSceneState(Date.now()), effects: [] }; - default: - return { state: scState, effects: [] }; + switch (action.t) { + case 'resize': return { state: scState, effects: [] }; // XXX maybe stash viewdata this in state somewhere? + case 'newGame': + return { state: mkGameSceneState(Date.now()), effects: [] }; + case 'setSceneState': + return { state: action.state, effects: [] }; + default: + if (scState.t == 'game') { + return reduceGameAction(scState.gameState, action); + } + else { + return { state: scState, effects: [] }; } } + } diff --git a/src/core/state.ts b/src/core/state.ts index 32b504b..a9d82e7 100644 --- a/src/core/state.ts +++ b/src/core/state.ts @@ -22,12 +22,13 @@ export type UiAction = | { t: 'mouseUp', p: Point } | { t: 'mouseMove', p: Point } | { t: 'wheel', p: Point, delta: number } + | { t: 'repaint' } ; export type Action = | { t: 'resize', vd: ViewData } - | { t: 'repaint' } | { t: 'newGame' } + | { t: 'setSceneState', state: SceneState } | GameAction ; @@ -53,7 +54,9 @@ export type SceneState = // It's updated in reduce.ts. revision: number, } - | { t: 'menu' }; + | { t: 'menu' } + | { t: 'instructions' } + ; export type State = { sceneState: SceneState,