70e6b5808b
refactor: 重构游戏面板布局与交互逻辑 style: 优化CSS变量与响应式设计 docs: 添加游戏模型与工具函数文档 chore: 整理项目结构与资源文件
52 lines
1.9 KiB
TypeScript
52 lines
1.9 KiB
TypeScript
import type { EdgeView, GameView } from '@tinywaste/game-core';
|
|
|
|
/** Risk tier boundaries */
|
|
const RISK_LOW_MAX = 0.35;
|
|
const RISK_MID_MAX = 0.65;
|
|
|
|
const PLACE_ATMOSPHERE: Record<
|
|
string,
|
|
{
|
|
weather: string;
|
|
temperature: string;
|
|
wind: string;
|
|
}
|
|
> = {
|
|
home: { weather: 'Light rain', temperature: '18°C', wind: 'Wind 12 km/h' },
|
|
roadside: { weather: 'Cloud break', temperature: '16°C', wind: 'Wind 18 km/h' },
|
|
old_store: { weather: 'Dust drift', temperature: '20°C', wind: 'Wind 9 km/h' },
|
|
village_market: { weather: 'Dry overcast', temperature: '22°C', wind: 'Wind 7 km/h' },
|
|
rain_farm: { weather: 'Wet fog', temperature: '14°C', wind: 'Wind 10 km/h' },
|
|
city_edge: { weather: 'Soot haze', temperature: '19°C', wind: 'Wind 15 km/h' },
|
|
subway_entrance: { weather: 'Cold draft', temperature: '11°C', wind: 'Wind 6 km/h' },
|
|
sewer: { weather: 'Toxic mist', temperature: '13°C', wind: 'Air still' },
|
|
vault_gate: { weather: 'Ash fall', temperature: '9°C', wind: 'Wind 4 km/h' },
|
|
};
|
|
|
|
export function edgeDestination(view: GameView, edge: EdgeView) {
|
|
return view.map.places.find((place) => place.id === edge.to);
|
|
}
|
|
|
|
export function getCurrentPlace(view: GameView) {
|
|
return view.map.places.find((place) => place.current) ?? null;
|
|
}
|
|
|
|
export function getPlaceAtmosphere(placeId: string) {
|
|
return PLACE_ATMOSPHERE[placeId] ?? { weather: 'Dry static', temperature: '17°C', wind: 'Wind 10 km/h' };
|
|
}
|
|
|
|
export function getVisibleRoutes(view: GameView, limit = 3) {
|
|
return view.map.edges.slice(0, limit);
|
|
}
|
|
|
|
export function getRouteRiskTier(risk: number) {
|
|
if (risk <= RISK_LOW_MAX) return { label: '低风险', tone: 'safe' as const };
|
|
if (risk <= RISK_MID_MAX) return { label: '中风险', tone: 'warn' as const };
|
|
return { label: '高风险', tone: 'danger' as const };
|
|
}
|
|
|
|
export function getRiskDots(risk: number) {
|
|
const lit = Math.max(1, Math.min(6, Math.round(risk * 6)));
|
|
return Array.from({ length: 6 }, (_, index) => index < lit);
|
|
}
|