经典飞行棋网页游戏
从零开发一款经典飞行棋网页游戏
面向儿童的平面3D风格飞行棋,纯前端实现,支持人机对战。本文记录了从需求分析到发布上架的完整开发历程。
一、项目背景
飞行棋(又称飞机棋、大富翁飞行棋)是一款经典的儿童棋盘游戏,规则简单但充满趣味性。项目目标是开发一款纯网页版飞行棋游戏,让儿童无需安装任何软件,打开浏览器即可游玩。
核心需求
| 维度 | 要求 |
|---|---|
| 用途 | 经典飞行棋 |
| 用户 | 儿童 |
| 玩法 | 完整经典规则(起飞、踢回、叠飞、跳跃、回家) |
| 风格 | 平面3D(isometric)风格 |
| 技术 | 纯前端,单 HTML 文件,无后端依赖 |
二、技术选型
为什么不用框架?
飞行棋是一个状态有限、交互明确的游戏,核心逻辑是棋盘路径计算和回合制状态机。引入 React/Vue 等框架反而增加构建复杂度,对儿童用户来说也不需要 SPA 的路由能力。
最终选择:单个 index.html 文件,内联 CSS + JS,用 python3 -m http.server 即可启动预览。
技术栈一览
HTML5 → 页面结构
CSS3 → 平面3D风格(perspective + rotateX)、动画(keyframes)
JS → 游戏逻辑、状态管理、AI决策
Canvas? → 不用,纯 DOM 渲染更易调试和样式化
三、棋盘设计
飞行棋的棋盘是经典的十字形布局,这是整个项目最核心也最复杂的部分。
棋盘结构
┌─────────┐
│ 黄方基地 │
├────┬────┤
│ │ │
红方基地 │ 外圈路径 │ 蓝方基地
│ │ │
├────┴────┤
│ 绿方基地 │
└─────────┘
棋盘由以下部分组成:
- 4 个基地(四角):每方 4 个停机位,飞机初始停放处
- 52 格外圈路径:所有玩家共享的环形跑道
- 4 条回家通道(×5 格):各方专属,通向中心终点
- 中心终点:棋盘正中央,飞机的最终目的地
路径坐标映射
棋盘在代码中以 15×15 的网格坐标系定义。每个格子用 [row, col] 表示,通过 gridToPx() 函数转换为像素坐标:
function gridToPx(r, c) {
return [c * (CELL + GAP) + OFFSET, r * (CELL + GAP) + OFFSET];
}
外圈 52 格路径的坐标是手工排列的,这是整个项目中最需要耐心的部分——52 个坐标点,一个都不能错:
const PATH_COORDS = [
[6,1],[6,2],[6,3],[6,4],[6,5], // 红方起飞方向
[5,6],[4,6],[3,6],[2,6],[1,6],[0,6], // 向上
[0,7],[0,8], // 顶部拐弯
[1,8],[2,8],[3,8],[4,8],[5,8], // 向右
// ... 共 52 个坐标
];
四方起飞点
红、黄、蓝、绿四方的起飞点在外圈路径上均匀分布,间隔 13 格:
const START_IDX = [0, 13, 26, 39]; // 红黄蓝绿
四、游戏规则实现
经典飞行棋的规则看似简单,但完整实现需要处理大量边界情况。
4.1 起飞规则
掷到 6 才能将飞机从基地移到起飞点,且掷到 6 可以再掷一次。
if (plane.state === 'base' && game.diceValue === 6) {
plane.state = 'path';
plane.pos = START_IDX[player.idx];
// 掷到6,额外回合
game.extraTurn = true;
}
4.2 移动与碰撞
飞机沿外圈行走,如果停在敌方飞机的位置,将对方踢回基地:
function checkCollision(player, plane) {
for (let other of game.players) {
if (other.idx === player.idx) continue;
for (let p of other.planes) {
if (p.state === 'path' && p.pos === plane.pos) {
p.state = 'base';
p.pos = -1;
setStatus(other.name + ' 被踢回基地!💥');
}
}
}
}
4.3 同色跳跃
经过同色飞行点(每方在外圈有专属飞行点),可以跳跃前进 4 格。这是飞行棋的精髓规则之一:
function checkJump(player, plane) {
let rel = (plane.pos - START_IDX[player.idx] + 52) % 52;
if (rel === 4) { // 同色飞行点
return (plane.pos + 4) % 52; // 跳跃4格
}
return 0;
}
4.4 回家通道
飞机走完外圈一圈后进入回家通道,回家通道共 5 格 + 终点。需要精确计算从外圈到回家通道的过渡:
let total = (plane.pos - START_IDX[ownerIdx] + 52) % 52;
let after = total + game.diceValue;
if (after < 52) {
// 还在外圈
} else {
let homeSteps = after - 52;
if (homeSteps <= 5) {
// 进入回家通道
plane.state = 'home';
plane.homePos = homeSteps;
if (homeSteps === 5) plane.state = 'finish';
}
}
4.5 胜利判定
一方将 4 架飞机全部送到终点即获胜:
function checkWin(player) {
if (player.finished >= 4) {
game.gameOver = true;
showVictory(player);
return true;
}
return false;
}
五、平面3D风格设计
“平面3D”(flat 3D / isometric)是本项目视觉设计的核心关键词——既要有立体感,又要保持平面化的简洁,适合儿童审美。
5.1 棋盘立体效果
使用 CSS perspective + rotateX 让棋盘产生轻微的俯视倾斜:
.board {
transform: perspective(1000px) rotateX(8deg);
transform-style: preserve-3d;
box-shadow: 0 20px 60px rgba(0,0,0,0.5),
inset 0 2px 10px rgba(255,255,255,0.1);
}
8 度的倾斜角是反复调试的结果——太小看不出立体感,太大则棋盘上方格子变形严重影响识别。
5.2 飞机3D质感
飞机用径向渐变 + 内阴影模拟球体3D效果:
.plane.red {
background: linear-gradient(145deg, #FF6B81, #FF4757);
border: 2px solid #fff;
box-shadow: 0 3px 8px rgba(0,0,0,0.4),
inset 0 2px 3px rgba(255,255,255,0.4);
}
5.3 骰子3D翻转动画
掷骰子时骰子进行 720 度3D翻转,营造"真实投掷"的感觉:
@keyframes roll {
0% { transform: rotateX(0) rotateY(0) scale(1); }
25% { transform: rotateX(180deg) rotateY(90deg) scale(1.2); }
50% { transform: rotateX(360deg) rotateY(180deg) scale(1.1); }
75% { transform: rotateX(540deg) rotateY(270deg) scale(1.15); }
100% { transform: rotateX(720deg) rotateY(360deg) scale(1); }
}
5.4 色彩方案
面向儿童,色彩需要鲜艳活泼但不刺眼:
| 方 | 主色 | 含义 |
|---|---|---|
| 红方 | #FF4757 |
鲜红 |
| 黄方 | #FFA502 |
橙黄 |
| 蓝方 | #3742FA |
靛蓝 |
| 绿方 | #2ED573 |
翠绿 |
背景使用紫色渐变(#667eea → #764ba2),与四色形成良好对比。
六、交互设计
6.1 回合制状态机
游戏核心是一个简单的状态机:
等待掷骰 → 掷骰中 → 选择飞机 → 移动中 → (额外回合/下一玩家)
每个状态对应不同的 UI 表现:
- 等待掷骰:骰子按钮可点击,提示"请掷骰子"
- 选择飞机:可移动的飞机弹跳动画,提示"请点击要移动的飞机"
- 移动中:飞机逐格移动动画,状态栏显示移动结果
6.2 可选飞机提示
掷骰子后,能移动的飞机会上下弹跳,引导儿童点击:
.plane.selectable {
animation: bounce 0.6s infinite;
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-6px); }
}
6.3 AI 玩家
AI 采用最简单的随机决策——从可移动的飞机中随机选一架。对于儿童游戏,AI 不需要太强,能陪玩即可:
if (player.type === 'ai') {
let pick = game.selectablePlanes[
Math.floor(Math.random() * game.selectablePlanes.length)
];
selectPlane(pick.owner, pick.pid);
}
6.4 胜利庆祝
获胜时全屏彩纸雨动画 + 大字祝贺:
function showVictory(player) {
for (let i = 0; i < 50; i++) {
let c = document.createElement('div');
c.className = 'confetti';
c.style.left = Math.random() * 100 + 'vw';
c.style.background = colors[Math.floor(Math.random() * colors.length)];
c.style.animationDelay = Math.random() * 2 + 's';
overlay.appendChild(c);
}
}
七、移动动画
飞机移动不是直接"跳"到目标位置,而是逐格行走,每步 200ms,让儿童能清楚看到飞机的移动路径:
function animateMove(plane, steps, callback) {
let i = 0;
function step() {
if (i >= steps) { callback(); return; }
plane.pos = (plane.pos + 1) % 52;
renderPlanes();
i++;
setTimeout(step, 200);
}
step();
}
这个设计参考了实体飞行棋的体验——你是一格一格走过去的,不是瞬移。
八、响应式布局
棋盘和侧边面板采用 Flex 布局,在窄屏下自动垂直排列:
@media (max-width: 980px) {
.game-container { flex-direction: column; align-items: center; }
.board-wrapper { width: 95vw; height: 95vw; max-width: 600px; }
.panel { width: 95vw; max-width: 600px; }
}
九、发布到作品展览馆
开发完成后,作品通过华为云开发者作品展览馆发布,流程包括:
- Git 仓库初始化 → 推送到 GitCode
- DevBridge 隧道 → 生成公网可访问的预览地址
- 封面截图 → Playwright 自动截取游戏画面生成封面
- 详情包打包 → README 详解 + 系统架构图
- 发布上架 → 关联活动,提交到展览馆
系统架构图
┌─────────────────────────────┐
│ 纯前端单页应用 (index.html) │
└──────────────┬──────────────┘
↓
┌──────────────┴──────────────┐
│ 棋盘渲染 │ 游戏逻辑模块 │
└──────┬───────┴───────┬───────┘
↓ ↓
┌──────┴────┐ ┌───────┴───────┐
│ CSS3 3D │ │ JS 状态管理 │
│ 样式层 │ │ AI 决策 │
└──────┬────┘ └───────┬───────┘
↓ ↓
┌──────┴───────────────┴──────┐
│ 交互层 │ 动画效果层 │
└─────────────────────────────┘
十、总结与反思
做对了的
- 单文件架构:零依赖,部署极简,
python3 -m http.server即可运行 - 平面3D风格:8 度倾斜 + 渐变阴影,立体感恰到好处
- 逐格移动动画:比瞬移更符合棋盘游戏的体感
- 弹跳提示:儿童不需要看文字也能知道点哪里
可以改进的
- AI 策略:目前纯随机,可以加入"优先送飞机回家"等简单策略
- 叠飞规则:同色飞机叠在一起一起移动,当前版本未完整实现
- 音效:掷骰子、踢飞机等场景缺少音效反馈
- 移动端触控:飞机点击区域较小,触屏体验有待优化
项目数据
| 指标 | 数值 |
|---|---|
| 代码行数 | ~370 行(含 CSS) |
| 文件大小 | ~22 KB |
| 外部依赖 | 0 |
| 支持玩家 | 1-4 人(真人 + AI) |
| 棋盘格子 | 52 外圈 + 20 回家通道 + 1 终点 |
本文对应的飞行棋游戏已发布至华为云开发者作品展览馆,可通过 作品链接 查看体验。
开发日期:2026 年 10 月 21 日
- 点赞
- 收藏
- 关注作者

评论(0)