Map modal - need to implement rooms and add hallways to map UI

main
Ashelyn Dawn 4 years ago
parent a61237305e
commit ced467289b

@ -5,6 +5,9 @@
width: 600px;
height: 400px;
background: black;
}
.screen, .screen img {
image-rendering: pixelated;
}

@ -3,6 +3,7 @@ import styles from './Menu.module.css'
import useSharedState from '../../hooks/useSharedState'
import Inventory from '../Modals/Inventory'
import Options from '../Modals/Options'
import Map from '../Modals/Map'
export default function ({containerRef}) {
const [currentMenu, setCurrentMenu] = useSharedState('currentMenu')
@ -33,6 +34,9 @@ export default function ({containerRef}) {
if(currentMenu === 'inventory')
return <Inventory/>
if(currentMenu === 'map')
return <Map />
if(currentMenu === 'options')
return <Options/>

@ -84,7 +84,7 @@
margin-top: 1px;
padding: 8px;
height: calc(100% - 40px);
overflow-y: scroll;
overflow-y: auto;
}
.modalContent :first-child {

@ -0,0 +1,85 @@
import React from 'react'
import ReactMarkdown from 'react-markdown'
import useGameState from '../../hooks/useGameState'
import map from './map.png'
import {ReactComponent as PlayerIcon} from './mapPerson.svg'
import styles from './Map.module.css'
import useSharedState from '../../hooks/useSharedState'
export default function Map() {
const gameState = useGameState()
const playerLocation = gameState?.player?.location
const isOnLower = ['engine', 'docking', 'mainframe', 'stairlower'].includes(playerLocation)
const [currentFloor, setFloor] = useSharedState('mapFloor', isOnLower ? 'lower' : 'upper')
const [roomName, setRoom] = useSharedState('mapRoom')
const currentRoom = (roomName && gameState.rooms.get(roomName)) || null
return (
<div className={styles.map}>
<img alt="" src={map}/>
<Floor name="upper" currentSelected={currentFloor} setCurrentFloor={setFloor}>
<Room name="bridge" top={15} left={25} width={20} height={15} currentSelected={roomName} setSelected={setRoom}/>
<Room name="commons" top={35} left={25} width={20} height={30} currentSelected={roomName} setSelected={setRoom}/>
<Room name="cabin" top={35} left={50} width={10} height={20} currentSelected={roomName} setSelected={setRoom}/>
<Room name="bathroom" top={60} left={50} width={10} height={10} currentSelected={roomName} setSelected={setRoom}/>
<Room name="medbay" top={35} left={10} width={10} height={20} currentSelected={roomName} setSelected={setRoom}/>
<Room name="stairupper" top={60} left={10} width={10} height={10} currentSelected={roomName} setSelected={setRoom}/>
</Floor>
<Floor name="lower" currentSelected={currentFloor} setCurrentFloor={setFloor}>
<Room name="engine" top={35} left={25} width={20} height={30} currentSelected={roomName} setSelected={setRoom}/>
<Room name="docking" top={35} left={50} width={10} height={35} currentSelected={roomName} setSelected={setRoom}/>
<Room name="mainframe" top={35} left={10} width={10} height={20} currentSelected={roomName} setSelected={setRoom}/>
<Room name="stairlower" top={60} left={10} width={10} height={10} currentSelected={roomName} setSelected={setRoom}/>
</Floor>
<div className={styles.floorSelector}>
<button className={currentFloor === 'upper' && styles.selectedFloor} onClick={()=>setFloor('upper')}>Upper</button>
<button className={currentFloor === 'lower' && styles.selectedFloor} onClick={()=>setFloor('lower')}>Lower</button>
</div>
<div className={styles.description}>
{currentRoom ? (
<>
<h3>{currentRoom.printableName}</h3>
<ReactMarkdown>{currentRoom.description}</ReactMarkdown>
</>
) : (
<h3 style={{marginTop: '45%', textAlign: 'center'}}>Select a Room</h3>
)}
</div>
</div>
)
}
function Floor({name, currentSelected, children}) {
// Do not render if not selected
if(name !== currentSelected)
return null;
return (
<div className={styles.rooms}>
{children}
</div>
)
}
function Room({name, top, left, width, height, setSelected, currentSelected}) {
const gameState = useGameState()
const current = gameState?.player?.location === name
return (
<div
onClick={() => setSelected(name)}
className={styles.room + (currentSelected === name ? ' ' + styles.selectedRoom : '')}
style={{top, left, width, height}}
>
{current && <PlayerIcon/>}
</div>
)
}

@ -0,0 +1,69 @@
.map {
flex-direction: row;
align-items: center;
height: 100%;
}
.map img {
position: absolute;
top: 64px;
left: 32px;
height: 150px;
}
.rooms {
position: absolute;
top: 70px;
left: 85px;
width: 70px;
height: 105px;
display: block;
}
.room {
position: absolute;
border: solid 1px white;
background: rgba(0,0,0,.6);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.room svg {
display: block;
width: 10px;
height: 10px;
}
.selectedRoom {
background: rgba(255,255,255,.2);
}
.floorSelector {
position: absolute;
top: 200px;
left: 58px
}
.floorSelector button {
display: inline-block;
margin: 10px;
background: transparent;
color: white;
border: solid 1px white;
padding: 4px;
cursor: pointer;
font-size: 12px;
}
.floorSelector .selectedFloor {
color: black;
background: white;
}
.description {
margin-left: 240px;
max-height: 100%;
padding: 10px 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="18px" height="18px"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>

After

Width:  |  Height:  |  Size: 264 B

@ -10,6 +10,8 @@ const updateSharedState = (key, state) => {
}
export default function useSharedState(key, initial) {
if(!key) throw new Error('Cannot call useSharedState without a key')
const [localState, setLocalState] = useState(sharedState[key] || initial)
useEffect(() => {

@ -76,7 +76,20 @@ game.addItem({
location: 'entry'
})
game.getState().player.location = 'entry'
game.addRoom({
type: ObjectType.Room,
printableName: 'Crew Cabin',
name: 'cabin',
aliases: [],
neighbors: new Map(),
description: `
A dark and dingy room with a single bunk bed along the starboard side.
The washroom is to the aft, with the common room to port.
`
})
game.getState().player.location = 'cabin'
game.saveDraft()

Loading…
Cancel
Save