【小程序】 贪吃蛇(Next.js+WebSocket+SQLite + Prisma ORM)

本项目站内程序和源代码下载地址下载地址

一、概述

"贪吃蛇"游戏------打开浏览器就能玩的那种,它是一个 以贪吃蛇游戏为核心展示的 Full-Stack 技术展示项目,背后藏着完整的现代 Web 工程体系:

  • 前端:用 Next.js 搭建的交互式贪吃蛇游戏页面
  • 后端:通过 API 路由提供的简单接口
  • 数据库:SQLite + Prisma ORM,存储用户和文章数据
  • 实时通信:WebSocket 聊天室(作为 mini-service 运行)
  • 部署体系:Caddy 反向代理、Docker 友好打包、生产级启动脚本

用一条蛇串起一整条技术栈。


二、项目结构

复制代码
tanchishe/
├── src/                          # 前端源代码
│   ├── app/                      # Next.js App Router 页面
│   │   ├── page.tsx              # 🏠 主页------贪吃蛇游戏本尊!
│   │   ├── layout.tsx            # 📐 全局布局(字体、meta、全局样式)
│   │   ├── globals.css           # 🎨 全局 CSS(Tailwind + 主题变量)
│   │   └── api/
│   │       └── route.ts          # 📡 Hello World API 接口
│   ├── components/ui/            # 🧩 shadcn/ui 组件库(50+个组件)
│   ├── hooks/
│   │   ├── use-mobile.ts        # 📱 响应式断点检测 Hook
│   │   └── use-toast.ts         # 🍞 Toast 通知 Hook
│   └── lib/
│       ├── db.ts                 # 🗄️ Prisma 数据库单例
│       └── utils.ts              # 🔧 工具函数(cn() class 合并)
│
├── prisma/
│   └── schema.prisma             # 📋 数据模型定义(User、Post)
│
├── examples/websocket/           # 🔌 WebSocket 示例
│   ├── server.ts                 #   服务端(Socket.IO,端口 3003)
│   └── frontend.tsx              #   前端聊天室页面
│
├── mini-services/                # ⚙️ 微服务目录(扩展用,目前空的)
│   └── .gitkeep
│
├── public/                       # 📂 静态资源
│   ├── logo.svg                  #   项目 Logo
│   └── robots.txt                #   爬虫规则
│
├── download/                     # 📥 下载目录(生成的产物说明)
│   └── README.md
│
├── db/                           # 🗄️ 数据库文件
│   └── custom.db                 #   SQLite 数据库(开发环境)
│
├── .zscripts/                    # ⚡ 脚本工具箱
│   ├── dev.sh                    #   开发环境一键启动
│   ├── build.sh                  #   生产构建打包
│   ├── start.sh                  #   生产环境启动
│   ├── mini-services-install.sh  #   安装微服务依赖
│   ├── mini-services-build.sh    #   构建微服务
│   └── mini-services-start.sh    #   启动微服务
│
├── .env                          # 🔐 环境变量
├── .gitignore                    # 🙈 Git 忽略规则
├── package.json                  # 📦 项目依赖
├── next.config.ts                # ⚙️ Next.js 配置
├── tailwind.config.ts            # 🎨 Tailwind CSS 配置
├── postcss.config.mjs            # 📎 PostCSS 配置
├── eslint.config.mjs             # ✅ ESLint 配置
├── Caddyfile                     # 🌐 Caddy 反向代理配置
└── tanchishe-architecture.md     # 📄 早期架构设计文档

三、技术栈

层面 技术 用途
框架 Next.js 16 全栈 React 框架
语言 TypeScript 类型安全
样式 Tailwind CSS v4 + shadcn/ui 原子化样式 + 组件库
动画 Framer Motion 游戏界面动效
数据库 SQLite + Prisma ORM 轻量数据存储
实时通信 Socket.IO WebSocket 聊天
状态管理 Zustand(已安装,待用) 全局状态
拖拽 @dnd-kit(已安装,待用) 拖拽交互
图表 Recharts(已安装,待用) 数据可视化
反代 Caddy 反向代理/SSL
运行时 Bun 包管理 + 运行
表单 react-hook-form + Zod 表单校验
HTTP 客户端 @tanstack/react-query 数据请求缓存

四、核心功能详解

4.1 🐍 贪吃蛇游戏(src/app/page.tsx)

这是项目的 C 位------一个完整的 Canvas 贪吃蛇游戏,全部在前端实现。

怎么玩的:

  • 键盘方向键 / WASD 控制蛇的移动
  • 吃红色食物增长身体,每吃一个加 10 分
  • 撞墙或撞到自己就 Game Over
  • 支持触屏滑动(移动端)
  • 高分记录存在 localStorage 里

代码里的小心思:

  • HiDPI 适配 :根据 devicePixelRatio 缩放 Canvas,确保高分辨率屏幕下不模糊
  • 蛇身渐变:从蛇头到尾巴颜色逐渐变暗,一眼能看出方向
  • 蛇眼睛:会跟随移动方向转动萌点
  • 食物发光效果:红色光晕让人忍不住想去吃
  • 帧循环 :用 requestAnimationFrame + 时间差控制 tick,而非 setInterval,更平滑
  • Ref 双缓冲snakeReffoodRef 等 ref 与 state 同步,避免闭包陷阱

游戏状态机: IDLE → PLAYING → GAME_OVER → IDLE

4.2 📡 API 接口(src/app/api/route.ts)

目前只有一个简单的 GET 接口:

复制代码
GET /api → { "message": "Hello, world!" }

这是留给未来扩展后端业务的入口。

4.3 🗄️ 数据库设计(prisma/schema.prisma)

使用 SQLite,定义了最简单的博客式数据模型:

prisma 复制代码
model User {
  id        String   @id @default(cuid())    // 用户 ID
  email     String   @unique                  // 邮箱(唯一)
  name      String?                           // 昵称
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  posts     Post[]                            // 一对多关系
}

model Post {
  id        String   @id @default(cuid())
  title     String                            // 标题
  content   String?                           // 内容
  published Boolean  @default(false)          // 是否发布
  authorId  String                            // 作者 ID
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  author    User     @relation(fields: [authorId], references: [id])
}

设计思路 :User ↔ Post 一对多关系,通过 authorId 外键关联。虽小但五脏俱全。

数据库路径通过环境变量 DATABASE_URL 配置,开发环境指向 db/custom.db

4.4 🔌 WebSocket 聊天室(examples/websocket/)

一个经典的 Socket.IO 聊天室示例:

服务端(server.ts):

  • 监听端口 3003
  • 管理用户在线列表(Map<socketId, User>)
  • 支持:加入房间、发送消息、离开房间
  • 事件:joinmessagedisconnect
  • 广播:user-joineduser-leftusers-list

前端(frontend.tsx):

  • 输入用户名加入聊天
  • 实时消息列表(自动滚动)
  • 在线用户列表
  • 系统消息(xxx 加入/离开)和用户消息分样式显示

4.5 🌐 反向代理(Caddyfile)

Caddy 作为统一入口,工作在 81 端口。核心逻辑:

复制代码
:81 {
    # 如果有 ?XTransformPort=3003 参数 → 转发到 3003(WebSocket 服务)
    # 其他所有请求 → 转发到 localhost:3000(Next.js)
}

这样用户访问同一个域名/端口,Caddy 根据查询参数自动路由到不同的后端服务。


五、开发/部署工作流

本地开发(dev.sh

bash 复制代码
$ bash .zscripts/dev.sh

脚本自动做几件事:

  1. 检查 bun 是否安装
  2. bun install 安装依赖
  3. bun run db:push 同步数据库表结构
  4. 启动 Next.js dev server(端口 3000)
  5. 健康检查确认服务可用
  6. 扫描 mini-services/ 下的子项目并启动

生产构建(build.sh

bash 复制代码
$ bash .zscripts/build.sh

构建流程:

  1. 全局安装依赖
  2. next build 构建 + 拷贝 standalone 产物
  3. 构建 mini-services(如果有)
  4. 复制数据库(开发 DB 转生产)
  5. 收集所有产物到 /tmp/build_fullstack_$BUILD_ID/
  6. 打包为 tar.gz

生产启动(start.sh

bash 复制代码
# 在部署服务器上解压后
$ bash start.sh

启动流程:

  1. 启动 Next.js standalone server(默认端口 3000)
  2. 启动 mini-services
  3. 前台运行 Caddy(按 Ctrl+C 全部关闭)

关键设计 :通过 trap cleanup 实现优雅关闭------发送 SIGTERM 后等待进程退出,超时则 SIGKILL。


六、配置说明

环境变量(.env)

env 复制代码
DATABASE_URL=file:/home/z/my-project/db/custom.db

数据库路径使用的是绝对路径,部署时需要根据实际路径调整。

Next.js 配置(next.config.ts)

typescript 复制代码
{
  output: "standalone",       // 独立部署输出
  typescript: { ignoreBuildErrors: true },  // 构建时跳过 TS 检查
  reactStrictMode: false,     // 关闭 Strict Mode(避免开发环境双重渲染)
}

ESLint 配置亮点

几乎所有规则都被关闭了("off"),包括 TypeScript 校验、React hooks、未使用变量等。这是有意为之------项目本身是 AI 辅助生成的脚手架,宽松的 lint 配置让 AI 编写代码更自由。


七、组件库说明

src/components/ui/ 下包含 50+ 个 shadcn/ui 组件,它们都是 无业务逻辑的纯 UI 组件,基于 Radix UI 原语构建:

  • 布局:Card、Sheet、Drawer、Resizable、Sidebar
  • 表单:Input、Select、Checkbox、RadioGroup、Slider、Switch
  • 反馈:Toast、Sonner、Alert、Progress、Skeleton
  • 导航:Tabs、Breadcrumb、Menubar、NavigationMenu、Pagination
  • 弹窗:Dialog、Popover、Tooltip、HoverCard、DropdownMenu
  • 数据展示:Table、Chart、Calendar、Carousel、Avatar、Badge

这些组件目前处于"待命"状态------它们已经被安装和注册,但不一定在主页中被使用。后续添加页面时可以直接 import 使用,无需从头造轮子。


八、设计哲学

1. 🎯 演示优先

整个项目的核心目的是 展示技术能力 。贪吃蛇游戏虽然简单,但在 Canvas 渲染、动画、HiDPI 适配、ref 管理等方面展示了扎实的前端功底。

2. 🧱 可扩展的骨架

项目虽然目前只有一个游戏页面,但基础设施已经准备就绪:

  • 数据库 ORM 已配置
  • API 路由已打通
  • WebSocket 示例已提供
  • 微服务架构已预留
  • CI/CD 脚本已编写

往里面加任何功能,都不需要重新搭建基础设施。


九、如何快速上手

我想跑起来看看

bash 复制代码
cd /home/tht/projects/tanchishe
bun install
bun run dev

浏览器打开 http://localhost:3000,就能看到贪吃蛇了。

我想试试 WebSocket 聊天

先启动 WebSocket 服务端:

bash 复制代码
cd /home/tht/projects/tanchishe/examples/websocket
bun server.ts

再通过 Caddy 访问(需要 Caddy 在 81 端口运行),或直接修改前端示例的端口连接方式。

我想改游戏逻辑

直接编辑 src/app/page.tsx,搜索以下关键区域:

  • const GRID_SIZE = 20 → 改棋盘大小
  • const INITIAL_SPEED = 150 → 改初始速度
  • const SPEED_INCREMENT = 3 → 改每次加速幅度
  • randomFood 函数 → 改食物生成逻辑

我想添加新页面

src/app/ 下新建文件夹 + page.tsx 即可,Next.js App Router 自动路由。比如 src/app/about/page.tsx 就是 /about 页面。


十、未来可能的演进方向

  • 多玩家对战:利用 WebSocket 做实时对战
  • 积分排行榜:接入数据库,展示全球高分
  • 关卡系统:障碍物、传送门等特殊元素
  • AI 蛇:AI 控制的蛇与玩家对战
  • 暗黑/护眼主题:利用已有的 next-themes
  • 游戏回放:记录每一步并重放
  • PWA:Service Worker 让游戏离线可玩

相关推荐
JiaWen技术圈1 小时前
next.js 开发中的水合(Hydration)问题
javascript
和blue一起变得更好2 小时前
周三:Vue3高级组件特性
前端·javascript·vue.js
Java编程爱好者2 小时前
Spring AI 1.0 实战:从原理到落地的完整指南
javascript
路光.2 小时前
uniapp小程序/App使用webview打通麦克风权限实现录音功能
小程序·uni-app·app
我命由我123453 小时前
VSCode - VSCode 自定义折叠区域
前端·javascript·ide·vscode·前端框架·编辑器·js
清水白石0083 小时前
Python 数据建模指南:dataclass、TypedDict 与 Pydantic 的选型博弈
前端·javascript·python
ZC跨境爬虫3 小时前
跟着 MDN 学CSS day_23:(表单与表格综合样式化实战)
前端·javascript·css·ui·html·tensorflow
hnxaoli3 小时前
统信小程序(十四)支持拖拽的旋图程序
python·小程序
MRSM_013 小时前
Three.js 入门:在浏览器里构建你的第一个 3D 场景
javascript