sa2kit 1.6.32 → 1.6.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -132,7 +132,7 @@ function canMerge(a, b, config) {
132
132
  const dx = b.x - a.x;
133
133
  const dy = b.y - a.y;
134
134
  const distance = Math.sqrt(dx * dx + dy * dy);
135
- const threshold = (a.radius + b.radius) * 0.92;
135
+ const threshold = a.radius + b.radius + 0.75;
136
136
  return distance <= threshold;
137
137
  }
138
138
  function mergeSameLevelOrbs(orbs, config) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mikuFusionGame/constants.ts","../../src/mikuFusionGame/engine/collision.ts","../../src/mikuFusionGame/engine/scoring.ts","../../src/mikuFusionGame/engine/physics.ts","../../src/mikuFusionGame/engine/merge.ts","../../src/mikuFusionGame/engine/stateMachine.ts","../../src/mikuFusionGame/hooks/useMikuFusionGame.ts","../../src/mikuFusionGame/hooks/useResponsiveCanvas.ts","../../src/mikuFusionGame/components/GameCanvas.tsx","../../src/mikuFusionGame/components/GameControls.tsx","../../src/mikuFusionGame/components/GameHUD.tsx","../../src/mikuFusionGame/components/GameResultModal.tsx","../../src/mikuFusionGame/components/MikuFusionGame.tsx","../../src/mikuFusionGame/content/index.ts"],"names":["useRef","useEffect","useLocalStorage","useState","useCallback","container","React","useMemo"],"mappings":"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","file":"index.js","sourcesContent":["import type { MikuFusionGameConfig } from './types';\n\nexport const BASE_RADIUS = 22;\nexport const RADIUS_STEP = 4;\n\nexport const LEVEL_LABEL_PREFIX = 'M';\n\nexport const DEFAULT_MIKU_FUSION_CONFIG: MikuFusionGameConfig = {\n width: 390,\n height: 700,\n gravity: 1450,\n damping: 0.995,\n collisionDamping: 0.92,\n spawnY: 82,\n lossLineY: 132,\n maxLevel: 10,\n maxOrbs: 90,\n maxMergesPerTick: 6,\n gameOverAgeThreshold: 1.1,\n spawnWeights: [0.62, 0.28, 0.1],\n theme: {\n backgroundTop: '#dafaff',\n backgroundBottom: '#86e5ef',\n aimLine: '#14b8a6',\n lossLine: '#ef4444',\n orbColors: [\n '#67e8f9',\n '#22d3ee',\n '#2dd4bf',\n '#5eead4',\n '#34d399',\n '#a7f3d0',\n '#99f6e4',\n '#0ea5e9',\n '#06b6d4',\n '#14b8a6',\n ],\n },\n};\n\n","import type { FusionOrb, MikuFusionGameConfig } from '../types';\n\nexport function resolveCircleCollisions(\n orbs: FusionOrb[],\n config: MikuFusionGameConfig\n): FusionOrb[] {\n const next = orbs.map((orb) => ({ ...orb }));\n\n for (let i = 0; i < next.length; i += 1) {\n for (let j = i + 1; j < next.length; j += 1) {\n const a = next[i];\n const b = next[j];\n\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const distance = Math.sqrt(dx * dx + dy * dy) || 0.0001;\n const minDistance = a.radius + b.radius;\n\n if (distance >= minDistance) {\n continue;\n }\n\n const nx = dx / distance;\n const ny = dy / distance;\n const overlap = minDistance - distance;\n\n a.x -= nx * overlap * 0.5;\n a.y -= ny * overlap * 0.5;\n b.x += nx * overlap * 0.5;\n b.y += ny * overlap * 0.5;\n\n const rvx = b.vx - a.vx;\n const rvy = b.vy - a.vy;\n const velocityAlongNormal = rvx * nx + rvy * ny;\n\n if (velocityAlongNormal > 0) {\n continue;\n }\n\n const restitution = config.collisionDamping;\n const impulse = (-(1 + restitution) * velocityAlongNormal) / 2;\n const impulseX = impulse * nx;\n const impulseY = impulse * ny;\n\n a.vx -= impulseX;\n a.vy -= impulseY;\n b.vx += impulseX;\n b.vy += impulseY;\n }\n }\n\n return next;\n}\n\n","export function getMergeScore(newLevel: number, chainIndex: number): number {\n const base = 10 * Math.max(1, newLevel) * Math.max(1, newLevel);\n const chainMultiplier = 1 + Math.max(0, chainIndex - 1) * 0.15;\n return Math.round(base * chainMultiplier);\n}\n\n","import { BASE_RADIUS, RADIUS_STEP } from '../constants';\nimport type { FusionOrb, MikuFusionGameConfig } from '../types';\n\nexport function getRadiusByLevel(level: number): number {\n return BASE_RADIUS + (Math.max(1, level) - 1) * RADIUS_STEP;\n}\n\nexport function stepPhysics(\n orbs: FusionOrb[],\n config: MikuFusionGameConfig,\n dt: number\n): FusionOrb[] {\n return orbs.map((orb) => {\n const next = { ...orb };\n\n next.vy += config.gravity * dt;\n next.vx *= config.damping;\n next.vy *= config.damping;\n\n next.x += next.vx * dt;\n next.y += next.vy * dt;\n next.age += dt;\n\n if (next.x - next.radius < 0) {\n next.x = next.radius;\n next.vx = Math.abs(next.vx) * config.collisionDamping;\n } else if (next.x + next.radius > config.width) {\n next.x = config.width - next.radius;\n next.vx = -Math.abs(next.vx) * config.collisionDamping;\n }\n\n if (next.y + next.radius > config.height) {\n next.y = config.height - next.radius;\n next.vy = -Math.abs(next.vy) * config.collisionDamping;\n }\n\n return next;\n });\n}\n\n","import type { FusionOrb, MergeResult, MikuFusionGameConfig } from '../types';\nimport { getMergeScore } from './scoring';\nimport { getRadiusByLevel } from './physics';\n\nfunction canMerge(a: FusionOrb, b: FusionOrb, config: MikuFusionGameConfig): boolean {\n if (a.level !== b.level) {\n return false;\n }\n\n if (a.level >= config.maxLevel) {\n return false;\n }\n\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n const threshold = (a.radius + b.radius) * 0.92;\n\n return distance <= threshold;\n}\n\nexport function mergeSameLevelOrbs(\n orbs: FusionOrb[],\n config: MikuFusionGameConfig\n): MergeResult {\n const mergedIds = new Set<string>();\n const spawned: FusionOrb[] = [];\n let scoreGain = 0;\n let chainIndex = 0;\n\n for (let i = 0; i < orbs.length; i += 1) {\n if (mergedIds.has(orbs[i].id)) {\n continue;\n }\n\n for (let j = i + 1; j < orbs.length; j += 1) {\n if (mergedIds.has(orbs[j].id)) {\n continue;\n }\n\n const a = orbs[i];\n const b = orbs[j];\n\n if (!canMerge(a, b, config)) {\n continue;\n }\n\n mergedIds.add(a.id);\n mergedIds.add(b.id);\n chainIndex += 1;\n\n const nextLevel = Math.min(config.maxLevel, a.level + 1);\n const mergedOrb: FusionOrb = {\n id: `orb-${a.id}-${b.id}-${chainIndex}`,\n x: (a.x + b.x) / 2,\n y: (a.y + b.y) / 2,\n vx: (a.vx + b.vx) / 2 * 0.4,\n vy: (a.vy + b.vy) / 2 * 0.4,\n radius: getRadiusByLevel(nextLevel),\n level: nextLevel,\n age: Math.min(a.age, b.age),\n };\n\n spawned.push(mergedOrb);\n scoreGain += getMergeScore(nextLevel, chainIndex);\n\n if (chainIndex >= config.maxMergesPerTick) {\n break;\n }\n }\n\n if (chainIndex >= config.maxMergesPerTick) {\n break;\n }\n }\n\n if (mergedIds.size === 0) {\n return {\n orbs,\n scoreGain: 0,\n mergeCount: 0,\n };\n }\n\n const survivors = orbs.filter((orb) => !mergedIds.has(orb.id));\n const mergedOrbs = survivors.concat(spawned);\n\n return {\n orbs: mergedOrbs,\n scoreGain,\n mergeCount: chainIndex,\n };\n}\n\n","import type { MikuFusionGameStatus } from '../types';\n\nconst ALLOWED_TRANSITIONS: Record<MikuFusionGameStatus, MikuFusionGameStatus[]> = {\n ready: ['playing'],\n playing: ['paused', 'gameOver', 'ready'],\n paused: ['playing', 'ready'],\n gameOver: ['ready', 'playing'],\n};\n\nexport function canTransition(\n from: MikuFusionGameStatus,\n to: MikuFusionGameStatus\n): boolean {\n return ALLOWED_TRANSITIONS[from].includes(to);\n}\n\n","'use client';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { RefObject } from 'react';\nimport { useLocalStorage } from '../../storage/hooks/useLocalStorage';\nimport { DEFAULT_MIKU_FUSION_CONFIG, LEVEL_LABEL_PREFIX } from '../constants';\nimport { resolveCircleCollisions } from '../engine/collision';\nimport { mergeSameLevelOrbs } from '../engine/merge';\nimport { getRadiusByLevel, stepPhysics } from '../engine/physics';\nimport { canTransition } from '../engine/stateMachine';\nimport type {\n FusionOrb,\n MikuFusionGameCallbacks,\n MikuFusionGameConfig,\n MikuFusionGameStatus,\n} from '../types';\n\nexport interface UseMikuFusionGameOptions extends Partial<MikuFusionGameConfig>, MikuFusionGameCallbacks {\n storageKey?: string;\n}\n\nexport interface UseMikuFusionGameResult {\n canvasRef: RefObject<HTMLCanvasElement>;\n status: MikuFusionGameStatus;\n score: number;\n bestScore: number;\n nextLevel: number;\n config: MikuFusionGameConfig;\n setAimFromClientX: (clientX: number, rect: DOMRect) => void;\n handleDrop: (clientX: number, rect: DOMRect) => void;\n togglePause: () => void;\n restart: () => void;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction nextOrbLevel(weights: number[]): number {\n const random = Math.random();\n let cumulative = 0;\n\n for (let i = 0; i < weights.length; i += 1) {\n cumulative += weights[i] ?? 0;\n if (random <= cumulative) {\n return i + 1;\n }\n }\n\n return Math.max(1, weights.length);\n}\n\nfunction getOrbColor(level: number, config: MikuFusionGameConfig): string {\n const index = Math.max(0, Math.min(config.theme.orbColors.length - 1, level - 1));\n return config.theme.orbColors[index] || '#22d3ee';\n}\n\nfunction drawScene(\n context: CanvasRenderingContext2D,\n width: number,\n height: number,\n config: MikuFusionGameConfig,\n orbs: FusionOrb[],\n aimX: number,\n nextLevel: number,\n status: MikuFusionGameStatus\n): void {\n const gradient = context.createLinearGradient(0, 0, 0, height);\n gradient.addColorStop(0, config.theme.backgroundTop);\n gradient.addColorStop(1, config.theme.backgroundBottom);\n context.fillStyle = gradient;\n context.fillRect(0, 0, width, height);\n\n context.lineWidth = 2;\n context.strokeStyle = config.theme.lossLine;\n context.setLineDash([6, 6]);\n context.beginPath();\n context.moveTo(0, config.lossLineY);\n context.lineTo(width, config.lossLineY);\n context.stroke();\n context.setLineDash([]);\n\n context.strokeStyle = config.theme.aimLine;\n context.lineWidth = 1.5;\n context.beginPath();\n context.moveTo(aimX, 0);\n context.lineTo(aimX, config.spawnY);\n context.stroke();\n\n const previewRadius = getRadiusByLevel(nextLevel);\n context.fillStyle = getOrbColor(nextLevel, config);\n context.beginPath();\n context.arc(aimX, config.spawnY - previewRadius - 4, previewRadius, 0, Math.PI * 2);\n context.fill();\n\n orbs.forEach((orb) => {\n context.beginPath();\n context.fillStyle = getOrbColor(orb.level, config);\n context.arc(orb.x, orb.y, orb.radius, 0, Math.PI * 2);\n context.fill();\n\n context.fillStyle = '#0f172a';\n context.font = 'bold 12px system-ui';\n context.textAlign = 'center';\n context.textBaseline = 'middle';\n context.fillText(`${LEVEL_LABEL_PREFIX}${orb.level}`, orb.x, orb.y);\n });\n\n if (status === 'paused') {\n context.fillStyle = 'rgba(15, 23, 42, 0.5)';\n context.fillRect(0, 0, width, height);\n context.fillStyle = '#ffffff';\n context.font = 'bold 30px system-ui';\n context.textAlign = 'center';\n context.fillText('Paused', width / 2, height / 2);\n }\n}\n\nfunction normalizeConfig(config?: Partial<MikuFusionGameConfig>): MikuFusionGameConfig {\n const mergedTheme = {\n ...DEFAULT_MIKU_FUSION_CONFIG.theme,\n ...(config?.theme ?? {}),\n };\n\n const merged = {\n ...DEFAULT_MIKU_FUSION_CONFIG,\n ...(config ?? {}),\n theme: mergedTheme,\n };\n\n const totalWeight = merged.spawnWeights.reduce((sum, current) => sum + current, 0);\n if (totalWeight <= 0) {\n merged.spawnWeights = [...DEFAULT_MIKU_FUSION_CONFIG.spawnWeights];\n } else if (Math.abs(totalWeight - 1) > 0.001) {\n merged.spawnWeights = merged.spawnWeights.map((weight) => weight / totalWeight);\n }\n\n return merged;\n}\n\nexport function useMikuFusionGame(options: UseMikuFusionGameOptions = {}): UseMikuFusionGameResult {\n const configRef = useRef<MikuFusionGameConfig>(normalizeConfig(options));\n const config = configRef.current;\n const onScoreChangeRef = useRef(options.onScoreChange);\n const onGameOverRef = useRef(options.onGameOver);\n\n useEffect(() => {\n onScoreChangeRef.current = options.onScoreChange;\n onGameOverRef.current = options.onGameOver;\n }, [options.onGameOver, options.onScoreChange]);\n\n const [bestScore, setBestScore] = useLocalStorage<number>(\n options.storageKey || 'sa2kit:mikuFusionGame:bestScore',\n 0\n );\n\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const rafRef = useRef<number | null>(null);\n const lastTsRef = useRef<number>(0);\n const idRef = useRef<number>(0);\n const orbsRef = useRef<FusionOrb[]>([]);\n const aimXRef = useRef<number>(config.width / 2);\n const scoreRef = useRef<number>(0);\n\n const [status, setStatus] = useState<MikuFusionGameStatus>('ready');\n const [score, setScore] = useState(0);\n const [nextLevel, setNextLevel] = useState(() => nextOrbLevel(config.spawnWeights));\n\n const draw = useCallback(\n (nextStatus: MikuFusionGameStatus = status) => {\n const canvas = canvasRef.current;\n if (!canvas) {\n return;\n }\n\n const context = canvas.getContext('2d');\n if (!context) {\n return;\n }\n\n drawScene(\n context,\n config.width,\n config.height,\n config,\n orbsRef.current,\n aimXRef.current,\n nextLevel,\n nextStatus\n );\n },\n [config, nextLevel, status]\n );\n\n const transitionStatus = useCallback((nextStatus: MikuFusionGameStatus) => {\n setStatus((previous) => (canTransition(previous, nextStatus) ? nextStatus : previous));\n }, []);\n\n const spawnOrb = useCallback(() => {\n if (status === 'paused' || status === 'gameOver') {\n return;\n }\n\n if (status === 'ready') {\n transitionStatus('playing');\n }\n\n idRef.current += 1;\n const radius = getRadiusByLevel(nextLevel);\n const x = clamp(aimXRef.current, radius, config.width - radius);\n const created: FusionOrb = {\n id: `${idRef.current}`,\n x,\n y: config.spawnY,\n vx: 0,\n vy: 0,\n radius,\n level: nextLevel,\n age: 0,\n };\n\n const nextOrbs = orbsRef.current.concat(created);\n orbsRef.current = nextOrbs.slice(-config.maxOrbs);\n\n setNextLevel(nextOrbLevel(config.spawnWeights));\n }, [config, nextLevel, status, transitionStatus]);\n\n const restart = useCallback(() => {\n orbsRef.current = [];\n scoreRef.current = 0;\n setScore(0);\n setNextLevel(nextOrbLevel(config.spawnWeights));\n transitionStatus('ready');\n draw('ready');\n }, [config.spawnWeights, draw, transitionStatus]);\n\n const togglePause = useCallback(() => {\n setStatus((previous) => {\n if (previous === 'playing' && canTransition(previous, 'paused')) {\n return 'paused';\n }\n if (previous === 'paused' && canTransition(previous, 'playing')) {\n return 'playing';\n }\n return previous;\n });\n }, []);\n\n const setAimFromClientX = useCallback((clientX: number, rect: DOMRect) => {\n const ratio = config.width / rect.width;\n const x = (clientX - rect.left) * ratio;\n aimXRef.current = clamp(x, 0, config.width);\n }, [config.width]);\n\n const handleDrop = useCallback(\n (clientX: number, rect: DOMRect) => {\n setAimFromClientX(clientX, rect);\n spawnOrb();\n },\n [setAimFromClientX, spawnOrb]\n );\n\n useEffect(() => {\n draw(status);\n }, [draw, status]);\n\n useEffect(() => {\n if (status !== 'playing') {\n if (rafRef.current) {\n window.cancelAnimationFrame(rafRef.current);\n }\n lastTsRef.current = 0;\n draw(status);\n return;\n }\n\n const frame = (timestamp: number) => {\n if (lastTsRef.current === 0) {\n lastTsRef.current = timestamp;\n }\n\n const dt = Math.min((timestamp - lastTsRef.current) / 1000, 0.033);\n lastTsRef.current = timestamp;\n\n let orbs = stepPhysics(orbsRef.current, config, dt);\n orbs = resolveCircleCollisions(orbs, config);\n\n const merged = mergeSameLevelOrbs(orbs, config);\n orbs = merged.orbs;\n orbsRef.current = orbs.slice(-config.maxOrbs);\n\n if (merged.scoreGain > 0) {\n scoreRef.current += merged.scoreGain;\n setScore(scoreRef.current);\n onScoreChangeRef.current?.(scoreRef.current);\n }\n\n const gameOver = orbs.some(\n (orb) =>\n orb.age > config.gameOverAgeThreshold &&\n orb.y - orb.radius <= config.lossLineY &&\n Math.abs(orb.vy) < 90\n );\n\n if (gameOver) {\n transitionStatus('gameOver');\n const latestBest = Math.max(bestScore, scoreRef.current);\n if (latestBest !== bestScore) {\n setBestScore(latestBest);\n }\n onGameOverRef.current?.(scoreRef.current, latestBest);\n draw('gameOver');\n return;\n }\n\n draw('playing');\n rafRef.current = window.requestAnimationFrame(frame);\n };\n\n rafRef.current = window.requestAnimationFrame(frame);\n\n return () => {\n if (rafRef.current) {\n window.cancelAnimationFrame(rafRef.current);\n }\n };\n }, [\n bestScore,\n config,\n draw,\n setBestScore,\n status,\n transitionStatus,\n ]);\n\n useEffect(() => {\n if (score > bestScore) {\n setBestScore(score);\n }\n }, [bestScore, score, setBestScore]);\n\n return {\n canvasRef,\n status,\n score,\n bestScore: Math.max(bestScore, score),\n nextLevel,\n config,\n setAimFromClientX,\n handleDrop,\n togglePause,\n restart,\n };\n}\n","'use client';\n\nimport { useEffect, useState } from 'react';\nimport type { RefObject } from 'react';\n\ninterface ResponsiveSize {\n displayWidth: number;\n displayHeight: number;\n scale: number;\n}\n\nexport function useResponsiveCanvas(\n logicalWidth: number,\n logicalHeight: number,\n containerRef: RefObject<HTMLElement>\n): ResponsiveSize {\n const [size, setSize] = useState<ResponsiveSize>({\n displayWidth: logicalWidth,\n displayHeight: logicalHeight,\n scale: 1,\n });\n\n useEffect(() => {\n const updateSize = () => {\n const container = containerRef.current;\n if (!container || typeof window === 'undefined') {\n return;\n }\n\n const rect = container.getBoundingClientRect();\n const maxWidth = Math.max(280, rect.width);\n const maxHeight = Math.max(420, Math.floor(window.innerHeight * 0.78));\n const scale = Math.min(maxWidth / logicalWidth, maxHeight / logicalHeight, 1);\n\n setSize({\n displayWidth: Math.floor(logicalWidth * scale),\n displayHeight: Math.floor(logicalHeight * scale),\n scale,\n });\n };\n\n updateSize();\n\n const container = containerRef.current;\n const observer =\n typeof ResizeObserver !== 'undefined' ? new ResizeObserver(updateSize) : null;\n if (container && observer) {\n observer.observe(container);\n }\n\n window.addEventListener('resize', updateSize);\n\n return () => {\n observer?.disconnect();\n window.removeEventListener('resize', updateSize);\n };\n }, [containerRef, logicalWidth, logicalHeight]);\n\n return size;\n}\n","import React from 'react';\nimport type { PointerEvent, RefObject } from 'react';\n\ninterface GameCanvasProps {\n canvasRef: RefObject<HTMLCanvasElement>;\n width: number;\n height: number;\n displayWidth: number;\n displayHeight: number;\n onPointerMove: (event: PointerEvent<HTMLCanvasElement>) => void;\n onPointerDown: (event: PointerEvent<HTMLCanvasElement>) => void;\n onPointerUp: (event: PointerEvent<HTMLCanvasElement>) => void;\n}\n\nexport function GameCanvas({\n canvasRef,\n width,\n height,\n displayWidth,\n displayHeight,\n onPointerMove,\n onPointerDown,\n onPointerUp,\n}: GameCanvasProps) {\n return (\n <canvas\n ref={canvasRef}\n width={width}\n height={height}\n className=\"rounded-xl border border-cyan-200 bg-cyan-50 shadow-sm\"\n style={{\n width: `${displayWidth}px`,\n height: `${displayHeight}px`,\n maxWidth: '100%',\n touchAction: 'none',\n }}\n onPointerMove={onPointerMove}\n onPointerDown={onPointerDown}\n onPointerUp={onPointerUp}\n onContextMenu={(event) => event.preventDefault()}\n />\n );\n}\n","import React from 'react';\n\ninterface GameControlsProps {\n isPaused: boolean;\n isPlaying: boolean;\n onTogglePause: () => void;\n onRestart: () => void;\n}\n\nexport function GameControls({ isPaused, isPlaying, onTogglePause, onRestart }: GameControlsProps) {\n return (\n <div className=\"grid grid-cols-2 gap-2\">\n <button\n type=\"button\"\n className=\"rounded-lg bg-cyan-600 px-4 py-3 text-sm font-semibold text-white disabled:cursor-not-allowed disabled:opacity-50\"\n onClick={onTogglePause}\n disabled={!isPlaying}\n >\n {isPaused ? '继续' : '暂停'}\n </button>\n <button\n type=\"button\"\n className=\"rounded-lg bg-emerald-600 px-4 py-3 text-sm font-semibold text-white\"\n onClick={onRestart}\n >\n 重开\n </button>\n </div>\n );\n}\n\n","import React from 'react';\n\ninterface GameHUDProps {\n score: number;\n bestScore: number;\n nextLevel: number;\n statusText: string;\n}\n\nexport function GameHUD({ score, bestScore, nextLevel, statusText }: GameHUDProps) {\n return (\n <div className=\"flex items-center justify-between gap-2 rounded-lg border border-cyan-200 bg-white/80 p-3\">\n <div className=\"min-w-0\">\n <div className=\"text-xs text-slate-500\">当前分数</div>\n <div className=\"text-xl font-bold text-cyan-700\">{score}</div>\n <div className=\"text-xs text-slate-500\">最高分 {bestScore}</div>\n </div>\n <div className=\"text-right\">\n <div className=\"text-xs text-slate-500\">下一个</div>\n <div className=\"text-base font-semibold text-emerald-700\">M{nextLevel}</div>\n <div className=\"text-xs font-medium text-slate-600\">{statusText}</div>\n </div>\n </div>\n );\n}\n\n","import React from 'react';\n\ninterface GameResultModalProps {\n open: boolean;\n score: number;\n bestScore: number;\n onRestart: () => void;\n}\n\nexport function GameResultModal({ open, score, bestScore, onRestart }: GameResultModalProps) {\n if (!open) {\n return null;\n }\n\n return (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center bg-slate-900/50 p-4\">\n <div className=\"pointer-events-auto w-full max-w-xs rounded-xl bg-white p-5 shadow-2xl\">\n <h3 className=\"text-lg font-semibold text-slate-900\">游戏结束</h3>\n <p className=\"mt-2 text-sm text-slate-600\">当前分数:{score}</p>\n <p className=\"text-sm text-slate-600\">最高分:{bestScore}</p>\n <button\n type=\"button\"\n className=\"mt-4 w-full rounded-lg bg-cyan-600 px-4 py-2 text-sm font-semibold text-white\"\n onClick={onRestart}\n >\n 再来一局\n </button>\n </div>\n </div>\n );\n}\n\n","'use client';\n\nimport React, { useMemo, useRef } from 'react';\nimport type { MikuFusionGameCallbacks, MikuFusionGameConfig } from '../types';\nimport { useMikuFusionGame } from '../hooks/useMikuFusionGame';\nimport { useResponsiveCanvas } from '../hooks/useResponsiveCanvas';\nimport { GameCanvas } from './GameCanvas';\nimport { GameControls } from './GameControls';\nimport { GameHUD } from './GameHUD';\nimport { GameResultModal } from './GameResultModal';\n\nexport interface MikuFusionGameProps extends Partial<MikuFusionGameConfig>, MikuFusionGameCallbacks {\n className?: string;\n storageKey?: string;\n}\n\nexport function MikuFusionGame({ className, storageKey, ...options }: MikuFusionGameProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const {\n canvasRef,\n status,\n score,\n bestScore,\n nextLevel,\n config,\n setAimFromClientX,\n handleDrop,\n togglePause,\n restart,\n } = useMikuFusionGame({ ...options, storageKey });\n\n const { displayWidth, displayHeight } = useResponsiveCanvas(\n config.width,\n config.height,\n containerRef\n );\n\n const statusText = useMemo(() => {\n if (status === 'ready') {\n return '待开始';\n }\n if (status === 'playing') {\n return '进行中';\n }\n if (status === 'paused') {\n return '已暂停';\n }\n return '已结束';\n }, [status]);\n\n const handlePointerMove = (event: React.PointerEvent<HTMLCanvasElement>) => {\n const rect = event.currentTarget.getBoundingClientRect();\n setAimFromClientX(event.clientX, rect);\n };\n\n const handlePointerDown = (event: React.PointerEvent<HTMLCanvasElement>) => {\n event.currentTarget.setPointerCapture(event.pointerId);\n const rect = event.currentTarget.getBoundingClientRect();\n setAimFromClientX(event.clientX, rect);\n };\n\n const handlePointerUp = (event: React.PointerEvent<HTMLCanvasElement>) => {\n const rect = event.currentTarget.getBoundingClientRect();\n handleDrop(event.clientX, rect);\n event.currentTarget.releasePointerCapture(event.pointerId);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key.toLowerCase() === 'r') {\n restart();\n }\n if (event.key.toLowerCase() === 'p') {\n togglePause();\n }\n };\n\n return (\n <div\n ref={containerRef}\n tabIndex={0}\n onKeyDown={handleKeyDown}\n className={`relative mx-auto flex w-full max-w-xl flex-col gap-3 p-3 md:p-4 ${className || ''}`}\n style={{\n paddingBottom: 'max(0.75rem, env(safe-area-inset-bottom))',\n }}\n >\n <GameHUD score={score} bestScore={bestScore} nextLevel={nextLevel} statusText={statusText} />\n\n <div className=\"relative mx-auto\">\n <GameCanvas\n canvasRef={canvasRef}\n width={config.width}\n height={config.height}\n displayWidth={displayWidth}\n displayHeight={displayHeight}\n onPointerMove={handlePointerMove}\n onPointerDown={handlePointerDown}\n onPointerUp={handlePointerUp}\n />\n <GameResultModal open={status === 'gameOver'} score={score} bestScore={bestScore} onRestart={restart} />\n </div>\n\n <GameControls\n isPaused={status === 'paused'}\n isPlaying={status === 'playing' || status === 'paused'}\n onTogglePause={togglePause}\n onRestart={restart}\n />\n </div>\n );\n}\n\n","import type { MikuFusionContentRegistry } from './types';\n\nexport type * from './types';\n\n/**\n * 仅作为未来内容包化扩展占位。\n * 当前基础玩法不会消费这些数据。\n */\nexport const defaultContentRegistry: MikuFusionContentRegistry = {\n producers: [],\n songs: [],\n themes: [],\n};\n\n"]}
1
+ {"version":3,"sources":["../../src/mikuFusionGame/constants.ts","../../src/mikuFusionGame/engine/collision.ts","../../src/mikuFusionGame/engine/scoring.ts","../../src/mikuFusionGame/engine/physics.ts","../../src/mikuFusionGame/engine/merge.ts","../../src/mikuFusionGame/engine/stateMachine.ts","../../src/mikuFusionGame/hooks/useMikuFusionGame.ts","../../src/mikuFusionGame/hooks/useResponsiveCanvas.ts","../../src/mikuFusionGame/components/GameCanvas.tsx","../../src/mikuFusionGame/components/GameControls.tsx","../../src/mikuFusionGame/components/GameHUD.tsx","../../src/mikuFusionGame/components/GameResultModal.tsx","../../src/mikuFusionGame/components/MikuFusionGame.tsx","../../src/mikuFusionGame/content/index.ts"],"names":["useRef","useEffect","useLocalStorage","useState","useCallback","container","React","useMemo"],"mappings":"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","file":"index.js","sourcesContent":["import type { MikuFusionGameConfig } from './types';\n\nexport const BASE_RADIUS = 22;\nexport const RADIUS_STEP = 4;\n\nexport const LEVEL_LABEL_PREFIX = 'M';\n\nexport const DEFAULT_MIKU_FUSION_CONFIG: MikuFusionGameConfig = {\n width: 390,\n height: 700,\n gravity: 1450,\n damping: 0.995,\n collisionDamping: 0.92,\n spawnY: 82,\n lossLineY: 132,\n maxLevel: 10,\n maxOrbs: 90,\n maxMergesPerTick: 6,\n gameOverAgeThreshold: 1.1,\n spawnWeights: [0.62, 0.28, 0.1],\n theme: {\n backgroundTop: '#dafaff',\n backgroundBottom: '#86e5ef',\n aimLine: '#14b8a6',\n lossLine: '#ef4444',\n orbColors: [\n '#67e8f9',\n '#22d3ee',\n '#2dd4bf',\n '#5eead4',\n '#34d399',\n '#a7f3d0',\n '#99f6e4',\n '#0ea5e9',\n '#06b6d4',\n '#14b8a6',\n ],\n },\n};\n\n","import type { FusionOrb, MikuFusionGameConfig } from '../types';\n\nexport function resolveCircleCollisions(\n orbs: FusionOrb[],\n config: MikuFusionGameConfig\n): FusionOrb[] {\n const next = orbs.map((orb) => ({ ...orb }));\n\n for (let i = 0; i < next.length; i += 1) {\n for (let j = i + 1; j < next.length; j += 1) {\n const a = next[i];\n const b = next[j];\n\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const distance = Math.sqrt(dx * dx + dy * dy) || 0.0001;\n const minDistance = a.radius + b.radius;\n\n if (distance >= minDistance) {\n continue;\n }\n\n const nx = dx / distance;\n const ny = dy / distance;\n const overlap = minDistance - distance;\n\n a.x -= nx * overlap * 0.5;\n a.y -= ny * overlap * 0.5;\n b.x += nx * overlap * 0.5;\n b.y += ny * overlap * 0.5;\n\n const rvx = b.vx - a.vx;\n const rvy = b.vy - a.vy;\n const velocityAlongNormal = rvx * nx + rvy * ny;\n\n if (velocityAlongNormal > 0) {\n continue;\n }\n\n const restitution = config.collisionDamping;\n const impulse = (-(1 + restitution) * velocityAlongNormal) / 2;\n const impulseX = impulse * nx;\n const impulseY = impulse * ny;\n\n a.vx -= impulseX;\n a.vy -= impulseY;\n b.vx += impulseX;\n b.vy += impulseY;\n }\n }\n\n return next;\n}\n\n","export function getMergeScore(newLevel: number, chainIndex: number): number {\n const base = 10 * Math.max(1, newLevel) * Math.max(1, newLevel);\n const chainMultiplier = 1 + Math.max(0, chainIndex - 1) * 0.15;\n return Math.round(base * chainMultiplier);\n}\n\n","import { BASE_RADIUS, RADIUS_STEP } from '../constants';\nimport type { FusionOrb, MikuFusionGameConfig } from '../types';\n\nexport function getRadiusByLevel(level: number): number {\n return BASE_RADIUS + (Math.max(1, level) - 1) * RADIUS_STEP;\n}\n\nexport function stepPhysics(\n orbs: FusionOrb[],\n config: MikuFusionGameConfig,\n dt: number\n): FusionOrb[] {\n return orbs.map((orb) => {\n const next = { ...orb };\n\n next.vy += config.gravity * dt;\n next.vx *= config.damping;\n next.vy *= config.damping;\n\n next.x += next.vx * dt;\n next.y += next.vy * dt;\n next.age += dt;\n\n if (next.x - next.radius < 0) {\n next.x = next.radius;\n next.vx = Math.abs(next.vx) * config.collisionDamping;\n } else if (next.x + next.radius > config.width) {\n next.x = config.width - next.radius;\n next.vx = -Math.abs(next.vx) * config.collisionDamping;\n }\n\n if (next.y + next.radius > config.height) {\n next.y = config.height - next.radius;\n next.vy = -Math.abs(next.vy) * config.collisionDamping;\n }\n\n return next;\n });\n}\n\n","import type { FusionOrb, MergeResult, MikuFusionGameConfig } from '../types';\nimport { getMergeScore } from './scoring';\nimport { getRadiusByLevel } from './physics';\n\nfunction canMerge(a: FusionOrb, b: FusionOrb, config: MikuFusionGameConfig): boolean {\n if (a.level !== b.level) {\n return false;\n }\n\n if (a.level >= config.maxLevel) {\n return false;\n }\n\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n // Collision resolution keeps circles around exact touching distance.\n // Use a small epsilon so touching same-level orbs can merge reliably.\n const threshold = a.radius + b.radius + 0.75;\n\n return distance <= threshold;\n}\n\nexport function mergeSameLevelOrbs(\n orbs: FusionOrb[],\n config: MikuFusionGameConfig\n): MergeResult {\n const mergedIds = new Set<string>();\n const spawned: FusionOrb[] = [];\n let scoreGain = 0;\n let chainIndex = 0;\n\n for (let i = 0; i < orbs.length; i += 1) {\n if (mergedIds.has(orbs[i].id)) {\n continue;\n }\n\n for (let j = i + 1; j < orbs.length; j += 1) {\n if (mergedIds.has(orbs[j].id)) {\n continue;\n }\n\n const a = orbs[i];\n const b = orbs[j];\n\n if (!canMerge(a, b, config)) {\n continue;\n }\n\n mergedIds.add(a.id);\n mergedIds.add(b.id);\n chainIndex += 1;\n\n const nextLevel = Math.min(config.maxLevel, a.level + 1);\n const mergedOrb: FusionOrb = {\n id: `orb-${a.id}-${b.id}-${chainIndex}`,\n x: (a.x + b.x) / 2,\n y: (a.y + b.y) / 2,\n vx: (a.vx + b.vx) / 2 * 0.4,\n vy: (a.vy + b.vy) / 2 * 0.4,\n radius: getRadiusByLevel(nextLevel),\n level: nextLevel,\n age: Math.min(a.age, b.age),\n };\n\n spawned.push(mergedOrb);\n scoreGain += getMergeScore(nextLevel, chainIndex);\n\n if (chainIndex >= config.maxMergesPerTick) {\n break;\n }\n }\n\n if (chainIndex >= config.maxMergesPerTick) {\n break;\n }\n }\n\n if (mergedIds.size === 0) {\n return {\n orbs,\n scoreGain: 0,\n mergeCount: 0,\n };\n }\n\n const survivors = orbs.filter((orb) => !mergedIds.has(orb.id));\n const mergedOrbs = survivors.concat(spawned);\n\n return {\n orbs: mergedOrbs,\n scoreGain,\n mergeCount: chainIndex,\n };\n}\n","import type { MikuFusionGameStatus } from '../types';\n\nconst ALLOWED_TRANSITIONS: Record<MikuFusionGameStatus, MikuFusionGameStatus[]> = {\n ready: ['playing'],\n playing: ['paused', 'gameOver', 'ready'],\n paused: ['playing', 'ready'],\n gameOver: ['ready', 'playing'],\n};\n\nexport function canTransition(\n from: MikuFusionGameStatus,\n to: MikuFusionGameStatus\n): boolean {\n return ALLOWED_TRANSITIONS[from].includes(to);\n}\n\n","'use client';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { RefObject } from 'react';\nimport { useLocalStorage } from '../../storage/hooks/useLocalStorage';\nimport { DEFAULT_MIKU_FUSION_CONFIG, LEVEL_LABEL_PREFIX } from '../constants';\nimport { resolveCircleCollisions } from '../engine/collision';\nimport { mergeSameLevelOrbs } from '../engine/merge';\nimport { getRadiusByLevel, stepPhysics } from '../engine/physics';\nimport { canTransition } from '../engine/stateMachine';\nimport type {\n FusionOrb,\n MikuFusionGameCallbacks,\n MikuFusionGameConfig,\n MikuFusionGameStatus,\n} from '../types';\n\nexport interface UseMikuFusionGameOptions extends Partial<MikuFusionGameConfig>, MikuFusionGameCallbacks {\n storageKey?: string;\n}\n\nexport interface UseMikuFusionGameResult {\n canvasRef: RefObject<HTMLCanvasElement>;\n status: MikuFusionGameStatus;\n score: number;\n bestScore: number;\n nextLevel: number;\n config: MikuFusionGameConfig;\n setAimFromClientX: (clientX: number, rect: DOMRect) => void;\n handleDrop: (clientX: number, rect: DOMRect) => void;\n togglePause: () => void;\n restart: () => void;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction nextOrbLevel(weights: number[]): number {\n const random = Math.random();\n let cumulative = 0;\n\n for (let i = 0; i < weights.length; i += 1) {\n cumulative += weights[i] ?? 0;\n if (random <= cumulative) {\n return i + 1;\n }\n }\n\n return Math.max(1, weights.length);\n}\n\nfunction getOrbColor(level: number, config: MikuFusionGameConfig): string {\n const index = Math.max(0, Math.min(config.theme.orbColors.length - 1, level - 1));\n return config.theme.orbColors[index] || '#22d3ee';\n}\n\nfunction drawScene(\n context: CanvasRenderingContext2D,\n width: number,\n height: number,\n config: MikuFusionGameConfig,\n orbs: FusionOrb[],\n aimX: number,\n nextLevel: number,\n status: MikuFusionGameStatus\n): void {\n const gradient = context.createLinearGradient(0, 0, 0, height);\n gradient.addColorStop(0, config.theme.backgroundTop);\n gradient.addColorStop(1, config.theme.backgroundBottom);\n context.fillStyle = gradient;\n context.fillRect(0, 0, width, height);\n\n context.lineWidth = 2;\n context.strokeStyle = config.theme.lossLine;\n context.setLineDash([6, 6]);\n context.beginPath();\n context.moveTo(0, config.lossLineY);\n context.lineTo(width, config.lossLineY);\n context.stroke();\n context.setLineDash([]);\n\n context.strokeStyle = config.theme.aimLine;\n context.lineWidth = 1.5;\n context.beginPath();\n context.moveTo(aimX, 0);\n context.lineTo(aimX, config.spawnY);\n context.stroke();\n\n const previewRadius = getRadiusByLevel(nextLevel);\n context.fillStyle = getOrbColor(nextLevel, config);\n context.beginPath();\n context.arc(aimX, config.spawnY - previewRadius - 4, previewRadius, 0, Math.PI * 2);\n context.fill();\n\n orbs.forEach((orb) => {\n context.beginPath();\n context.fillStyle = getOrbColor(orb.level, config);\n context.arc(orb.x, orb.y, orb.radius, 0, Math.PI * 2);\n context.fill();\n\n context.fillStyle = '#0f172a';\n context.font = 'bold 12px system-ui';\n context.textAlign = 'center';\n context.textBaseline = 'middle';\n context.fillText(`${LEVEL_LABEL_PREFIX}${orb.level}`, orb.x, orb.y);\n });\n\n if (status === 'paused') {\n context.fillStyle = 'rgba(15, 23, 42, 0.5)';\n context.fillRect(0, 0, width, height);\n context.fillStyle = '#ffffff';\n context.font = 'bold 30px system-ui';\n context.textAlign = 'center';\n context.fillText('Paused', width / 2, height / 2);\n }\n}\n\nfunction normalizeConfig(config?: Partial<MikuFusionGameConfig>): MikuFusionGameConfig {\n const mergedTheme = {\n ...DEFAULT_MIKU_FUSION_CONFIG.theme,\n ...(config?.theme ?? {}),\n };\n\n const merged = {\n ...DEFAULT_MIKU_FUSION_CONFIG,\n ...(config ?? {}),\n theme: mergedTheme,\n };\n\n const totalWeight = merged.spawnWeights.reduce((sum, current) => sum + current, 0);\n if (totalWeight <= 0) {\n merged.spawnWeights = [...DEFAULT_MIKU_FUSION_CONFIG.spawnWeights];\n } else if (Math.abs(totalWeight - 1) > 0.001) {\n merged.spawnWeights = merged.spawnWeights.map((weight) => weight / totalWeight);\n }\n\n return merged;\n}\n\nexport function useMikuFusionGame(options: UseMikuFusionGameOptions = {}): UseMikuFusionGameResult {\n const configRef = useRef<MikuFusionGameConfig>(normalizeConfig(options));\n const config = configRef.current;\n const onScoreChangeRef = useRef(options.onScoreChange);\n const onGameOverRef = useRef(options.onGameOver);\n\n useEffect(() => {\n onScoreChangeRef.current = options.onScoreChange;\n onGameOverRef.current = options.onGameOver;\n }, [options.onGameOver, options.onScoreChange]);\n\n const [bestScore, setBestScore] = useLocalStorage<number>(\n options.storageKey || 'sa2kit:mikuFusionGame:bestScore',\n 0\n );\n\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const rafRef = useRef<number | null>(null);\n const lastTsRef = useRef<number>(0);\n const idRef = useRef<number>(0);\n const orbsRef = useRef<FusionOrb[]>([]);\n const aimXRef = useRef<number>(config.width / 2);\n const scoreRef = useRef<number>(0);\n\n const [status, setStatus] = useState<MikuFusionGameStatus>('ready');\n const [score, setScore] = useState(0);\n const [nextLevel, setNextLevel] = useState(() => nextOrbLevel(config.spawnWeights));\n\n const draw = useCallback(\n (nextStatus: MikuFusionGameStatus = status) => {\n const canvas = canvasRef.current;\n if (!canvas) {\n return;\n }\n\n const context = canvas.getContext('2d');\n if (!context) {\n return;\n }\n\n drawScene(\n context,\n config.width,\n config.height,\n config,\n orbsRef.current,\n aimXRef.current,\n nextLevel,\n nextStatus\n );\n },\n [config, nextLevel, status]\n );\n\n const transitionStatus = useCallback((nextStatus: MikuFusionGameStatus) => {\n setStatus((previous) => (canTransition(previous, nextStatus) ? nextStatus : previous));\n }, []);\n\n const spawnOrb = useCallback(() => {\n if (status === 'paused' || status === 'gameOver') {\n return;\n }\n\n if (status === 'ready') {\n transitionStatus('playing');\n }\n\n idRef.current += 1;\n const radius = getRadiusByLevel(nextLevel);\n const x = clamp(aimXRef.current, radius, config.width - radius);\n const created: FusionOrb = {\n id: `${idRef.current}`,\n x,\n y: config.spawnY,\n vx: 0,\n vy: 0,\n radius,\n level: nextLevel,\n age: 0,\n };\n\n const nextOrbs = orbsRef.current.concat(created);\n orbsRef.current = nextOrbs.slice(-config.maxOrbs);\n\n setNextLevel(nextOrbLevel(config.spawnWeights));\n }, [config, nextLevel, status, transitionStatus]);\n\n const restart = useCallback(() => {\n orbsRef.current = [];\n scoreRef.current = 0;\n setScore(0);\n setNextLevel(nextOrbLevel(config.spawnWeights));\n transitionStatus('ready');\n draw('ready');\n }, [config.spawnWeights, draw, transitionStatus]);\n\n const togglePause = useCallback(() => {\n setStatus((previous) => {\n if (previous === 'playing' && canTransition(previous, 'paused')) {\n return 'paused';\n }\n if (previous === 'paused' && canTransition(previous, 'playing')) {\n return 'playing';\n }\n return previous;\n });\n }, []);\n\n const setAimFromClientX = useCallback((clientX: number, rect: DOMRect) => {\n const ratio = config.width / rect.width;\n const x = (clientX - rect.left) * ratio;\n aimXRef.current = clamp(x, 0, config.width);\n }, [config.width]);\n\n const handleDrop = useCallback(\n (clientX: number, rect: DOMRect) => {\n setAimFromClientX(clientX, rect);\n spawnOrb();\n },\n [setAimFromClientX, spawnOrb]\n );\n\n useEffect(() => {\n draw(status);\n }, [draw, status]);\n\n useEffect(() => {\n if (status !== 'playing') {\n if (rafRef.current) {\n window.cancelAnimationFrame(rafRef.current);\n }\n lastTsRef.current = 0;\n draw(status);\n return;\n }\n\n const frame = (timestamp: number) => {\n if (lastTsRef.current === 0) {\n lastTsRef.current = timestamp;\n }\n\n const dt = Math.min((timestamp - lastTsRef.current) / 1000, 0.033);\n lastTsRef.current = timestamp;\n\n let orbs = stepPhysics(orbsRef.current, config, dt);\n orbs = resolveCircleCollisions(orbs, config);\n\n const merged = mergeSameLevelOrbs(orbs, config);\n orbs = merged.orbs;\n orbsRef.current = orbs.slice(-config.maxOrbs);\n\n if (merged.scoreGain > 0) {\n scoreRef.current += merged.scoreGain;\n setScore(scoreRef.current);\n onScoreChangeRef.current?.(scoreRef.current);\n }\n\n const gameOver = orbs.some(\n (orb) =>\n orb.age > config.gameOverAgeThreshold &&\n orb.y - orb.radius <= config.lossLineY &&\n Math.abs(orb.vy) < 90\n );\n\n if (gameOver) {\n transitionStatus('gameOver');\n const latestBest = Math.max(bestScore, scoreRef.current);\n if (latestBest !== bestScore) {\n setBestScore(latestBest);\n }\n onGameOverRef.current?.(scoreRef.current, latestBest);\n draw('gameOver');\n return;\n }\n\n draw('playing');\n rafRef.current = window.requestAnimationFrame(frame);\n };\n\n rafRef.current = window.requestAnimationFrame(frame);\n\n return () => {\n if (rafRef.current) {\n window.cancelAnimationFrame(rafRef.current);\n }\n };\n }, [\n bestScore,\n config,\n draw,\n setBestScore,\n status,\n transitionStatus,\n ]);\n\n useEffect(() => {\n if (score > bestScore) {\n setBestScore(score);\n }\n }, [bestScore, score, setBestScore]);\n\n return {\n canvasRef,\n status,\n score,\n bestScore: Math.max(bestScore, score),\n nextLevel,\n config,\n setAimFromClientX,\n handleDrop,\n togglePause,\n restart,\n };\n}\n","'use client';\n\nimport { useEffect, useState } from 'react';\nimport type { RefObject } from 'react';\n\ninterface ResponsiveSize {\n displayWidth: number;\n displayHeight: number;\n scale: number;\n}\n\nexport function useResponsiveCanvas(\n logicalWidth: number,\n logicalHeight: number,\n containerRef: RefObject<HTMLElement>\n): ResponsiveSize {\n const [size, setSize] = useState<ResponsiveSize>({\n displayWidth: logicalWidth,\n displayHeight: logicalHeight,\n scale: 1,\n });\n\n useEffect(() => {\n const updateSize = () => {\n const container = containerRef.current;\n if (!container || typeof window === 'undefined') {\n return;\n }\n\n const rect = container.getBoundingClientRect();\n const maxWidth = Math.max(280, rect.width);\n const maxHeight = Math.max(420, Math.floor(window.innerHeight * 0.78));\n const scale = Math.min(maxWidth / logicalWidth, maxHeight / logicalHeight, 1);\n\n setSize({\n displayWidth: Math.floor(logicalWidth * scale),\n displayHeight: Math.floor(logicalHeight * scale),\n scale,\n });\n };\n\n updateSize();\n\n const container = containerRef.current;\n const observer =\n typeof ResizeObserver !== 'undefined' ? new ResizeObserver(updateSize) : null;\n if (container && observer) {\n observer.observe(container);\n }\n\n window.addEventListener('resize', updateSize);\n\n return () => {\n observer?.disconnect();\n window.removeEventListener('resize', updateSize);\n };\n }, [containerRef, logicalWidth, logicalHeight]);\n\n return size;\n}\n","import React from 'react';\nimport type { PointerEvent, RefObject } from 'react';\n\ninterface GameCanvasProps {\n canvasRef: RefObject<HTMLCanvasElement>;\n width: number;\n height: number;\n displayWidth: number;\n displayHeight: number;\n onPointerMove: (event: PointerEvent<HTMLCanvasElement>) => void;\n onPointerDown: (event: PointerEvent<HTMLCanvasElement>) => void;\n onPointerUp: (event: PointerEvent<HTMLCanvasElement>) => void;\n}\n\nexport function GameCanvas({\n canvasRef,\n width,\n height,\n displayWidth,\n displayHeight,\n onPointerMove,\n onPointerDown,\n onPointerUp,\n}: GameCanvasProps) {\n return (\n <canvas\n ref={canvasRef}\n width={width}\n height={height}\n className=\"rounded-xl border border-cyan-200 bg-cyan-50 shadow-sm\"\n style={{\n width: `${displayWidth}px`,\n height: `${displayHeight}px`,\n maxWidth: '100%',\n touchAction: 'none',\n }}\n onPointerMove={onPointerMove}\n onPointerDown={onPointerDown}\n onPointerUp={onPointerUp}\n onContextMenu={(event) => event.preventDefault()}\n />\n );\n}\n","import React from 'react';\n\ninterface GameControlsProps {\n isPaused: boolean;\n isPlaying: boolean;\n onTogglePause: () => void;\n onRestart: () => void;\n}\n\nexport function GameControls({ isPaused, isPlaying, onTogglePause, onRestart }: GameControlsProps) {\n return (\n <div className=\"grid grid-cols-2 gap-2\">\n <button\n type=\"button\"\n className=\"rounded-lg bg-cyan-600 px-4 py-3 text-sm font-semibold text-white disabled:cursor-not-allowed disabled:opacity-50\"\n onClick={onTogglePause}\n disabled={!isPlaying}\n >\n {isPaused ? '继续' : '暂停'}\n </button>\n <button\n type=\"button\"\n className=\"rounded-lg bg-emerald-600 px-4 py-3 text-sm font-semibold text-white\"\n onClick={onRestart}\n >\n 重开\n </button>\n </div>\n );\n}\n\n","import React from 'react';\n\ninterface GameHUDProps {\n score: number;\n bestScore: number;\n nextLevel: number;\n statusText: string;\n}\n\nexport function GameHUD({ score, bestScore, nextLevel, statusText }: GameHUDProps) {\n return (\n <div className=\"flex items-center justify-between gap-2 rounded-lg border border-cyan-200 bg-white/80 p-3\">\n <div className=\"min-w-0\">\n <div className=\"text-xs text-slate-500\">当前分数</div>\n <div className=\"text-xl font-bold text-cyan-700\">{score}</div>\n <div className=\"text-xs text-slate-500\">最高分 {bestScore}</div>\n </div>\n <div className=\"text-right\">\n <div className=\"text-xs text-slate-500\">下一个</div>\n <div className=\"text-base font-semibold text-emerald-700\">M{nextLevel}</div>\n <div className=\"text-xs font-medium text-slate-600\">{statusText}</div>\n </div>\n </div>\n );\n}\n\n","import React from 'react';\n\ninterface GameResultModalProps {\n open: boolean;\n score: number;\n bestScore: number;\n onRestart: () => void;\n}\n\nexport function GameResultModal({ open, score, bestScore, onRestart }: GameResultModalProps) {\n if (!open) {\n return null;\n }\n\n return (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center bg-slate-900/50 p-4\">\n <div className=\"pointer-events-auto w-full max-w-xs rounded-xl bg-white p-5 shadow-2xl\">\n <h3 className=\"text-lg font-semibold text-slate-900\">游戏结束</h3>\n <p className=\"mt-2 text-sm text-slate-600\">当前分数:{score}</p>\n <p className=\"text-sm text-slate-600\">最高分:{bestScore}</p>\n <button\n type=\"button\"\n className=\"mt-4 w-full rounded-lg bg-cyan-600 px-4 py-2 text-sm font-semibold text-white\"\n onClick={onRestart}\n >\n 再来一局\n </button>\n </div>\n </div>\n );\n}\n\n","'use client';\n\nimport React, { useMemo, useRef } from 'react';\nimport type { MikuFusionGameCallbacks, MikuFusionGameConfig } from '../types';\nimport { useMikuFusionGame } from '../hooks/useMikuFusionGame';\nimport { useResponsiveCanvas } from '../hooks/useResponsiveCanvas';\nimport { GameCanvas } from './GameCanvas';\nimport { GameControls } from './GameControls';\nimport { GameHUD } from './GameHUD';\nimport { GameResultModal } from './GameResultModal';\n\nexport interface MikuFusionGameProps extends Partial<MikuFusionGameConfig>, MikuFusionGameCallbacks {\n className?: string;\n storageKey?: string;\n}\n\nexport function MikuFusionGame({ className, storageKey, ...options }: MikuFusionGameProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const {\n canvasRef,\n status,\n score,\n bestScore,\n nextLevel,\n config,\n setAimFromClientX,\n handleDrop,\n togglePause,\n restart,\n } = useMikuFusionGame({ ...options, storageKey });\n\n const { displayWidth, displayHeight } = useResponsiveCanvas(\n config.width,\n config.height,\n containerRef\n );\n\n const statusText = useMemo(() => {\n if (status === 'ready') {\n return '待开始';\n }\n if (status === 'playing') {\n return '进行中';\n }\n if (status === 'paused') {\n return '已暂停';\n }\n return '已结束';\n }, [status]);\n\n const handlePointerMove = (event: React.PointerEvent<HTMLCanvasElement>) => {\n const rect = event.currentTarget.getBoundingClientRect();\n setAimFromClientX(event.clientX, rect);\n };\n\n const handlePointerDown = (event: React.PointerEvent<HTMLCanvasElement>) => {\n event.currentTarget.setPointerCapture(event.pointerId);\n const rect = event.currentTarget.getBoundingClientRect();\n setAimFromClientX(event.clientX, rect);\n };\n\n const handlePointerUp = (event: React.PointerEvent<HTMLCanvasElement>) => {\n const rect = event.currentTarget.getBoundingClientRect();\n handleDrop(event.clientX, rect);\n event.currentTarget.releasePointerCapture(event.pointerId);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key.toLowerCase() === 'r') {\n restart();\n }\n if (event.key.toLowerCase() === 'p') {\n togglePause();\n }\n };\n\n return (\n <div\n ref={containerRef}\n tabIndex={0}\n onKeyDown={handleKeyDown}\n className={`relative mx-auto flex w-full max-w-xl flex-col gap-3 p-3 md:p-4 ${className || ''}`}\n style={{\n paddingBottom: 'max(0.75rem, env(safe-area-inset-bottom))',\n }}\n >\n <GameHUD score={score} bestScore={bestScore} nextLevel={nextLevel} statusText={statusText} />\n\n <div className=\"relative mx-auto\">\n <GameCanvas\n canvasRef={canvasRef}\n width={config.width}\n height={config.height}\n displayWidth={displayWidth}\n displayHeight={displayHeight}\n onPointerMove={handlePointerMove}\n onPointerDown={handlePointerDown}\n onPointerUp={handlePointerUp}\n />\n <GameResultModal open={status === 'gameOver'} score={score} bestScore={bestScore} onRestart={restart} />\n </div>\n\n <GameControls\n isPaused={status === 'paused'}\n isPlaying={status === 'playing' || status === 'paused'}\n onTogglePause={togglePause}\n onRestart={restart}\n />\n </div>\n );\n}\n\n","import type { MikuFusionContentRegistry } from './types';\n\nexport type * from './types';\n\n/**\n * 仅作为未来内容包化扩展占位。\n * 当前基础玩法不会消费这些数据。\n */\nexport const defaultContentRegistry: MikuFusionContentRegistry = {\n producers: [],\n songs: [],\n themes: [],\n};\n\n"]}
@@ -126,7 +126,7 @@ function canMerge(a, b, config) {
126
126
  const dx = b.x - a.x;
127
127
  const dy = b.y - a.y;
128
128
  const distance = Math.sqrt(dx * dx + dy * dy);
129
- const threshold = (a.radius + b.radius) * 0.92;
129
+ const threshold = a.radius + b.radius + 0.75;
130
130
  return distance <= threshold;
131
131
  }
132
132
  function mergeSameLevelOrbs(orbs, config) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mikuFusionGame/constants.ts","../../src/mikuFusionGame/engine/collision.ts","../../src/mikuFusionGame/engine/scoring.ts","../../src/mikuFusionGame/engine/physics.ts","../../src/mikuFusionGame/engine/merge.ts","../../src/mikuFusionGame/engine/stateMachine.ts","../../src/mikuFusionGame/hooks/useMikuFusionGame.ts","../../src/mikuFusionGame/hooks/useResponsiveCanvas.ts","../../src/mikuFusionGame/components/GameCanvas.tsx","../../src/mikuFusionGame/components/GameControls.tsx","../../src/mikuFusionGame/components/GameHUD.tsx","../../src/mikuFusionGame/components/GameResultModal.tsx","../../src/mikuFusionGame/components/MikuFusionGame.tsx","../../src/mikuFusionGame/content/index.ts"],"names":["useState","useEffect","container","React","useRef"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { MikuFusionGameConfig } from './types';\n\nexport const BASE_RADIUS = 22;\nexport const RADIUS_STEP = 4;\n\nexport const LEVEL_LABEL_PREFIX = 'M';\n\nexport const DEFAULT_MIKU_FUSION_CONFIG: MikuFusionGameConfig = {\n width: 390,\n height: 700,\n gravity: 1450,\n damping: 0.995,\n collisionDamping: 0.92,\n spawnY: 82,\n lossLineY: 132,\n maxLevel: 10,\n maxOrbs: 90,\n maxMergesPerTick: 6,\n gameOverAgeThreshold: 1.1,\n spawnWeights: [0.62, 0.28, 0.1],\n theme: {\n backgroundTop: '#dafaff',\n backgroundBottom: '#86e5ef',\n aimLine: '#14b8a6',\n lossLine: '#ef4444',\n orbColors: [\n '#67e8f9',\n '#22d3ee',\n '#2dd4bf',\n '#5eead4',\n '#34d399',\n '#a7f3d0',\n '#99f6e4',\n '#0ea5e9',\n '#06b6d4',\n '#14b8a6',\n ],\n },\n};\n\n","import type { FusionOrb, MikuFusionGameConfig } from '../types';\n\nexport function resolveCircleCollisions(\n orbs: FusionOrb[],\n config: MikuFusionGameConfig\n): FusionOrb[] {\n const next = orbs.map((orb) => ({ ...orb }));\n\n for (let i = 0; i < next.length; i += 1) {\n for (let j = i + 1; j < next.length; j += 1) {\n const a = next[i];\n const b = next[j];\n\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const distance = Math.sqrt(dx * dx + dy * dy) || 0.0001;\n const minDistance = a.radius + b.radius;\n\n if (distance >= minDistance) {\n continue;\n }\n\n const nx = dx / distance;\n const ny = dy / distance;\n const overlap = minDistance - distance;\n\n a.x -= nx * overlap * 0.5;\n a.y -= ny * overlap * 0.5;\n b.x += nx * overlap * 0.5;\n b.y += ny * overlap * 0.5;\n\n const rvx = b.vx - a.vx;\n const rvy = b.vy - a.vy;\n const velocityAlongNormal = rvx * nx + rvy * ny;\n\n if (velocityAlongNormal > 0) {\n continue;\n }\n\n const restitution = config.collisionDamping;\n const impulse = (-(1 + restitution) * velocityAlongNormal) / 2;\n const impulseX = impulse * nx;\n const impulseY = impulse * ny;\n\n a.vx -= impulseX;\n a.vy -= impulseY;\n b.vx += impulseX;\n b.vy += impulseY;\n }\n }\n\n return next;\n}\n\n","export function getMergeScore(newLevel: number, chainIndex: number): number {\n const base = 10 * Math.max(1, newLevel) * Math.max(1, newLevel);\n const chainMultiplier = 1 + Math.max(0, chainIndex - 1) * 0.15;\n return Math.round(base * chainMultiplier);\n}\n\n","import { BASE_RADIUS, RADIUS_STEP } from '../constants';\nimport type { FusionOrb, MikuFusionGameConfig } from '../types';\n\nexport function getRadiusByLevel(level: number): number {\n return BASE_RADIUS + (Math.max(1, level) - 1) * RADIUS_STEP;\n}\n\nexport function stepPhysics(\n orbs: FusionOrb[],\n config: MikuFusionGameConfig,\n dt: number\n): FusionOrb[] {\n return orbs.map((orb) => {\n const next = { ...orb };\n\n next.vy += config.gravity * dt;\n next.vx *= config.damping;\n next.vy *= config.damping;\n\n next.x += next.vx * dt;\n next.y += next.vy * dt;\n next.age += dt;\n\n if (next.x - next.radius < 0) {\n next.x = next.radius;\n next.vx = Math.abs(next.vx) * config.collisionDamping;\n } else if (next.x + next.radius > config.width) {\n next.x = config.width - next.radius;\n next.vx = -Math.abs(next.vx) * config.collisionDamping;\n }\n\n if (next.y + next.radius > config.height) {\n next.y = config.height - next.radius;\n next.vy = -Math.abs(next.vy) * config.collisionDamping;\n }\n\n return next;\n });\n}\n\n","import type { FusionOrb, MergeResult, MikuFusionGameConfig } from '../types';\nimport { getMergeScore } from './scoring';\nimport { getRadiusByLevel } from './physics';\n\nfunction canMerge(a: FusionOrb, b: FusionOrb, config: MikuFusionGameConfig): boolean {\n if (a.level !== b.level) {\n return false;\n }\n\n if (a.level >= config.maxLevel) {\n return false;\n }\n\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n const threshold = (a.radius + b.radius) * 0.92;\n\n return distance <= threshold;\n}\n\nexport function mergeSameLevelOrbs(\n orbs: FusionOrb[],\n config: MikuFusionGameConfig\n): MergeResult {\n const mergedIds = new Set<string>();\n const spawned: FusionOrb[] = [];\n let scoreGain = 0;\n let chainIndex = 0;\n\n for (let i = 0; i < orbs.length; i += 1) {\n if (mergedIds.has(orbs[i].id)) {\n continue;\n }\n\n for (let j = i + 1; j < orbs.length; j += 1) {\n if (mergedIds.has(orbs[j].id)) {\n continue;\n }\n\n const a = orbs[i];\n const b = orbs[j];\n\n if (!canMerge(a, b, config)) {\n continue;\n }\n\n mergedIds.add(a.id);\n mergedIds.add(b.id);\n chainIndex += 1;\n\n const nextLevel = Math.min(config.maxLevel, a.level + 1);\n const mergedOrb: FusionOrb = {\n id: `orb-${a.id}-${b.id}-${chainIndex}`,\n x: (a.x + b.x) / 2,\n y: (a.y + b.y) / 2,\n vx: (a.vx + b.vx) / 2 * 0.4,\n vy: (a.vy + b.vy) / 2 * 0.4,\n radius: getRadiusByLevel(nextLevel),\n level: nextLevel,\n age: Math.min(a.age, b.age),\n };\n\n spawned.push(mergedOrb);\n scoreGain += getMergeScore(nextLevel, chainIndex);\n\n if (chainIndex >= config.maxMergesPerTick) {\n break;\n }\n }\n\n if (chainIndex >= config.maxMergesPerTick) {\n break;\n }\n }\n\n if (mergedIds.size === 0) {\n return {\n orbs,\n scoreGain: 0,\n mergeCount: 0,\n };\n }\n\n const survivors = orbs.filter((orb) => !mergedIds.has(orb.id));\n const mergedOrbs = survivors.concat(spawned);\n\n return {\n orbs: mergedOrbs,\n scoreGain,\n mergeCount: chainIndex,\n };\n}\n\n","import type { MikuFusionGameStatus } from '../types';\n\nconst ALLOWED_TRANSITIONS: Record<MikuFusionGameStatus, MikuFusionGameStatus[]> = {\n ready: ['playing'],\n playing: ['paused', 'gameOver', 'ready'],\n paused: ['playing', 'ready'],\n gameOver: ['ready', 'playing'],\n};\n\nexport function canTransition(\n from: MikuFusionGameStatus,\n to: MikuFusionGameStatus\n): boolean {\n return ALLOWED_TRANSITIONS[from].includes(to);\n}\n\n","'use client';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { RefObject } from 'react';\nimport { useLocalStorage } from '../../storage/hooks/useLocalStorage';\nimport { DEFAULT_MIKU_FUSION_CONFIG, LEVEL_LABEL_PREFIX } from '../constants';\nimport { resolveCircleCollisions } from '../engine/collision';\nimport { mergeSameLevelOrbs } from '../engine/merge';\nimport { getRadiusByLevel, stepPhysics } from '../engine/physics';\nimport { canTransition } from '../engine/stateMachine';\nimport type {\n FusionOrb,\n MikuFusionGameCallbacks,\n MikuFusionGameConfig,\n MikuFusionGameStatus,\n} from '../types';\n\nexport interface UseMikuFusionGameOptions extends Partial<MikuFusionGameConfig>, MikuFusionGameCallbacks {\n storageKey?: string;\n}\n\nexport interface UseMikuFusionGameResult {\n canvasRef: RefObject<HTMLCanvasElement>;\n status: MikuFusionGameStatus;\n score: number;\n bestScore: number;\n nextLevel: number;\n config: MikuFusionGameConfig;\n setAimFromClientX: (clientX: number, rect: DOMRect) => void;\n handleDrop: (clientX: number, rect: DOMRect) => void;\n togglePause: () => void;\n restart: () => void;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction nextOrbLevel(weights: number[]): number {\n const random = Math.random();\n let cumulative = 0;\n\n for (let i = 0; i < weights.length; i += 1) {\n cumulative += weights[i] ?? 0;\n if (random <= cumulative) {\n return i + 1;\n }\n }\n\n return Math.max(1, weights.length);\n}\n\nfunction getOrbColor(level: number, config: MikuFusionGameConfig): string {\n const index = Math.max(0, Math.min(config.theme.orbColors.length - 1, level - 1));\n return config.theme.orbColors[index] || '#22d3ee';\n}\n\nfunction drawScene(\n context: CanvasRenderingContext2D,\n width: number,\n height: number,\n config: MikuFusionGameConfig,\n orbs: FusionOrb[],\n aimX: number,\n nextLevel: number,\n status: MikuFusionGameStatus\n): void {\n const gradient = context.createLinearGradient(0, 0, 0, height);\n gradient.addColorStop(0, config.theme.backgroundTop);\n gradient.addColorStop(1, config.theme.backgroundBottom);\n context.fillStyle = gradient;\n context.fillRect(0, 0, width, height);\n\n context.lineWidth = 2;\n context.strokeStyle = config.theme.lossLine;\n context.setLineDash([6, 6]);\n context.beginPath();\n context.moveTo(0, config.lossLineY);\n context.lineTo(width, config.lossLineY);\n context.stroke();\n context.setLineDash([]);\n\n context.strokeStyle = config.theme.aimLine;\n context.lineWidth = 1.5;\n context.beginPath();\n context.moveTo(aimX, 0);\n context.lineTo(aimX, config.spawnY);\n context.stroke();\n\n const previewRadius = getRadiusByLevel(nextLevel);\n context.fillStyle = getOrbColor(nextLevel, config);\n context.beginPath();\n context.arc(aimX, config.spawnY - previewRadius - 4, previewRadius, 0, Math.PI * 2);\n context.fill();\n\n orbs.forEach((orb) => {\n context.beginPath();\n context.fillStyle = getOrbColor(orb.level, config);\n context.arc(orb.x, orb.y, orb.radius, 0, Math.PI * 2);\n context.fill();\n\n context.fillStyle = '#0f172a';\n context.font = 'bold 12px system-ui';\n context.textAlign = 'center';\n context.textBaseline = 'middle';\n context.fillText(`${LEVEL_LABEL_PREFIX}${orb.level}`, orb.x, orb.y);\n });\n\n if (status === 'paused') {\n context.fillStyle = 'rgba(15, 23, 42, 0.5)';\n context.fillRect(0, 0, width, height);\n context.fillStyle = '#ffffff';\n context.font = 'bold 30px system-ui';\n context.textAlign = 'center';\n context.fillText('Paused', width / 2, height / 2);\n }\n}\n\nfunction normalizeConfig(config?: Partial<MikuFusionGameConfig>): MikuFusionGameConfig {\n const mergedTheme = {\n ...DEFAULT_MIKU_FUSION_CONFIG.theme,\n ...(config?.theme ?? {}),\n };\n\n const merged = {\n ...DEFAULT_MIKU_FUSION_CONFIG,\n ...(config ?? {}),\n theme: mergedTheme,\n };\n\n const totalWeight = merged.spawnWeights.reduce((sum, current) => sum + current, 0);\n if (totalWeight <= 0) {\n merged.spawnWeights = [...DEFAULT_MIKU_FUSION_CONFIG.spawnWeights];\n } else if (Math.abs(totalWeight - 1) > 0.001) {\n merged.spawnWeights = merged.spawnWeights.map((weight) => weight / totalWeight);\n }\n\n return merged;\n}\n\nexport function useMikuFusionGame(options: UseMikuFusionGameOptions = {}): UseMikuFusionGameResult {\n const configRef = useRef<MikuFusionGameConfig>(normalizeConfig(options));\n const config = configRef.current;\n const onScoreChangeRef = useRef(options.onScoreChange);\n const onGameOverRef = useRef(options.onGameOver);\n\n useEffect(() => {\n onScoreChangeRef.current = options.onScoreChange;\n onGameOverRef.current = options.onGameOver;\n }, [options.onGameOver, options.onScoreChange]);\n\n const [bestScore, setBestScore] = useLocalStorage<number>(\n options.storageKey || 'sa2kit:mikuFusionGame:bestScore',\n 0\n );\n\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const rafRef = useRef<number | null>(null);\n const lastTsRef = useRef<number>(0);\n const idRef = useRef<number>(0);\n const orbsRef = useRef<FusionOrb[]>([]);\n const aimXRef = useRef<number>(config.width / 2);\n const scoreRef = useRef<number>(0);\n\n const [status, setStatus] = useState<MikuFusionGameStatus>('ready');\n const [score, setScore] = useState(0);\n const [nextLevel, setNextLevel] = useState(() => nextOrbLevel(config.spawnWeights));\n\n const draw = useCallback(\n (nextStatus: MikuFusionGameStatus = status) => {\n const canvas = canvasRef.current;\n if (!canvas) {\n return;\n }\n\n const context = canvas.getContext('2d');\n if (!context) {\n return;\n }\n\n drawScene(\n context,\n config.width,\n config.height,\n config,\n orbsRef.current,\n aimXRef.current,\n nextLevel,\n nextStatus\n );\n },\n [config, nextLevel, status]\n );\n\n const transitionStatus = useCallback((nextStatus: MikuFusionGameStatus) => {\n setStatus((previous) => (canTransition(previous, nextStatus) ? nextStatus : previous));\n }, []);\n\n const spawnOrb = useCallback(() => {\n if (status === 'paused' || status === 'gameOver') {\n return;\n }\n\n if (status === 'ready') {\n transitionStatus('playing');\n }\n\n idRef.current += 1;\n const radius = getRadiusByLevel(nextLevel);\n const x = clamp(aimXRef.current, radius, config.width - radius);\n const created: FusionOrb = {\n id: `${idRef.current}`,\n x,\n y: config.spawnY,\n vx: 0,\n vy: 0,\n radius,\n level: nextLevel,\n age: 0,\n };\n\n const nextOrbs = orbsRef.current.concat(created);\n orbsRef.current = nextOrbs.slice(-config.maxOrbs);\n\n setNextLevel(nextOrbLevel(config.spawnWeights));\n }, [config, nextLevel, status, transitionStatus]);\n\n const restart = useCallback(() => {\n orbsRef.current = [];\n scoreRef.current = 0;\n setScore(0);\n setNextLevel(nextOrbLevel(config.spawnWeights));\n transitionStatus('ready');\n draw('ready');\n }, [config.spawnWeights, draw, transitionStatus]);\n\n const togglePause = useCallback(() => {\n setStatus((previous) => {\n if (previous === 'playing' && canTransition(previous, 'paused')) {\n return 'paused';\n }\n if (previous === 'paused' && canTransition(previous, 'playing')) {\n return 'playing';\n }\n return previous;\n });\n }, []);\n\n const setAimFromClientX = useCallback((clientX: number, rect: DOMRect) => {\n const ratio = config.width / rect.width;\n const x = (clientX - rect.left) * ratio;\n aimXRef.current = clamp(x, 0, config.width);\n }, [config.width]);\n\n const handleDrop = useCallback(\n (clientX: number, rect: DOMRect) => {\n setAimFromClientX(clientX, rect);\n spawnOrb();\n },\n [setAimFromClientX, spawnOrb]\n );\n\n useEffect(() => {\n draw(status);\n }, [draw, status]);\n\n useEffect(() => {\n if (status !== 'playing') {\n if (rafRef.current) {\n window.cancelAnimationFrame(rafRef.current);\n }\n lastTsRef.current = 0;\n draw(status);\n return;\n }\n\n const frame = (timestamp: number) => {\n if (lastTsRef.current === 0) {\n lastTsRef.current = timestamp;\n }\n\n const dt = Math.min((timestamp - lastTsRef.current) / 1000, 0.033);\n lastTsRef.current = timestamp;\n\n let orbs = stepPhysics(orbsRef.current, config, dt);\n orbs = resolveCircleCollisions(orbs, config);\n\n const merged = mergeSameLevelOrbs(orbs, config);\n orbs = merged.orbs;\n orbsRef.current = orbs.slice(-config.maxOrbs);\n\n if (merged.scoreGain > 0) {\n scoreRef.current += merged.scoreGain;\n setScore(scoreRef.current);\n onScoreChangeRef.current?.(scoreRef.current);\n }\n\n const gameOver = orbs.some(\n (orb) =>\n orb.age > config.gameOverAgeThreshold &&\n orb.y - orb.radius <= config.lossLineY &&\n Math.abs(orb.vy) < 90\n );\n\n if (gameOver) {\n transitionStatus('gameOver');\n const latestBest = Math.max(bestScore, scoreRef.current);\n if (latestBest !== bestScore) {\n setBestScore(latestBest);\n }\n onGameOverRef.current?.(scoreRef.current, latestBest);\n draw('gameOver');\n return;\n }\n\n draw('playing');\n rafRef.current = window.requestAnimationFrame(frame);\n };\n\n rafRef.current = window.requestAnimationFrame(frame);\n\n return () => {\n if (rafRef.current) {\n window.cancelAnimationFrame(rafRef.current);\n }\n };\n }, [\n bestScore,\n config,\n draw,\n setBestScore,\n status,\n transitionStatus,\n ]);\n\n useEffect(() => {\n if (score > bestScore) {\n setBestScore(score);\n }\n }, [bestScore, score, setBestScore]);\n\n return {\n canvasRef,\n status,\n score,\n bestScore: Math.max(bestScore, score),\n nextLevel,\n config,\n setAimFromClientX,\n handleDrop,\n togglePause,\n restart,\n };\n}\n","'use client';\n\nimport { useEffect, useState } from 'react';\nimport type { RefObject } from 'react';\n\ninterface ResponsiveSize {\n displayWidth: number;\n displayHeight: number;\n scale: number;\n}\n\nexport function useResponsiveCanvas(\n logicalWidth: number,\n logicalHeight: number,\n containerRef: RefObject<HTMLElement>\n): ResponsiveSize {\n const [size, setSize] = useState<ResponsiveSize>({\n displayWidth: logicalWidth,\n displayHeight: logicalHeight,\n scale: 1,\n });\n\n useEffect(() => {\n const updateSize = () => {\n const container = containerRef.current;\n if (!container || typeof window === 'undefined') {\n return;\n }\n\n const rect = container.getBoundingClientRect();\n const maxWidth = Math.max(280, rect.width);\n const maxHeight = Math.max(420, Math.floor(window.innerHeight * 0.78));\n const scale = Math.min(maxWidth / logicalWidth, maxHeight / logicalHeight, 1);\n\n setSize({\n displayWidth: Math.floor(logicalWidth * scale),\n displayHeight: Math.floor(logicalHeight * scale),\n scale,\n });\n };\n\n updateSize();\n\n const container = containerRef.current;\n const observer =\n typeof ResizeObserver !== 'undefined' ? new ResizeObserver(updateSize) : null;\n if (container && observer) {\n observer.observe(container);\n }\n\n window.addEventListener('resize', updateSize);\n\n return () => {\n observer?.disconnect();\n window.removeEventListener('resize', updateSize);\n };\n }, [containerRef, logicalWidth, logicalHeight]);\n\n return size;\n}\n","import React from 'react';\nimport type { PointerEvent, RefObject } from 'react';\n\ninterface GameCanvasProps {\n canvasRef: RefObject<HTMLCanvasElement>;\n width: number;\n height: number;\n displayWidth: number;\n displayHeight: number;\n onPointerMove: (event: PointerEvent<HTMLCanvasElement>) => void;\n onPointerDown: (event: PointerEvent<HTMLCanvasElement>) => void;\n onPointerUp: (event: PointerEvent<HTMLCanvasElement>) => void;\n}\n\nexport function GameCanvas({\n canvasRef,\n width,\n height,\n displayWidth,\n displayHeight,\n onPointerMove,\n onPointerDown,\n onPointerUp,\n}: GameCanvasProps) {\n return (\n <canvas\n ref={canvasRef}\n width={width}\n height={height}\n className=\"rounded-xl border border-cyan-200 bg-cyan-50 shadow-sm\"\n style={{\n width: `${displayWidth}px`,\n height: `${displayHeight}px`,\n maxWidth: '100%',\n touchAction: 'none',\n }}\n onPointerMove={onPointerMove}\n onPointerDown={onPointerDown}\n onPointerUp={onPointerUp}\n onContextMenu={(event) => event.preventDefault()}\n />\n );\n}\n","import React from 'react';\n\ninterface GameControlsProps {\n isPaused: boolean;\n isPlaying: boolean;\n onTogglePause: () => void;\n onRestart: () => void;\n}\n\nexport function GameControls({ isPaused, isPlaying, onTogglePause, onRestart }: GameControlsProps) {\n return (\n <div className=\"grid grid-cols-2 gap-2\">\n <button\n type=\"button\"\n className=\"rounded-lg bg-cyan-600 px-4 py-3 text-sm font-semibold text-white disabled:cursor-not-allowed disabled:opacity-50\"\n onClick={onTogglePause}\n disabled={!isPlaying}\n >\n {isPaused ? '继续' : '暂停'}\n </button>\n <button\n type=\"button\"\n className=\"rounded-lg bg-emerald-600 px-4 py-3 text-sm font-semibold text-white\"\n onClick={onRestart}\n >\n 重开\n </button>\n </div>\n );\n}\n\n","import React from 'react';\n\ninterface GameHUDProps {\n score: number;\n bestScore: number;\n nextLevel: number;\n statusText: string;\n}\n\nexport function GameHUD({ score, bestScore, nextLevel, statusText }: GameHUDProps) {\n return (\n <div className=\"flex items-center justify-between gap-2 rounded-lg border border-cyan-200 bg-white/80 p-3\">\n <div className=\"min-w-0\">\n <div className=\"text-xs text-slate-500\">当前分数</div>\n <div className=\"text-xl font-bold text-cyan-700\">{score}</div>\n <div className=\"text-xs text-slate-500\">最高分 {bestScore}</div>\n </div>\n <div className=\"text-right\">\n <div className=\"text-xs text-slate-500\">下一个</div>\n <div className=\"text-base font-semibold text-emerald-700\">M{nextLevel}</div>\n <div className=\"text-xs font-medium text-slate-600\">{statusText}</div>\n </div>\n </div>\n );\n}\n\n","import React from 'react';\n\ninterface GameResultModalProps {\n open: boolean;\n score: number;\n bestScore: number;\n onRestart: () => void;\n}\n\nexport function GameResultModal({ open, score, bestScore, onRestart }: GameResultModalProps) {\n if (!open) {\n return null;\n }\n\n return (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center bg-slate-900/50 p-4\">\n <div className=\"pointer-events-auto w-full max-w-xs rounded-xl bg-white p-5 shadow-2xl\">\n <h3 className=\"text-lg font-semibold text-slate-900\">游戏结束</h3>\n <p className=\"mt-2 text-sm text-slate-600\">当前分数:{score}</p>\n <p className=\"text-sm text-slate-600\">最高分:{bestScore}</p>\n <button\n type=\"button\"\n className=\"mt-4 w-full rounded-lg bg-cyan-600 px-4 py-2 text-sm font-semibold text-white\"\n onClick={onRestart}\n >\n 再来一局\n </button>\n </div>\n </div>\n );\n}\n\n","'use client';\n\nimport React, { useMemo, useRef } from 'react';\nimport type { MikuFusionGameCallbacks, MikuFusionGameConfig } from '../types';\nimport { useMikuFusionGame } from '../hooks/useMikuFusionGame';\nimport { useResponsiveCanvas } from '../hooks/useResponsiveCanvas';\nimport { GameCanvas } from './GameCanvas';\nimport { GameControls } from './GameControls';\nimport { GameHUD } from './GameHUD';\nimport { GameResultModal } from './GameResultModal';\n\nexport interface MikuFusionGameProps extends Partial<MikuFusionGameConfig>, MikuFusionGameCallbacks {\n className?: string;\n storageKey?: string;\n}\n\nexport function MikuFusionGame({ className, storageKey, ...options }: MikuFusionGameProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const {\n canvasRef,\n status,\n score,\n bestScore,\n nextLevel,\n config,\n setAimFromClientX,\n handleDrop,\n togglePause,\n restart,\n } = useMikuFusionGame({ ...options, storageKey });\n\n const { displayWidth, displayHeight } = useResponsiveCanvas(\n config.width,\n config.height,\n containerRef\n );\n\n const statusText = useMemo(() => {\n if (status === 'ready') {\n return '待开始';\n }\n if (status === 'playing') {\n return '进行中';\n }\n if (status === 'paused') {\n return '已暂停';\n }\n return '已结束';\n }, [status]);\n\n const handlePointerMove = (event: React.PointerEvent<HTMLCanvasElement>) => {\n const rect = event.currentTarget.getBoundingClientRect();\n setAimFromClientX(event.clientX, rect);\n };\n\n const handlePointerDown = (event: React.PointerEvent<HTMLCanvasElement>) => {\n event.currentTarget.setPointerCapture(event.pointerId);\n const rect = event.currentTarget.getBoundingClientRect();\n setAimFromClientX(event.clientX, rect);\n };\n\n const handlePointerUp = (event: React.PointerEvent<HTMLCanvasElement>) => {\n const rect = event.currentTarget.getBoundingClientRect();\n handleDrop(event.clientX, rect);\n event.currentTarget.releasePointerCapture(event.pointerId);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key.toLowerCase() === 'r') {\n restart();\n }\n if (event.key.toLowerCase() === 'p') {\n togglePause();\n }\n };\n\n return (\n <div\n ref={containerRef}\n tabIndex={0}\n onKeyDown={handleKeyDown}\n className={`relative mx-auto flex w-full max-w-xl flex-col gap-3 p-3 md:p-4 ${className || ''}`}\n style={{\n paddingBottom: 'max(0.75rem, env(safe-area-inset-bottom))',\n }}\n >\n <GameHUD score={score} bestScore={bestScore} nextLevel={nextLevel} statusText={statusText} />\n\n <div className=\"relative mx-auto\">\n <GameCanvas\n canvasRef={canvasRef}\n width={config.width}\n height={config.height}\n displayWidth={displayWidth}\n displayHeight={displayHeight}\n onPointerMove={handlePointerMove}\n onPointerDown={handlePointerDown}\n onPointerUp={handlePointerUp}\n />\n <GameResultModal open={status === 'gameOver'} score={score} bestScore={bestScore} onRestart={restart} />\n </div>\n\n <GameControls\n isPaused={status === 'paused'}\n isPlaying={status === 'playing' || status === 'paused'}\n onTogglePause={togglePause}\n onRestart={restart}\n />\n </div>\n );\n}\n\n","import type { MikuFusionContentRegistry } from './types';\n\nexport type * from './types';\n\n/**\n * 仅作为未来内容包化扩展占位。\n * 当前基础玩法不会消费这些数据。\n */\nexport const defaultContentRegistry: MikuFusionContentRegistry = {\n producers: [],\n songs: [],\n themes: [],\n};\n\n"]}
1
+ {"version":3,"sources":["../../src/mikuFusionGame/constants.ts","../../src/mikuFusionGame/engine/collision.ts","../../src/mikuFusionGame/engine/scoring.ts","../../src/mikuFusionGame/engine/physics.ts","../../src/mikuFusionGame/engine/merge.ts","../../src/mikuFusionGame/engine/stateMachine.ts","../../src/mikuFusionGame/hooks/useMikuFusionGame.ts","../../src/mikuFusionGame/hooks/useResponsiveCanvas.ts","../../src/mikuFusionGame/components/GameCanvas.tsx","../../src/mikuFusionGame/components/GameControls.tsx","../../src/mikuFusionGame/components/GameHUD.tsx","../../src/mikuFusionGame/components/GameResultModal.tsx","../../src/mikuFusionGame/components/MikuFusionGame.tsx","../../src/mikuFusionGame/content/index.ts"],"names":["useState","useEffect","container","React","useRef"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { MikuFusionGameConfig } from './types';\n\nexport const BASE_RADIUS = 22;\nexport const RADIUS_STEP = 4;\n\nexport const LEVEL_LABEL_PREFIX = 'M';\n\nexport const DEFAULT_MIKU_FUSION_CONFIG: MikuFusionGameConfig = {\n width: 390,\n height: 700,\n gravity: 1450,\n damping: 0.995,\n collisionDamping: 0.92,\n spawnY: 82,\n lossLineY: 132,\n maxLevel: 10,\n maxOrbs: 90,\n maxMergesPerTick: 6,\n gameOverAgeThreshold: 1.1,\n spawnWeights: [0.62, 0.28, 0.1],\n theme: {\n backgroundTop: '#dafaff',\n backgroundBottom: '#86e5ef',\n aimLine: '#14b8a6',\n lossLine: '#ef4444',\n orbColors: [\n '#67e8f9',\n '#22d3ee',\n '#2dd4bf',\n '#5eead4',\n '#34d399',\n '#a7f3d0',\n '#99f6e4',\n '#0ea5e9',\n '#06b6d4',\n '#14b8a6',\n ],\n },\n};\n\n","import type { FusionOrb, MikuFusionGameConfig } from '../types';\n\nexport function resolveCircleCollisions(\n orbs: FusionOrb[],\n config: MikuFusionGameConfig\n): FusionOrb[] {\n const next = orbs.map((orb) => ({ ...orb }));\n\n for (let i = 0; i < next.length; i += 1) {\n for (let j = i + 1; j < next.length; j += 1) {\n const a = next[i];\n const b = next[j];\n\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const distance = Math.sqrt(dx * dx + dy * dy) || 0.0001;\n const minDistance = a.radius + b.radius;\n\n if (distance >= minDistance) {\n continue;\n }\n\n const nx = dx / distance;\n const ny = dy / distance;\n const overlap = minDistance - distance;\n\n a.x -= nx * overlap * 0.5;\n a.y -= ny * overlap * 0.5;\n b.x += nx * overlap * 0.5;\n b.y += ny * overlap * 0.5;\n\n const rvx = b.vx - a.vx;\n const rvy = b.vy - a.vy;\n const velocityAlongNormal = rvx * nx + rvy * ny;\n\n if (velocityAlongNormal > 0) {\n continue;\n }\n\n const restitution = config.collisionDamping;\n const impulse = (-(1 + restitution) * velocityAlongNormal) / 2;\n const impulseX = impulse * nx;\n const impulseY = impulse * ny;\n\n a.vx -= impulseX;\n a.vy -= impulseY;\n b.vx += impulseX;\n b.vy += impulseY;\n }\n }\n\n return next;\n}\n\n","export function getMergeScore(newLevel: number, chainIndex: number): number {\n const base = 10 * Math.max(1, newLevel) * Math.max(1, newLevel);\n const chainMultiplier = 1 + Math.max(0, chainIndex - 1) * 0.15;\n return Math.round(base * chainMultiplier);\n}\n\n","import { BASE_RADIUS, RADIUS_STEP } from '../constants';\nimport type { FusionOrb, MikuFusionGameConfig } from '../types';\n\nexport function getRadiusByLevel(level: number): number {\n return BASE_RADIUS + (Math.max(1, level) - 1) * RADIUS_STEP;\n}\n\nexport function stepPhysics(\n orbs: FusionOrb[],\n config: MikuFusionGameConfig,\n dt: number\n): FusionOrb[] {\n return orbs.map((orb) => {\n const next = { ...orb };\n\n next.vy += config.gravity * dt;\n next.vx *= config.damping;\n next.vy *= config.damping;\n\n next.x += next.vx * dt;\n next.y += next.vy * dt;\n next.age += dt;\n\n if (next.x - next.radius < 0) {\n next.x = next.radius;\n next.vx = Math.abs(next.vx) * config.collisionDamping;\n } else if (next.x + next.radius > config.width) {\n next.x = config.width - next.radius;\n next.vx = -Math.abs(next.vx) * config.collisionDamping;\n }\n\n if (next.y + next.radius > config.height) {\n next.y = config.height - next.radius;\n next.vy = -Math.abs(next.vy) * config.collisionDamping;\n }\n\n return next;\n });\n}\n\n","import type { FusionOrb, MergeResult, MikuFusionGameConfig } from '../types';\nimport { getMergeScore } from './scoring';\nimport { getRadiusByLevel } from './physics';\n\nfunction canMerge(a: FusionOrb, b: FusionOrb, config: MikuFusionGameConfig): boolean {\n if (a.level !== b.level) {\n return false;\n }\n\n if (a.level >= config.maxLevel) {\n return false;\n }\n\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n // Collision resolution keeps circles around exact touching distance.\n // Use a small epsilon so touching same-level orbs can merge reliably.\n const threshold = a.radius + b.radius + 0.75;\n\n return distance <= threshold;\n}\n\nexport function mergeSameLevelOrbs(\n orbs: FusionOrb[],\n config: MikuFusionGameConfig\n): MergeResult {\n const mergedIds = new Set<string>();\n const spawned: FusionOrb[] = [];\n let scoreGain = 0;\n let chainIndex = 0;\n\n for (let i = 0; i < orbs.length; i += 1) {\n if (mergedIds.has(orbs[i].id)) {\n continue;\n }\n\n for (let j = i + 1; j < orbs.length; j += 1) {\n if (mergedIds.has(orbs[j].id)) {\n continue;\n }\n\n const a = orbs[i];\n const b = orbs[j];\n\n if (!canMerge(a, b, config)) {\n continue;\n }\n\n mergedIds.add(a.id);\n mergedIds.add(b.id);\n chainIndex += 1;\n\n const nextLevel = Math.min(config.maxLevel, a.level + 1);\n const mergedOrb: FusionOrb = {\n id: `orb-${a.id}-${b.id}-${chainIndex}`,\n x: (a.x + b.x) / 2,\n y: (a.y + b.y) / 2,\n vx: (a.vx + b.vx) / 2 * 0.4,\n vy: (a.vy + b.vy) / 2 * 0.4,\n radius: getRadiusByLevel(nextLevel),\n level: nextLevel,\n age: Math.min(a.age, b.age),\n };\n\n spawned.push(mergedOrb);\n scoreGain += getMergeScore(nextLevel, chainIndex);\n\n if (chainIndex >= config.maxMergesPerTick) {\n break;\n }\n }\n\n if (chainIndex >= config.maxMergesPerTick) {\n break;\n }\n }\n\n if (mergedIds.size === 0) {\n return {\n orbs,\n scoreGain: 0,\n mergeCount: 0,\n };\n }\n\n const survivors = orbs.filter((orb) => !mergedIds.has(orb.id));\n const mergedOrbs = survivors.concat(spawned);\n\n return {\n orbs: mergedOrbs,\n scoreGain,\n mergeCount: chainIndex,\n };\n}\n","import type { MikuFusionGameStatus } from '../types';\n\nconst ALLOWED_TRANSITIONS: Record<MikuFusionGameStatus, MikuFusionGameStatus[]> = {\n ready: ['playing'],\n playing: ['paused', 'gameOver', 'ready'],\n paused: ['playing', 'ready'],\n gameOver: ['ready', 'playing'],\n};\n\nexport function canTransition(\n from: MikuFusionGameStatus,\n to: MikuFusionGameStatus\n): boolean {\n return ALLOWED_TRANSITIONS[from].includes(to);\n}\n\n","'use client';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { RefObject } from 'react';\nimport { useLocalStorage } from '../../storage/hooks/useLocalStorage';\nimport { DEFAULT_MIKU_FUSION_CONFIG, LEVEL_LABEL_PREFIX } from '../constants';\nimport { resolveCircleCollisions } from '../engine/collision';\nimport { mergeSameLevelOrbs } from '../engine/merge';\nimport { getRadiusByLevel, stepPhysics } from '../engine/physics';\nimport { canTransition } from '../engine/stateMachine';\nimport type {\n FusionOrb,\n MikuFusionGameCallbacks,\n MikuFusionGameConfig,\n MikuFusionGameStatus,\n} from '../types';\n\nexport interface UseMikuFusionGameOptions extends Partial<MikuFusionGameConfig>, MikuFusionGameCallbacks {\n storageKey?: string;\n}\n\nexport interface UseMikuFusionGameResult {\n canvasRef: RefObject<HTMLCanvasElement>;\n status: MikuFusionGameStatus;\n score: number;\n bestScore: number;\n nextLevel: number;\n config: MikuFusionGameConfig;\n setAimFromClientX: (clientX: number, rect: DOMRect) => void;\n handleDrop: (clientX: number, rect: DOMRect) => void;\n togglePause: () => void;\n restart: () => void;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction nextOrbLevel(weights: number[]): number {\n const random = Math.random();\n let cumulative = 0;\n\n for (let i = 0; i < weights.length; i += 1) {\n cumulative += weights[i] ?? 0;\n if (random <= cumulative) {\n return i + 1;\n }\n }\n\n return Math.max(1, weights.length);\n}\n\nfunction getOrbColor(level: number, config: MikuFusionGameConfig): string {\n const index = Math.max(0, Math.min(config.theme.orbColors.length - 1, level - 1));\n return config.theme.orbColors[index] || '#22d3ee';\n}\n\nfunction drawScene(\n context: CanvasRenderingContext2D,\n width: number,\n height: number,\n config: MikuFusionGameConfig,\n orbs: FusionOrb[],\n aimX: number,\n nextLevel: number,\n status: MikuFusionGameStatus\n): void {\n const gradient = context.createLinearGradient(0, 0, 0, height);\n gradient.addColorStop(0, config.theme.backgroundTop);\n gradient.addColorStop(1, config.theme.backgroundBottom);\n context.fillStyle = gradient;\n context.fillRect(0, 0, width, height);\n\n context.lineWidth = 2;\n context.strokeStyle = config.theme.lossLine;\n context.setLineDash([6, 6]);\n context.beginPath();\n context.moveTo(0, config.lossLineY);\n context.lineTo(width, config.lossLineY);\n context.stroke();\n context.setLineDash([]);\n\n context.strokeStyle = config.theme.aimLine;\n context.lineWidth = 1.5;\n context.beginPath();\n context.moveTo(aimX, 0);\n context.lineTo(aimX, config.spawnY);\n context.stroke();\n\n const previewRadius = getRadiusByLevel(nextLevel);\n context.fillStyle = getOrbColor(nextLevel, config);\n context.beginPath();\n context.arc(aimX, config.spawnY - previewRadius - 4, previewRadius, 0, Math.PI * 2);\n context.fill();\n\n orbs.forEach((orb) => {\n context.beginPath();\n context.fillStyle = getOrbColor(orb.level, config);\n context.arc(orb.x, orb.y, orb.radius, 0, Math.PI * 2);\n context.fill();\n\n context.fillStyle = '#0f172a';\n context.font = 'bold 12px system-ui';\n context.textAlign = 'center';\n context.textBaseline = 'middle';\n context.fillText(`${LEVEL_LABEL_PREFIX}${orb.level}`, orb.x, orb.y);\n });\n\n if (status === 'paused') {\n context.fillStyle = 'rgba(15, 23, 42, 0.5)';\n context.fillRect(0, 0, width, height);\n context.fillStyle = '#ffffff';\n context.font = 'bold 30px system-ui';\n context.textAlign = 'center';\n context.fillText('Paused', width / 2, height / 2);\n }\n}\n\nfunction normalizeConfig(config?: Partial<MikuFusionGameConfig>): MikuFusionGameConfig {\n const mergedTheme = {\n ...DEFAULT_MIKU_FUSION_CONFIG.theme,\n ...(config?.theme ?? {}),\n };\n\n const merged = {\n ...DEFAULT_MIKU_FUSION_CONFIG,\n ...(config ?? {}),\n theme: mergedTheme,\n };\n\n const totalWeight = merged.spawnWeights.reduce((sum, current) => sum + current, 0);\n if (totalWeight <= 0) {\n merged.spawnWeights = [...DEFAULT_MIKU_FUSION_CONFIG.spawnWeights];\n } else if (Math.abs(totalWeight - 1) > 0.001) {\n merged.spawnWeights = merged.spawnWeights.map((weight) => weight / totalWeight);\n }\n\n return merged;\n}\n\nexport function useMikuFusionGame(options: UseMikuFusionGameOptions = {}): UseMikuFusionGameResult {\n const configRef = useRef<MikuFusionGameConfig>(normalizeConfig(options));\n const config = configRef.current;\n const onScoreChangeRef = useRef(options.onScoreChange);\n const onGameOverRef = useRef(options.onGameOver);\n\n useEffect(() => {\n onScoreChangeRef.current = options.onScoreChange;\n onGameOverRef.current = options.onGameOver;\n }, [options.onGameOver, options.onScoreChange]);\n\n const [bestScore, setBestScore] = useLocalStorage<number>(\n options.storageKey || 'sa2kit:mikuFusionGame:bestScore',\n 0\n );\n\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const rafRef = useRef<number | null>(null);\n const lastTsRef = useRef<number>(0);\n const idRef = useRef<number>(0);\n const orbsRef = useRef<FusionOrb[]>([]);\n const aimXRef = useRef<number>(config.width / 2);\n const scoreRef = useRef<number>(0);\n\n const [status, setStatus] = useState<MikuFusionGameStatus>('ready');\n const [score, setScore] = useState(0);\n const [nextLevel, setNextLevel] = useState(() => nextOrbLevel(config.spawnWeights));\n\n const draw = useCallback(\n (nextStatus: MikuFusionGameStatus = status) => {\n const canvas = canvasRef.current;\n if (!canvas) {\n return;\n }\n\n const context = canvas.getContext('2d');\n if (!context) {\n return;\n }\n\n drawScene(\n context,\n config.width,\n config.height,\n config,\n orbsRef.current,\n aimXRef.current,\n nextLevel,\n nextStatus\n );\n },\n [config, nextLevel, status]\n );\n\n const transitionStatus = useCallback((nextStatus: MikuFusionGameStatus) => {\n setStatus((previous) => (canTransition(previous, nextStatus) ? nextStatus : previous));\n }, []);\n\n const spawnOrb = useCallback(() => {\n if (status === 'paused' || status === 'gameOver') {\n return;\n }\n\n if (status === 'ready') {\n transitionStatus('playing');\n }\n\n idRef.current += 1;\n const radius = getRadiusByLevel(nextLevel);\n const x = clamp(aimXRef.current, radius, config.width - radius);\n const created: FusionOrb = {\n id: `${idRef.current}`,\n x,\n y: config.spawnY,\n vx: 0,\n vy: 0,\n radius,\n level: nextLevel,\n age: 0,\n };\n\n const nextOrbs = orbsRef.current.concat(created);\n orbsRef.current = nextOrbs.slice(-config.maxOrbs);\n\n setNextLevel(nextOrbLevel(config.spawnWeights));\n }, [config, nextLevel, status, transitionStatus]);\n\n const restart = useCallback(() => {\n orbsRef.current = [];\n scoreRef.current = 0;\n setScore(0);\n setNextLevel(nextOrbLevel(config.spawnWeights));\n transitionStatus('ready');\n draw('ready');\n }, [config.spawnWeights, draw, transitionStatus]);\n\n const togglePause = useCallback(() => {\n setStatus((previous) => {\n if (previous === 'playing' && canTransition(previous, 'paused')) {\n return 'paused';\n }\n if (previous === 'paused' && canTransition(previous, 'playing')) {\n return 'playing';\n }\n return previous;\n });\n }, []);\n\n const setAimFromClientX = useCallback((clientX: number, rect: DOMRect) => {\n const ratio = config.width / rect.width;\n const x = (clientX - rect.left) * ratio;\n aimXRef.current = clamp(x, 0, config.width);\n }, [config.width]);\n\n const handleDrop = useCallback(\n (clientX: number, rect: DOMRect) => {\n setAimFromClientX(clientX, rect);\n spawnOrb();\n },\n [setAimFromClientX, spawnOrb]\n );\n\n useEffect(() => {\n draw(status);\n }, [draw, status]);\n\n useEffect(() => {\n if (status !== 'playing') {\n if (rafRef.current) {\n window.cancelAnimationFrame(rafRef.current);\n }\n lastTsRef.current = 0;\n draw(status);\n return;\n }\n\n const frame = (timestamp: number) => {\n if (lastTsRef.current === 0) {\n lastTsRef.current = timestamp;\n }\n\n const dt = Math.min((timestamp - lastTsRef.current) / 1000, 0.033);\n lastTsRef.current = timestamp;\n\n let orbs = stepPhysics(orbsRef.current, config, dt);\n orbs = resolveCircleCollisions(orbs, config);\n\n const merged = mergeSameLevelOrbs(orbs, config);\n orbs = merged.orbs;\n orbsRef.current = orbs.slice(-config.maxOrbs);\n\n if (merged.scoreGain > 0) {\n scoreRef.current += merged.scoreGain;\n setScore(scoreRef.current);\n onScoreChangeRef.current?.(scoreRef.current);\n }\n\n const gameOver = orbs.some(\n (orb) =>\n orb.age > config.gameOverAgeThreshold &&\n orb.y - orb.radius <= config.lossLineY &&\n Math.abs(orb.vy) < 90\n );\n\n if (gameOver) {\n transitionStatus('gameOver');\n const latestBest = Math.max(bestScore, scoreRef.current);\n if (latestBest !== bestScore) {\n setBestScore(latestBest);\n }\n onGameOverRef.current?.(scoreRef.current, latestBest);\n draw('gameOver');\n return;\n }\n\n draw('playing');\n rafRef.current = window.requestAnimationFrame(frame);\n };\n\n rafRef.current = window.requestAnimationFrame(frame);\n\n return () => {\n if (rafRef.current) {\n window.cancelAnimationFrame(rafRef.current);\n }\n };\n }, [\n bestScore,\n config,\n draw,\n setBestScore,\n status,\n transitionStatus,\n ]);\n\n useEffect(() => {\n if (score > bestScore) {\n setBestScore(score);\n }\n }, [bestScore, score, setBestScore]);\n\n return {\n canvasRef,\n status,\n score,\n bestScore: Math.max(bestScore, score),\n nextLevel,\n config,\n setAimFromClientX,\n handleDrop,\n togglePause,\n restart,\n };\n}\n","'use client';\n\nimport { useEffect, useState } from 'react';\nimport type { RefObject } from 'react';\n\ninterface ResponsiveSize {\n displayWidth: number;\n displayHeight: number;\n scale: number;\n}\n\nexport function useResponsiveCanvas(\n logicalWidth: number,\n logicalHeight: number,\n containerRef: RefObject<HTMLElement>\n): ResponsiveSize {\n const [size, setSize] = useState<ResponsiveSize>({\n displayWidth: logicalWidth,\n displayHeight: logicalHeight,\n scale: 1,\n });\n\n useEffect(() => {\n const updateSize = () => {\n const container = containerRef.current;\n if (!container || typeof window === 'undefined') {\n return;\n }\n\n const rect = container.getBoundingClientRect();\n const maxWidth = Math.max(280, rect.width);\n const maxHeight = Math.max(420, Math.floor(window.innerHeight * 0.78));\n const scale = Math.min(maxWidth / logicalWidth, maxHeight / logicalHeight, 1);\n\n setSize({\n displayWidth: Math.floor(logicalWidth * scale),\n displayHeight: Math.floor(logicalHeight * scale),\n scale,\n });\n };\n\n updateSize();\n\n const container = containerRef.current;\n const observer =\n typeof ResizeObserver !== 'undefined' ? new ResizeObserver(updateSize) : null;\n if (container && observer) {\n observer.observe(container);\n }\n\n window.addEventListener('resize', updateSize);\n\n return () => {\n observer?.disconnect();\n window.removeEventListener('resize', updateSize);\n };\n }, [containerRef, logicalWidth, logicalHeight]);\n\n return size;\n}\n","import React from 'react';\nimport type { PointerEvent, RefObject } from 'react';\n\ninterface GameCanvasProps {\n canvasRef: RefObject<HTMLCanvasElement>;\n width: number;\n height: number;\n displayWidth: number;\n displayHeight: number;\n onPointerMove: (event: PointerEvent<HTMLCanvasElement>) => void;\n onPointerDown: (event: PointerEvent<HTMLCanvasElement>) => void;\n onPointerUp: (event: PointerEvent<HTMLCanvasElement>) => void;\n}\n\nexport function GameCanvas({\n canvasRef,\n width,\n height,\n displayWidth,\n displayHeight,\n onPointerMove,\n onPointerDown,\n onPointerUp,\n}: GameCanvasProps) {\n return (\n <canvas\n ref={canvasRef}\n width={width}\n height={height}\n className=\"rounded-xl border border-cyan-200 bg-cyan-50 shadow-sm\"\n style={{\n width: `${displayWidth}px`,\n height: `${displayHeight}px`,\n maxWidth: '100%',\n touchAction: 'none',\n }}\n onPointerMove={onPointerMove}\n onPointerDown={onPointerDown}\n onPointerUp={onPointerUp}\n onContextMenu={(event) => event.preventDefault()}\n />\n );\n}\n","import React from 'react';\n\ninterface GameControlsProps {\n isPaused: boolean;\n isPlaying: boolean;\n onTogglePause: () => void;\n onRestart: () => void;\n}\n\nexport function GameControls({ isPaused, isPlaying, onTogglePause, onRestart }: GameControlsProps) {\n return (\n <div className=\"grid grid-cols-2 gap-2\">\n <button\n type=\"button\"\n className=\"rounded-lg bg-cyan-600 px-4 py-3 text-sm font-semibold text-white disabled:cursor-not-allowed disabled:opacity-50\"\n onClick={onTogglePause}\n disabled={!isPlaying}\n >\n {isPaused ? '继续' : '暂停'}\n </button>\n <button\n type=\"button\"\n className=\"rounded-lg bg-emerald-600 px-4 py-3 text-sm font-semibold text-white\"\n onClick={onRestart}\n >\n 重开\n </button>\n </div>\n );\n}\n\n","import React from 'react';\n\ninterface GameHUDProps {\n score: number;\n bestScore: number;\n nextLevel: number;\n statusText: string;\n}\n\nexport function GameHUD({ score, bestScore, nextLevel, statusText }: GameHUDProps) {\n return (\n <div className=\"flex items-center justify-between gap-2 rounded-lg border border-cyan-200 bg-white/80 p-3\">\n <div className=\"min-w-0\">\n <div className=\"text-xs text-slate-500\">当前分数</div>\n <div className=\"text-xl font-bold text-cyan-700\">{score}</div>\n <div className=\"text-xs text-slate-500\">最高分 {bestScore}</div>\n </div>\n <div className=\"text-right\">\n <div className=\"text-xs text-slate-500\">下一个</div>\n <div className=\"text-base font-semibold text-emerald-700\">M{nextLevel}</div>\n <div className=\"text-xs font-medium text-slate-600\">{statusText}</div>\n </div>\n </div>\n );\n}\n\n","import React from 'react';\n\ninterface GameResultModalProps {\n open: boolean;\n score: number;\n bestScore: number;\n onRestart: () => void;\n}\n\nexport function GameResultModal({ open, score, bestScore, onRestart }: GameResultModalProps) {\n if (!open) {\n return null;\n }\n\n return (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center bg-slate-900/50 p-4\">\n <div className=\"pointer-events-auto w-full max-w-xs rounded-xl bg-white p-5 shadow-2xl\">\n <h3 className=\"text-lg font-semibold text-slate-900\">游戏结束</h3>\n <p className=\"mt-2 text-sm text-slate-600\">当前分数:{score}</p>\n <p className=\"text-sm text-slate-600\">最高分:{bestScore}</p>\n <button\n type=\"button\"\n className=\"mt-4 w-full rounded-lg bg-cyan-600 px-4 py-2 text-sm font-semibold text-white\"\n onClick={onRestart}\n >\n 再来一局\n </button>\n </div>\n </div>\n );\n}\n\n","'use client';\n\nimport React, { useMemo, useRef } from 'react';\nimport type { MikuFusionGameCallbacks, MikuFusionGameConfig } from '../types';\nimport { useMikuFusionGame } from '../hooks/useMikuFusionGame';\nimport { useResponsiveCanvas } from '../hooks/useResponsiveCanvas';\nimport { GameCanvas } from './GameCanvas';\nimport { GameControls } from './GameControls';\nimport { GameHUD } from './GameHUD';\nimport { GameResultModal } from './GameResultModal';\n\nexport interface MikuFusionGameProps extends Partial<MikuFusionGameConfig>, MikuFusionGameCallbacks {\n className?: string;\n storageKey?: string;\n}\n\nexport function MikuFusionGame({ className, storageKey, ...options }: MikuFusionGameProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const {\n canvasRef,\n status,\n score,\n bestScore,\n nextLevel,\n config,\n setAimFromClientX,\n handleDrop,\n togglePause,\n restart,\n } = useMikuFusionGame({ ...options, storageKey });\n\n const { displayWidth, displayHeight } = useResponsiveCanvas(\n config.width,\n config.height,\n containerRef\n );\n\n const statusText = useMemo(() => {\n if (status === 'ready') {\n return '待开始';\n }\n if (status === 'playing') {\n return '进行中';\n }\n if (status === 'paused') {\n return '已暂停';\n }\n return '已结束';\n }, [status]);\n\n const handlePointerMove = (event: React.PointerEvent<HTMLCanvasElement>) => {\n const rect = event.currentTarget.getBoundingClientRect();\n setAimFromClientX(event.clientX, rect);\n };\n\n const handlePointerDown = (event: React.PointerEvent<HTMLCanvasElement>) => {\n event.currentTarget.setPointerCapture(event.pointerId);\n const rect = event.currentTarget.getBoundingClientRect();\n setAimFromClientX(event.clientX, rect);\n };\n\n const handlePointerUp = (event: React.PointerEvent<HTMLCanvasElement>) => {\n const rect = event.currentTarget.getBoundingClientRect();\n handleDrop(event.clientX, rect);\n event.currentTarget.releasePointerCapture(event.pointerId);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key.toLowerCase() === 'r') {\n restart();\n }\n if (event.key.toLowerCase() === 'p') {\n togglePause();\n }\n };\n\n return (\n <div\n ref={containerRef}\n tabIndex={0}\n onKeyDown={handleKeyDown}\n className={`relative mx-auto flex w-full max-w-xl flex-col gap-3 p-3 md:p-4 ${className || ''}`}\n style={{\n paddingBottom: 'max(0.75rem, env(safe-area-inset-bottom))',\n }}\n >\n <GameHUD score={score} bestScore={bestScore} nextLevel={nextLevel} statusText={statusText} />\n\n <div className=\"relative mx-auto\">\n <GameCanvas\n canvasRef={canvasRef}\n width={config.width}\n height={config.height}\n displayWidth={displayWidth}\n displayHeight={displayHeight}\n onPointerMove={handlePointerMove}\n onPointerDown={handlePointerDown}\n onPointerUp={handlePointerUp}\n />\n <GameResultModal open={status === 'gameOver'} score={score} bestScore={bestScore} onRestart={restart} />\n </div>\n\n <GameControls\n isPaused={status === 'paused'}\n isPlaying={status === 'playing' || status === 'paused'}\n onTogglePause={togglePause}\n onRestart={restart}\n />\n </div>\n );\n}\n\n","import type { MikuFusionContentRegistry } from './types';\n\nexport type * from './types';\n\n/**\n * 仅作为未来内容包化扩展占位。\n * 当前基础玩法不会消费这些数据。\n */\nexport const defaultContentRegistry: MikuFusionContentRegistry = {\n producers: [],\n songs: [],\n themes: [],\n};\n\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sa2kit",
3
- "version": "1.6.32",
3
+ "version": "1.6.33",
4
4
  "description": "A modern, type-safe React utility library with cross-platform support and platform adapters",
5
5
  "keywords": [
6
6
  "react",