v0.1.0: 仙途家族志 · Chronicle of the Immortal Clan
家族模拟器首版:修仙/经营/战斗/外交/叙事全套系统 - Electron + React + TS + MetonaSqlark(aria+OPFS) - 水墨中国风 UI - 引擎种子随机、确定性可回放 - 19 项单元测试、端到端冒烟验证
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import { useGameStore } from '../store'
|
||||
import { SaveMeta } from '../../game/types/domain'
|
||||
import mountainUrl from '../../assets/mountain.svg'
|
||||
|
||||
function slotLabel(meta: SaveMeta | null): string {
|
||||
if (!meta) return '虚位以待'
|
||||
return `${meta.name} · ${meta.year}年${meta.month}月 · ${meta.members}人 · 声望${meta.reputation}`
|
||||
}
|
||||
|
||||
export default function Boot() {
|
||||
const slots = useGameStore((s) => s.slots)
|
||||
const go = useGameStore((s) => s.go)
|
||||
const continueGame = useGameStore((s) => s.continueGame)
|
||||
const deleteSave = useGameStore((s) => s.deleteSave)
|
||||
const toast = useGameStore((s) => s.toast)
|
||||
|
||||
return (
|
||||
<div className="boot">
|
||||
<div className="boot-bg">
|
||||
<img src={mountainUrl} alt="" />
|
||||
</div>
|
||||
<div className="boot-inner">
|
||||
<div className="boot-title">仙途家族志</div>
|
||||
<div className="boot-tagline">一 族 兴 衰 · 千 秋 烟 云</div>
|
||||
<div className="boot-divider" />
|
||||
<div className="boot-en">CHRONICLE OF THE IMMORTAL CLAN</div>
|
||||
<div className="boot-actions" style={{ marginTop: 26 }}>
|
||||
<button className="boot-newgame" onClick={() => go('newgame')}>
|
||||
开 创 家 族
|
||||
</button>
|
||||
{slots.map((meta, i) => (
|
||||
<div key={i} className="boot-slot">
|
||||
{meta && <div className="slot-no">{i + 1}</div>}
|
||||
{meta ? (
|
||||
<>
|
||||
<div style={{ flex: 1, cursor: 'pointer' }} onClick={() => void continueGame(i + 1)}>
|
||||
<div className="dim2" style={{ fontSize: '0.72rem', color: '#6d5d40' }}>第{i + 1}档</div>
|
||||
<div style={{ color: '#dcc898', letterSpacing: '1px' }}>{slotLabel(meta)}</div>
|
||||
</div>
|
||||
<button
|
||||
className="btn btn-sm btn-danger"
|
||||
title="删除本档"
|
||||
onClick={() => {
|
||||
if (window.confirm(`确定删除第 ${i + 1} 档存档?此操作不可撤销。`)) {
|
||||
void deleteSave(i + 1)
|
||||
}
|
||||
}}
|
||||
>
|
||||
删
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<div className="boot-slot-empty" style={{ flex: 1 }} onClick={() => go('newgame')}>
|
||||
<span className="slot-no">{i + 1}</span>
|
||||
<span style={{ color: '#6d5d40' }}>虚位以待</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 18 }}>
|
||||
<span className="seal" style={{ fontSize: '0.62rem' }}>癸未年</span>
|
||||
<span style={{ color: '#6d5d40', fontSize: '0.78rem', letterSpacing: '2px' }}>
|
||||
燃灯续香火 · 卷中写春秋
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{toast && <div className="toast">{toast}</div>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user