feat(game): 添加桌面和移动设备的状态栏功能

- 添加 FORCE_DESKTOP_STREAK_EFFECT_PREVIEW 和 FORCE_MOBILE_STREAK_EFFECT_PREVIEW 常量用于预览
- 在桌面状态栏中实现连击效果显示逻辑
- 在移动状态栏中实现不同的背景图像和布局样式
- 为移动设备添加火焰图标和连击计数显示
- 更新移动设备状态栏的列布局和间距配置
- 使用条件渲染来切换不同的背景和字体样式
This commit is contained in:
JiaJun
2026-07-16 14:47:04 +08:00
parent 20f31ff0a5
commit 596d435d52
2 changed files with 36 additions and 14 deletions

View File

@@ -17,6 +17,8 @@ import { DesktopCountdown } from '@/features/game/components/desktop/desktop-cou
import { useGameStatusVm } from '@/hooks/use-game-status-vm.ts' import { useGameStatusVm } from '@/hooks/use-game-status-vm.ts'
import { cn } from '@/lib/utils.ts' import { cn } from '@/lib/utils.ts'
const FORCE_DESKTOP_STREAK_EFFECT_PREVIEW = true
export function DesktopStatusLine() { export function DesktopStatusLine() {
const { t } = useTranslation() const { t } = useTranslation()
const prefersReducedMotion = useReducedMotion() const prefersReducedMotion = useReducedMotion()
@@ -32,7 +34,9 @@ export function DesktopStatusLine() {
} = useGameStatusVm() } = useGameStatusVm()
const [remainingMs, setRemainingMs] = useState(countdownMs) const [remainingMs, setRemainingMs] = useState(countdownMs)
const showWarningCountdown = remainingMs <= 5000 && remainingMs > 0 const showWarningCountdown = remainingMs <= 5000 && remainingMs > 0
const showStreakLimitOnly = typeof streakValue === 'number' && streakValue > 1 const showStreakLimitOnly =
FORCE_DESKTOP_STREAK_EFFECT_PREVIEW ||
(typeof streakValue === 'number' && streakValue > 1)
const countdownClassName = useMemo( const countdownClassName = useMemo(
() => () =>
showWarningCountdown showWarningCountdown

View File

@@ -15,6 +15,8 @@ import { DesktopCountdown } from '@/features/game/components/desktop/desktop-cou
import { useGameStatusVm } from '@/hooks/use-game-status-vm.ts' import { useGameStatusVm } from '@/hooks/use-game-status-vm.ts'
import { cn } from '@/lib/utils.ts' import { cn } from '@/lib/utils.ts'
const FORCE_MOBILE_STREAK_EFFECT_PREVIEW = true
function isIosDevice() { function isIosDevice() {
if (typeof navigator === 'undefined') { if (typeof navigator === 'undefined') {
return false return false
@@ -160,23 +162,32 @@ export function MobileStatusLine() {
export function MobileStatusMetrics() { export function MobileStatusMetrics() {
const { t } = useTranslation() const { t } = useTranslation()
const { limitLabel, oddsLabel, streakLabel, streakValue } = useGameStatusVm() const { limitLabel, oddsLabel, streakLabel, streakValue } = useGameStatusVm()
const showStreakLimitOnly = typeof streakValue === 'number' && streakValue > 1 const showStreakLimitOnly =
FORCE_MOBILE_STREAK_EFFECT_PREVIEW ||
(typeof streakValue === 'number' && streakValue > 1)
return ( return (
<SmartBackground <SmartBackground
src={statusLine} src={showStreakLimitOnly ? streakBg : statusLine}
size="100% 100%" size={showStreakLimitOnly ? '106% 126%' : '100% 100%'}
className="relative grid h-design-26 w-full grid-cols-3 items-center overflow-visible bg-center bg-no-repeat px-design-3 font-bold leading-none text-[#CBD3D5]" className={cn(
style={{ fontSize: 'calc(var(--design-unit) * 5.5)' }} 'relative grid h-design-26 w-full items-center overflow-visible bg-center bg-no-repeat px-design-3 font-bold leading-none text-[#CBD3D5]',
showStreakLimitOnly
? 'grid-cols-2 text-design-7'
: 'grid-cols-3 text-[calc(var(--design-unit)*5.5)]',
)}
> >
{showStreakLimitOnly ? ( {showStreakLimitOnly ? (
<div <div className="relative z-10 flex min-w-0 items-center justify-center gap-design-2 whitespace-nowrap [text-shadow:0_0_calc(var(--design-unit)*3)_#000,0_calc(var(--design-unit)*1)_calc(var(--design-unit)*1)_#000]">
className="pointer-events-none absolute bottom-[calc(var(--design-unit)*-5)] left-0 right-[33.333%] top-[calc(var(--design-unit)*-6)] z-0 bg-center bg-no-repeat opacity-95" <SmartImage
style={{ className="h-design-10 w-design-8"
backgroundImage: `url(${streakBg})`, alt="fire"
backgroundSize: '120% 150%', src={fire}
}} />
/> <span>{t('gameDesktop.status.streak')}:</span>
{/*<span className="bg-gradient-to-b from-[#FF9C36] to-[#FF9C36] bg-clip-text text-transparent">*/}
<span className="text-[#FF9C36]">{streakLabel}</span>
</div>
) : ( ) : (
<> <>
<div className="relative z-10 flex min-w-0 items-center justify-center whitespace-nowrap"> <div className="relative z-10 flex min-w-0 items-center justify-center whitespace-nowrap">
@@ -196,7 +207,14 @@ export function MobileStatusMetrics() {
</div> </div>
</> </>
)} )}
<div className="relative z-10 col-start-3 flex min-w-0 items-center justify-center gap-design-1 whitespace-nowrap"> <div
className={cn(
'relative z-10 flex min-w-0 items-center justify-center whitespace-nowrap',
showStreakLimitOnly
? 'col-start-2 gap-design-2 [text-shadow:0_0_calc(var(--design-unit)*3)_#000,0_calc(var(--design-unit)*1)_calc(var(--design-unit)*1)_#000]'
: 'col-start-3 gap-design-1',
)}
>
<SmartImage className="h-design-8 w-design-6" alt="lock" src={lock} /> <SmartImage className="h-design-8 w-design-6" alt="lock" src={lock} />
<span>{t('gameDesktop.status.limit')}:</span> <span>{t('gameDesktop.status.limit')}:</span>
<SmartImage <SmartImage