这个项目是什么
Wordless 就是个类似 Wordle 的猜单词游戏,用 Next.js 搭建的。玩家有 6 次机会猜出单词,支持 3 到 8 个字母的单词。说实话,开始只是想做点跟 wordle 不一样东西,没想到做着做着就越来越有意思了。
点击这里可以体验:https://wordless.online/
我用了一个周末把代码撸完以后,直接发布上线,也没怎么关注,没想到几个月过去了,这个小游戏的流量一直很稳定,有 50% 的自然搜索,40% 的直接访问流量,这可是个非常漂亮的流量数据呀。
用了什么技术
主要框架
UI 相关
其他工具
文件结构
wordlessgame/ ├── src/ │ ├── app/ # Next.js App Router │ │ ├── api/ # API 路由 │ │ │ ├── ai-completion/ # AI 辅助功能 │ │ │ ├── validate-word/ # 单词验证 │ │ │ └── words/ # 单词生成 │ │ ├── layout.tsx # 根布局 │ │ └── page.tsx # 主页面 │ ├── components/ # React 组件 │ │ ├── ui/ # 基础 UI 组件 │ │ ├── game-grid.tsx # 游戏网格 │ │ ├── key-board.tsx # 虚拟键盘 │ │ └── result-modal.tsx # 结果弹窗 │ ├── data/ # 静态数据 │ │ └── word-lists.ts # 单词词库 │ ├── lib/ # 工具函数 │ │ ├── api.ts # API 调用 │ │ └── utils.ts # 工具函数 │ ├── ai/ # AI 相关功能 │ └── styles/ # 样式文件 └── public/ # 静态资源
核心功能实现
游戏使用 React Hooks 管理复杂的状态:
// 主要状态 const [columns, setColumns] = useState(3); // 单词长度 const [gridContent, setGridContent] = useState([]); // 网格内容 const [currentCell, setCurrentCell] = useState(-1); // 当前输入位置 const [word, setWord] = useState(''); // 目标单词 const [matchResults, setMatchResults] = useState([]); // 匹配结果 const [cellMatchClasses, setCellMatchClasses] = useState([]); // 样式类
采用优化的单词生成器,避免重复选择同一单词:
class WordGenerator { private static instance: WordGenerator; private readonly cache: Map = new Map(); private readonly usedIndices: Map> = new Map(); private readonly shuffledIndices: Map = new Map();
public getRandomWord(length: number): string { // Fisher-Yates 洗牌算法确保随机性 // 避免重复选择相同单词 } }
// 第一遍:标记完全匹配的字母 for (let i = 0; i < guessedWord.length; i++) { if (guessedWord[i] === targetWord[i]) { result[i] = 'C'; // C=正确位置 } else { targetCounts.set(targetWord[i]!, (targetCounts.get(targetWord[i]!) || 0) + 1); } }
// 第二遍:标记位置错误的字母 for (let i = 0; i < guessedWord.length; i++) { if (result[i] !== 'C') { const char = guessedWord[i]!; if (targetCounts.get(char)! > 0) { result[i] = 'P'; // P=位置错误 targetCounts.set(char, targetCounts.get(char)! - 1); } } }
return result; };
export function GameGrid({ gridContent, columns, currentCell, cellMatchClasses, flippingRows }: GameGridProps) { return (
{gridContent.map((content, index) => { const matchClass = cellMatchClasses[index]; const isFlipping = flippingRows.has(Math.floor(index / columns));return (
{content} ); })} ); }使用 memo 优化渲染性能:
const KeyButton = memo(({ letter, isMatched, noMatched, onClick }: KeyButtonProps) => { return ( onClick(letter)} className={cn( 'w-14 h-14 rounded-md font-bold transition-colors', isMatched ? 'bg-green-500 text-white' : noMatched ? 'bg-zinc-400 text-white' : 'bg-white hover:bg-violet-50' )} > {letter} ); });
数据结构
单词词库 词库按长度分类存储,每个长度包含 500+ 个单词:
export const WORD_LISTS: Record = { 3: ['ace', 'age', 'air', ...], // 500+ 三字母单词 4: ['able', 'acid', 'aged', ...], // 500+ 四字母单词 5: ['about', 'above', 'abuse', ...], // 500+ 五字母单词 6: ['abroad', 'accept', 'access', ...], // 500+ 六字母单词 7: ['abandon', 'ability', 'absence', ...], // 500+ 七字母单词 8: ['absolute', 'academic', 'accepted', ...] // 500+ 八字母单词 };
API 设计
Edge Runtime API 使用 Next.js Edge Runtime 提供快速的 API 响应:
export const runtime = 'edge';
export async function GET(request: NextRequest) { // API 逻辑 return NextResponse.json({ data }); }
用户体验优化
胜利庆祝:使用 canvas-confetti 库
响应式设计
移动端优化的键盘布局
自适应网格大小
触摸友好的交互
性能优化
使用 React.memo 减少不必要的重渲染
useCallback 和 useMemo 优化函数和计算
单词生成器的缓存机制
部署和 SEO
SEO 优化 export const metadata: Metadata = { title: "Unlimited Wordless Online: Guess the Word in 6 Tries!", description: "Wordless Online: Endless Word Challenges...", keywords: "wordless,wordly, wordle, game, puzzle, word, words, letters, play, online, guess,unlimited", };
分析工具
开发工具
代码质量
包管理
游戏流程
特色功能
可变单词长度 支持 3-8 个字母的单词,增加游戏难度选择
智能单词生成 避免重复,确保每次游戏都有新鲜感
实时反馈 即时的视觉和交互反馈,提升用户体验
无限游戏 没有次数限制,可以连续游戏
响应式设计 适配各种设备屏幕尺寸
技术亮点
总结 Wordless 是一款用现代 Web 技术打造的游戏,干净利落,跑得飞快,代码还容易维护。没堆花里胡哨的东西,但该有的全都有——好玩、流畅、写得明白。 欢迎来体验: https://wordless.online/