update: achievement

This commit is contained in:
Vick Scarlet
2026-08-16 20:06:16 +08:00
committed by 神戸小鳥
parent a0e3f1b355
commit 9dc8a3e8bb
12 changed files with 284 additions and 17 deletions
+1 -1
View File
@@ -17,7 +17,7 @@
width: 100%;
padding: 0;
box-sizing: border-box;
.title {
> .title {
display: flex;
flex-direction: row;
justify-content: center;
+2
View File
@@ -8,6 +8,7 @@ import Pick from '@/containers/TalentPick'
import Alloc from '@/containers/Alloc'
import Play from '@/containers/Play'
import Summary from '@/containers/Summary'
import Achv from '@/containers/Achv'
import './Game.css'
export function Container() {
@@ -20,6 +21,7 @@ export function Container() {
case Step.Alloc: return <Alloc />
case Step.Play: return <Play />
case Step.Summary: return <Summary />
case Step.Achv: return <Achv />
default: return null
}
}
+2 -2
View File
@@ -52,8 +52,8 @@ export const JudgeLineMap = {
spirit: [0, 1, 2, 4, 7, 9, 11],
intelligence: [0, 1, 2, 4, 7, 9, 11, 21, 131, 501],
strength: [0, 1, 2, 4, 7, 9, 11, 21, 101, 401, 1001, 2001],
talent: [0, 0.3, 0.6, 0.9],
event: [0, 0.2, 0.4, 0.6],
talent: [0, 30, 60, 90],
event: [0, 20, 40, 60],
}
// 可评级属性
export type Judges = keyof typeof JudgeLineMap
+120
View File
@@ -0,0 +1,120 @@
.screen.achv {
height: calc(100dvh - 2rem);
width: min(calc(100dvw - 2rem), 48rem);
gap: 1rem;
> .stats {
> .details {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.5rem;
> div {
display: flex;
flex-direction: column;
align-items: center;
border: 0.0625rem solid var(--grade-color);
color: var(--grade-color);
box-sizing: border-box;
position: relative;
transform-style: preserve-3d;
user-select: none;
> span {
display: flex;
align-items: center;
justify-content: center;
}
> .title {
font-weight: bold;
font-size: 1.5rem;
height: 2.5rem;
}
> .value {
height: 2rem;
}
}
> .prg {
padding-bottom: 0.1875rem;
&::before,
&::after {
content: '';
display: block;
position: absolute;
height: 0.1875rem;
left: 0;
bottom: 0;
transform: translateZ(-1px);
}
&::after {
width: var(--progress, 0%);
background: var(--grade-color);
transition: width 0.2s ease-in-out;
}
&::before {
width: 100%;
border-top: 0.0625rem solid var(--grade-color);
box-sizing: border-box;
}
}
}
}
> .achievement-list {
flex: 1 0;
width: 100%;
> ul {
flex: 1 0;
display: grid;
flex-direction: column;
grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
gap: 0.5rem;
box-sizing: border-box;
> li.achievement {
margin-right: 0.0625rem;
display: flex;
flex-direction: column;
align-items: center;
color: var(--grade-color);
border: 0.0625rem solid var(--grade-color);
padding: 0 0.0625rem;
box-sizing: border-box;
transform-style: preserve-3d;
position: relative;
user-select: none;
>.name {
font-weight: bold;
font-size: 1.2rem;
height: 2rem;
display: flex;
align-items: center;
justify-content: center;
}
>.description {
height: 1.5rem;
display: flex;
align-items: center;
justify-content: center;
}
&::before{
content: '';
display: block;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
padding: 0.0625rem;
margin: -0.0625rem;
transform: translateZ(1px);
background: var(--base-background-color);
opacity: 0.8;
}
&.colled {
&::before{
transform: translateZ(-1px);
background: var(--grade-color);
opacity: 0.15;
}
}
}
}
}
}
+82
View File
@@ -0,0 +1,82 @@
import { useAchv, useGoHome } from '@remake/hooks'
import { judge, judgeGrade, judgeGradeByValue } from '@/config'
import { rates } from '@/display'
import { achievements, type Achievement } from '@remake/data'
import './Achv.css'
interface AchievementProps {
id: Achievement['id']
colled: boolean
}
export function AchievementItem({ id, colled }: AchievementProps) {
const { name, grade, description, hide } = achievements.get(id)!
return (
<li className={`achievement grade-${grade} ${colled ? 'colled' : ''}`}>
<span className="name">{hide && !colled ? '???' : name}</span>
<span className="description">
{hide && !colled ? '???' : description}
</span>
</li>
)
}
export function Achv() {
const goHome = useGoHome()
const [stats, sorted] = useAchv()
const jtimes = judge('times', stats.times)
const gtimes = judgeGrade('times', jtimes)
const jachv = judge('achievements', stats.achv)
const gachv = judgeGrade('achievements', jachv)
const gevent = judgeGradeByValue('event', stats.event)
const revent = stats.event.toFixed(2) + '%'
const gtalent = judgeGradeByValue('talent', stats.talent)
const rtalent = stats.talent.toFixed(2) + '%'
return (
<div className="screen achv">
<div className="controls">
<button className="info"></button>
<button className="primary" onClick={goHome}>
</button>
</div>
<div className="section stats">
<div className="title"></div>
<div className="details">
<div className={`grade-${gtimes}`}>
<span className="title">{stats.times}</span>
<span className="value">{rates.times[jtimes]}</span>
</div>
<div className={`grade-${gachv}`}>
<span className="title">{stats.achv}</span>
<span className="value">
{rates.achievement[jachv]}
</span>
</div>
<div
className={`prg grade-${gevent}`}
style={{ '--progress': revent } as React.CSSProperties}
>
<span className="title"></span>
<span className="value">{revent}</span>
</div>
<div
className={`prg grade-${gtalent}`}
style={{ '--progress': rtalent } as React.CSSProperties}
>
<span className="title"></span>
<span className="value">{rtalent}</span>
</div>
</div>
</div>
<div className="section achievement-list hide-scrollbar">
<div className="title"></div>
<ul className="details hide-scrollbar">
{sorted.map(({ id, colled }) => (
<AchievementItem key={id} id={id} colled={colled} />
))}
</ul>
</div>
</div>
)
}
export default Achv
+11
View File
@@ -21,4 +21,15 @@
-webkit-tap-highlight-color: transparent;
transition: background-color 0.3s;
}
>.controls {
flex-direction: column;
> div {
flex: 1 0;
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
> button { flex: 1 0; }
}
}
}
+17 -4
View File
@@ -1,19 +1,32 @@
import { useRemake } from '@remake/hooks'
import { useRemake, useGoAchv } from '@remake/hooks'
import { TextSvg } from '@/components/TextSvg'
import { ThemeToggle } from '@/components/ThemeToggle'
import './Home.css'
export default function Home() {
const remake = useRemake()
const goAchv = useGoAchv()
return (
<div className="screen home">
<div className="title">
<TextSvg text="人生重开模拟器" className="main" />
<TextSvg text="这垃圾人生一秒也不想待了" className="sub" />
</div>
<button className="primary focus" onClick={remake}>
</button>
<div className="controls">
<div>
<button className="primary focus" onClick={remake}>
</button>
</div>
<div>
<button className="info" onClick={goAchv}>
</button>
<button className="info" onClick={goAchv}>
</button>
</div>
</div>
<ThemeToggle />
</div>
)