Game can pause output

main
Ashelyn Dawn 4 years ago
parent d3b3d1deb2
commit a12ee6e079

@ -17,6 +17,7 @@
right: 0;
left: 0;
bottom: 0;
z-index: 2;
opacity: .4;
overflow: hidden;

@ -24,7 +24,7 @@ export default function ({containerRef}) {
document.addEventListener('keydown', handleKey)
return () => document.removeEventListener('keydown', handleKey)
}, [])
}, [setCurrentMenu])
return (
<div ref={containerRef} className={styles.menuBar}>

@ -47,6 +47,7 @@
background: black;
border: solid 12px black;
padding: 4px;
z-index: 1;
}
.modal::before {

@ -2,11 +2,9 @@ import React, {useLayoutEffect, useRef} from 'react'
import ReactMarkdown from 'react-markdown'
import styles from './Screen.module.css'
import Menu from '../Menu/Menu'
import useGameState from '../../hooks/useGameState'
export default function Text({promptVisible, currentInput, currentScroll}) {
export default function Text({promptVisible, messages, currentInput, currentScroll, outputPaused}) {
const outputRef = useRef()
const {messages} = useGameState()
useLayoutEffect(() => {
outputRef.current.scrollTop = currentScroll
@ -25,6 +23,11 @@ export default function Text({promptVisible, currentInput, currentScroll}) {
return null
})}
{outputPaused && (
<p className={styles.pausePrompt}>
(Press [RETURN] to continue)
</p>
)}
</div>
<div className={styles.input + (!promptVisible ? ' ' + styles.hidden : '')}>
<input readOnly tabIndex="-1" value={currentInput}/>

@ -6,17 +6,27 @@ import Menu from '../Menu/Menu'
import useGameState from '../../hooks/useGameState'
import useSharedState from '../../hooks/useSharedState'
export default function Text({promptVisible, handleCommand, showReflection}) {
import {game} from '../../engine'
export default function Text({promptVisible: promptEnabled, handleCommand, showReflection}) {
const inputRef = useRef()
const outputRef = useRef()
const textRef = useRef()
const menuRef = useRef()
const {messages} = useGameState()
const [currentMenu] = useSharedState('currentMenu')
const [_, updateArbitrary] = useState(0) // eslint-disable-line no-unused-vars
const forceRender = () => updateArbitrary(arbitrary => arbitrary + 1)
const [currentInput, setCurrentInput] = useState('')
const [currentScroll, setCurrentScroll] = useState(0)
const currentPause = messages.findIndex(message => (message.type === 'pause' && message.resolved === false))
const outputPaused = currentPause > -1
let printedMessages = !outputPaused ? messages : messages.slice(0, currentPause)
const promptVisible = promptEnabled && !outputPaused
async function onSubmit(ev) {
if(ev) ev.preventDefault()
@ -62,12 +72,30 @@ export default function Text({promptVisible, handleCommand, showReflection}) {
inputRef.current.focus()
}, [currentMenu])
// Unpause output on space or return
useEffect(() => {
if(!outputPaused) return;
function handleKey(ev) {
if(ev.key !== ' ' && ev.key !== 'Enter') return;
ev.preventDefault()
console.log('Unpausing')
game.getState().messages[currentPause].resolved = true
game.saveDraft()
forceRender()
}
document.addEventListener('keydown', handleKey)
return () => document.removeEventListener('keydown', handleKey)
}, [currentPause, outputPaused, messages])
return (
<>
<div ref={textRef} className={styles.playArea}>
<Menu containerRef={menuRef}/>
<div ref={outputRef} onScroll={() => setCurrentScroll(outputRef.current?.scrollTop)} className={styles.output + (currentMenu !== null ? ' ' + styles.noMouse : '')}>
{messages.map((message, i) => {
{printedMessages.map((message, i) => {
if(message.type === 'message')
return <ReactMarkdown key={i}>{message.message}</ReactMarkdown>
@ -76,12 +104,17 @@ export default function Text({promptVisible, handleCommand, showReflection}) {
return null
})}
{outputPaused && (
<p className={styles.pausePrompt}>
(Press [RETURN] to continue)
</p>
)}
</div>
<form style={{pointerEvents: currentMenu ? 'none' : 'initial'}} className={styles.input + (!promptVisible ? ' ' + styles.hidden : '')} onSubmit={onSubmit}>
<form style={{pointerEvents: currentMenu ? 'none' : 'initial'}} className={styles.input + (!promptVisible ? ' ' + styles.hidden : '')} onSubmit={onSubmit}>
<input autoFocus ref={inputRef} onChange={ev => setCurrentInput(ev.target.value)} id="gameInput"/>
</form>
</div>
{showReflection && <Reflection promptVisible={promptVisible} messages={messages} currentInput={currentInput} currentScroll={currentScroll}/>}
{showReflection && <Reflection outputPaused={outputPaused} promptVisible={promptVisible} messages={printedMessages} currentInput={currentInput} currentScroll={currentScroll}/>}
</>
)
}

@ -18,6 +18,7 @@
opacity: .2;
filter: blur(2px);
overflow: hidden;
z-index: 2;
}
.output {
@ -76,3 +77,8 @@
.output.noMouse {
pointer-events: none;
}
.pausePrompt {
text-align: center;
opacity: .6;
}

@ -1,7 +1,7 @@
import {enableMapSet, createDraft, finishDraft, Draft} from 'immer'
import GameState, { GameObject, Room, Door, Item, ObjectType, ObjectID, Direction } from './types/GameState'
import ParsedCommand, { ValidCommandDetails, InvalidCommandDetails } from './types/ParsedCommand'
import { GameEventMessage, GameEventCommand } from './types/GameEvent'
import { GameEventMessage, GameEventCommand, GameEventPause } from './types/GameEvent'
enableMapSet()
@ -57,6 +57,10 @@ export default class Game {
state.messages.push(new GameEventMessage(message))
}
pause() {
this.getState().messages.push(new GameEventPause())
}
filterValidCommands(commands: ParsedCommand[]) : CommandValidateResult {
let validCommands : ValidCommandDetails[] = []
let invalidCommands : InvalidCommandDetails[] = []

@ -1,6 +1,7 @@
export enum GameEventType {
Message = 'message',
Command = 'command'
Command = 'command',
Pause = 'pause'
}
export default class GameEvent {
@ -28,3 +29,12 @@ export class GameEventCommand extends GameEvent {
this.command = command
}
}
export class GameEventPause extends GameEvent {
readonly resolved : boolean
constructor() {
super(GameEventType.Pause)
this.resolved = false
}
}

@ -201,6 +201,7 @@ html.noeffects {
right: 0;
overflow: hidden;
pointer-events: none;
z-index:3;
}
.scan:before{

@ -24,6 +24,14 @@ game.addItem('Block', 'A boring wooden block', 'commons')
game.saveDraft()
// Print description on game start
rules.onGameStart(() => {
game.say(`Come, join the navy they said.`)
game.pause()
game.say(`It'll be fun they said.`)
game.pause()
})
renderer.start(document.getElementById('root'))

Loading…
Cancel
Save