import { canonicalizeSoundEffectPrompt } from './ImageCanvasSoundEffectPromptModel'; export type SoundEffectPromptPresetCategory = 'event' | 'requirement'; export type SoundEffectPromptPresetGroup = | 'ui-operation' | 'pickup-reward' | 'growth-result' | 'character-combat' | 'skill-status' | 'mechanism-scene-interaction' | 'style-direction' | 'feedback-requirement'; export type SoundEffectPromptPreset = { id: string; category: SoundEffectPromptPresetCategory; group: SoundEffectPromptPresetGroup; label: string; prompt: string; }; const UNICODE_PUNCTUATION_CODE_POINT = /^\p{Punctuation}$/u; const SOUND_EFFECT_PRESET_SEPARATOR = ','; export const SOUND_EFFECT_PROMPT_PRESET_GROUPS = [ 'ui-operation', 'pickup-reward', 'growth-result', 'character-combat', 'skill-status', 'mechanism-scene-interaction', 'style-direction', 'feedback-requirement', ] as const satisfies readonly SoundEffectPromptPresetGroup[]; /** 权威设计「SFX 生成优化 V2.0」冻结的 40 个事件预设与 12 个补充要求。 */ export const SOUND_EFFECT_PROMPT_PRESETS = [ { id: 'button-tap', category: 'event', group: 'ui-operation', label: '轻触按钮', prompt: '柔和的按钮点击声', }, { id: 'operation-confirm', category: 'event', group: 'ui-operation', label: '确认操作', prompt: '明亮的确认提示音', }, { id: 'back-cancel', category: 'event', group: 'ui-operation', label: '返回取消', prompt: '轻微下降的取消提示音', }, { id: 'page-transition', category: 'event', group: 'ui-operation', label: '页面切换', prompt: '快速掠过的界面切换声', }, { id: 'notification', category: 'event', group: 'ui-operation', label: '通知提醒', prompt: '清晰柔和的通知提示音', }, { id: 'operation-error', category: 'event', group: 'ui-operation', label: '操作错误', prompt: '短促克制的错误提示音', }, { id: 'coin-pickup', category: 'event', group: 'pickup-reward', label: '金币拾取', prompt: '金币拾取时清脆的金属叮当声', }, { id: 'item-pickup', category: 'event', group: 'pickup-reward', label: '道具拾取', prompt: '拾取道具时轻快的提示音', }, { id: 'reward-received', category: 'event', group: 'pickup-reward', label: '获得奖励', prompt: '奖励出现时明亮的提示音', }, { id: 'chest-open', category: 'event', group: 'pickup-reward', label: '宝箱开启', prompt: '金属锁扣弹开,随后响起明亮的奖励提示音', }, { id: 'content-unlock', category: 'event', group: 'pickup-reward', label: '解锁内容', prompt: '锁定状态解除,随后响起解锁提示音', }, { id: 'rare-drop', category: 'event', group: 'pickup-reward', label: '稀有掉落', prompt: '稀有物品出现时闪耀的奖励提示音', }, { id: 'item-craft', category: 'event', group: 'growth-result', label: '物品合成', prompt: '两件物品融合,随后响起明亮的完成提示音', }, { id: 'character-level-up', category: 'event', group: 'growth-result', label: '角色升级', prompt: '能量快速上升,随后响起明亮的升级提示音', }, { id: 'quest-complete', category: 'event', group: 'growth-result', label: '任务完成', prompt: '任务完成提示音,随后响起简短的奖励音符', }, { id: 'achievement-unlocked', category: 'event', group: 'growth-result', label: '成就达成', prompt: '明亮的成就提示音,随后响起简短的庆祝音符', }, { id: 'challenge-victory', category: 'event', group: 'growth-result', label: '挑战胜利', prompt: '明亮的胜利提示音,随后响起短暂的庆祝音符', }, { id: 'challenge-defeat', category: 'event', group: 'growth-result', label: '挑战失败', prompt: '低沉的失败提示音', }, { id: 'character-jump', category: 'event', group: 'character-combat', label: '角色跳跃', prompt: '角色轻盈跳起的声音', }, { id: 'character-land', category: 'event', group: 'character-combat', label: '角色落地', prompt: '角色落地时轻微的撞击声', }, { id: 'light-hit', category: 'event', group: 'character-combat', label: '轻度受击', prompt: '轻微撞击的受击声', }, { id: 'heavy-hit', category: 'event', group: 'character-combat', label: '重度受击', prompt: '沉重有力的撞击声', }, { id: 'attack-swing', category: 'event', group: 'character-combat', label: '攻击挥动', prompt: '武器快速挥过空气的呼啸声', }, { id: 'attack-hit', category: 'event', group: 'character-combat', label: '攻击命中', prompt: '武器击中目标的清晰撞击声', }, { id: 'block-success', category: 'event', group: 'character-combat', label: '格挡成功', prompt: '武器碰撞,随后被挡开的金属声', }, { id: 'object-break', category: 'event', group: 'character-combat', label: '物体破碎', prompt: '物体撞击地面后快速破碎的声音', }, { id: 'skill-charge', category: 'event', group: 'skill-status', label: '技能蓄力', prompt: '能量逐渐聚集的低沉嗡鸣声', }, { id: 'magic-cast', category: 'event', group: 'skill-status', label: '魔法释放', prompt: '柔和的魔法能量扩散,带有圆润空灵的闪光声', }, { id: 'healing', category: 'event', group: 'skill-status', label: '治疗恢复', prompt: '柔和能量扩散,带有温暖圆润的提示音', }, { id: 'shield-create', category: 'event', group: 'skill-status', label: '护盾生成', prompt: '能量向外展开,形成稳定的护盾声', }, { id: 'teleport', category: 'event', group: 'skill-status', label: '瞬间移动', prompt: '能量快速收缩,随后以短促的空气抽离声消失', }, { id: 'ice-skill', category: 'event', group: 'skill-status', label: '冰冻技能', prompt: '冰霜能量扩散,随后响起清脆的冻结声', }, { id: 'fire-skill', category: 'event', group: 'skill-status', label: '火焰技能', prompt: '火焰迅速喷发,带有短促的燃烧声', }, { id: 'status-buff', category: 'event', group: 'skill-status', label: '状态强化', prompt: '能量逐渐上升,形成稳定明亮的提示音', }, { id: 'door-open', category: 'event', group: 'mechanism-scene-interaction', label: '门开启', prompt: '门锁解除,随后厚重的木门缓慢打开', }, { id: 'mechanism-start', category: 'event', group: 'mechanism-scene-interaction', label: '机关启动', prompt: '机关解锁,随后齿轮开始转动', }, { id: 'lever-trigger', category: 'event', group: 'mechanism-scene-interaction', label: '拉杆触发', prompt: '拉杆被扳动,随后远处机关启动', }, { id: 'stone-move', category: 'event', group: 'mechanism-scene-interaction', label: '石块移动', prompt: '大型石块缓慢移动时低沉的摩擦声', }, { id: 'portal-open', category: 'event', group: 'mechanism-scene-interaction', label: '传送门开启', prompt: '能量旋转聚集,随后响起持续、空灵的传送门展开声', }, { id: 'countdown-warning', category: 'event', group: 'mechanism-scene-interaction', label: '倒计时警告', prompt: '逐渐加快的倒计时提示音', }, { id: 'casual-cute', category: 'requirement', group: 'style-direction', label: '休闲可爱', prompt: '轻快可爱的卡通风格', }, { id: 'retro-arcade', category: 'requirement', group: 'style-direction', label: '复古街机', prompt: '复古街机风格', }, { id: 'sci-fi-electronic', category: 'requirement', group: 'style-direction', label: '科幻电子', prompt: '干净的科幻电子音色', }, { id: 'fantasy-magic', category: 'requirement', group: 'style-direction', label: '奇幻魔法', prompt: '柔和梦幻的魔法音色', }, { id: 'realistic-natural', category: 'requirement', group: 'style-direction', label: '写实自然', prompt: '自然真实的声音质感', }, { id: 'cartoon-exaggerated', category: 'requirement', group: 'style-direction', label: '卡通夸张', prompt: '夸张鲜明的卡通风格', }, { id: 'gentle-feedback', category: 'requirement', group: 'feedback-requirement', label: '轻柔反馈', prompt: '轻柔克制', }, { id: 'strong-feedback', category: 'requirement', group: 'feedback-requirement', label: '有力反馈', prompt: '更有力的撞击感', }, { id: 'short-feedback', category: 'requirement', group: 'feedback-requirement', label: '短促反馈', prompt: '短促的单次声音', }, { id: 'two-stage-rise', category: 'requirement', group: 'feedback-requirement', label: '两段递进', prompt: '由弱到强的两段变化', }, { id: 'clean-prominent', category: 'requirement', group: 'feedback-requirement', label: '干净突出', prompt: '主体声音清晰,减少杂音', }, { id: 'soft-not-harsh', category: 'requirement', group: 'feedback-requirement', label: '柔和不刺耳', prompt: '圆润柔和,避免尖锐高频', }, ] as const satisfies readonly SoundEffectPromptPreset[]; function readLastCodePoint(value: string) { const codePoints = Array.from(value); return codePoints[codePoints.length - 1]; } export function appendSoundEffectPromptPreset( currentPrompt: string, preset: SoundEffectPromptPreset, ) { const canonicalPrompt = canonicalizeSoundEffectPrompt(currentPrompt); if (!canonicalPrompt) { return preset.prompt; } const lastCodePoint = readLastCodePoint(canonicalPrompt); if (lastCodePoint && UNICODE_PUNCTUATION_CODE_POINT.test(lastCodePoint)) { return `${canonicalPrompt}${preset.prompt}`; } return `${canonicalPrompt}${SOUND_EFFECT_PRESET_SEPARATOR}${preset.prompt}`; }