docs: 添加PRD需求文档、任务计划和设计系统

This commit is contained in:
Cloud Bot
2026-03-21 08:16:51 +00:00
parent 3a236fd294
commit 21e3da573e
6 changed files with 1608 additions and 0 deletions

View File

@@ -0,0 +1,226 @@
# Task 1A+1B: 游戏基础框架搭建
## 任务概要
在现有 Next.js 项目中,安装 Phaser.js改造主页封面创建游戏页面实现 Phaser 游戏框架挂载 + S型地图渲染。
## 执行步骤
### Step 1: 安装 Phaser.js
```bash
pnpm add phaser
```
### Step 2: 改造 `app/page.tsx`(主页/游戏封面)
完全重写主页,展示游戏封面。注意:**必须覆盖模板原有 UI不保留任何模板样式**。
设计要求(参考 `design-system/大厂保卫战/MASTER.md`
- 背景色:`#0F0F23`(深夜宇宙蓝)
- 标题字体Press Start 2P像素字体颜色 `#A78BFA`(霓虹紫)
- 副标题VT323 字体
- 主色 CTA 按钮(进入游戏):`#F43F5E` 红色
- 效果CRT 扫描线叠加层(`::before` 伪元素repeating-linear-gradient 细黑线)
- 霓虹发光效果:标题 `text-shadow` 双层发光
- 装饰性文字:背景中随机排列大厂黑话(低透明度)
主页内容结构:
```
[全屏黑色背景]
[CRT扫描线叠加层]
[装饰黑话背景文字]
[中央卡片]
标题:大厂保卫战
副标题:最后的打工人
英文副标THE LAST GRINDER
描述保住KPI战胜空降VP
[开始游戏] 按钮 → 跳转 /game
[底部版权:像素风格]
```
### Step 3: 创建 `app/game/page.tsx`(游戏页面)
```typescript
'use client'
import { useEffect, useRef } from 'react'
export default function GamePage() {
const gameRef = useRef<any>(null)
useEffect(() => {
let game: any = null
const initGame = async () => {
const Phaser = (await import('phaser')).default
const { createGameConfig } = await import('@/game/config')
if (gameRef.current && !game) {
game = new Phaser.Game(createGameConfig('game-container'))
}
}
initGame()
return () => {
game?.destroy(true)
}
}, [])
return (
<div className="w-full h-screen bg-[#0F0F23] overflow-hidden">
<div id="game-container" className="w-full h-full" />
</div>
)
}
```
### Step 4: 创建游戏核心文件
**`game/constants.ts`**(游戏常量):
```typescript
export const MAP_COLS = 16
export const MAP_ROWS = 12
export const TILE_SIZE = 80 // 每格80px总计 1280x960Phaser会缩放
export const GAME_WIDTH = 1280
export const GAME_HEIGHT = 720
// S型路径格子坐标
export const PATH_WAYPOINTS = [
{ x: 0, y: 2 },
{ x: 11, y: 2 },
{ x: 11, y: 9 },
{ x: 15, y: 9 },
]
// 游戏初始数值
export const INITIAL_HC = 200
export const INITIAL_KPI = 100
export const STAMINA_MAX = 100
export const STAMINA_REGEN = 5 // 每秒恢复量
export const COFFEE_COST = 10 // 瑞幸咖啡 HC 成本
// 颜色常量
export const COLOR_PATH = 0x3d2b1f
export const COLOR_BUILDABLE = 0x1e3a5f
export const COLOR_HOVER = 0x2d5a8e
export const COLOR_BORDER = 0x0a1628
```
**`game/config.ts`**Phaser 配置):
```typescript
import Phaser from 'phaser'
import { GAME_WIDTH, GAME_HEIGHT } from './constants'
export function createGameConfig(containerId: string): Phaser.Types.Core.GameConfig {
return {
type: Phaser.AUTO,
width: GAME_WIDTH,
height: GAME_HEIGHT,
parent: containerId,
backgroundColor: '#0a1628',
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH,
},
scene: [], // 在 GameScene 中动态加载
physics: {
default: 'arcade',
arcade: { debug: false }
}
}
}
```
**`game/GameScene.ts`**(主游戏场景):
核心地图渲染逻辑:
- 创建 16x12 格子网格
- 根据 PATH_WAYPOINTS 计算路径格子集合(路径上的每个格子都是路径格)
- 路径格子:深褐色(`0x3d2b1f`
- 可建塔格子:深蓝色(`0x1e3a5f`
- 格子间有1px间距
- 鼠标悬停非路径格子时高亮
- 点击非路径格子触发建塔逻辑Phase 1先只做UI提示
- 添加地图装饰性文字("面试间"、"财务室"
- 场景中显示:顶部 HUD 区域KPI进度条 + HC数值
地图路径计算方式(不能只用 4 个坐标点,需要填充中间格子):
```typescript
// 将折线坐标展开为完整路径格子集合
function buildPathTiles(waypoints): Set<string> {
const tiles = new Set<string>()
for (let i = 0; i < waypoints.length - 1; i++) {
const from = waypoints[i]
const to = waypoints[i + 1]
// 水平或垂直连线
if (from.x === to.x) {
for (let y = Math.min(from.y, to.y); y <= Math.max(from.y, to.y); y++) {
tiles.add(`${from.x},${y}`)
}
} else {
for (let x = Math.min(from.x, to.x); x <= Math.max(from.x, to.x); x++) {
tiles.add(`${x},${from.y}`)
}
}
}
return tiles
}
```
HUD 设计Phaser Text/Graphics 实现,而非 HTML 层):
- 顶部黑色半透明条全宽高度60px
- 左:游戏标题 "大厂保卫战" Press Start 2P小字号
-KPI 进度条宽300px绿→黄→红渐变
-HC 数值 "HC: 200"
**`game/GameManager.ts`**(游戏状态管理器):
```typescript
export class GameManager {
private static instance: GameManager
public hc: number = INITIAL_HC
public kpi: number = INITIAL_KPI
public currentWave: number = 0
public gameState: 'idle' | 'playing' | 'paused' | 'victory' | 'defeat' = 'idle'
static getInstance(): GameManager { ... }
spendHC(amount: number): boolean { ... } // 扣除HC不足返回false
addHC(amount: number): void { ... }
reduceKPI(amount: number): void { ... } // 减少KPI归零触发失败
// 事件系统(用于 Scene 与 UI 通信)
onHCChange: ((hc: number) => void)[] = []
onKPIChange: ((kpi: number) => void)[] = []
onGameOver: (() => void)[] = []
onVictory: (() => void)[] = []
}
```
### Step 5: 更新 `app/layout.tsx`
在 layout 中引入 Google FontsPress Start 2P + VT323
```tsx
// 在 <head> 中添加
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=VT323:wght@400&display=swap" rel="stylesheet" />
```
### Step 6: 更新 `app/globals.css`
添加游戏全局样式:
- CSS 变量(颜色 token
- CRT 扫描线效果(供主页使用)
- 霓虹发光 keyframes 动画
- 像素字体 class
## 验收标准
1. `pnpm dev` 启动成功,无编译错误
2. 访问 `/`:显示游戏封面,有进入游戏按钮,霓虹效果正常
3. 点击进入游戏跳转至 `/game`
4. 访问 `/game`:渲染 16x12 格子地图S型路径可见深褐色路径深蓝色可建区域
5. 鼠标悬停可建塔格子时高亮
6. 顶部 HUD 显示 KPI 进度条和 HC 数值
## 相关上下文
- 设计系统:`design-system/大厂保卫战/MASTER.md`
- PRD`.docs/prd-tower-defense-game.md`
- 计划文档:`.docs/plans/2026-03-21-tower-defense-game.md`
- 开发规范:`@rules/dev-best-practices.md`**必须先阅读**
完成开发后,按 `@rules/atomic-commit.md` 规范,将变更按逻辑模块分组提交(禁止 `git add .`),确保所有文件均已 commit 后再结束任务。