Flutter 框架跨平台鸿蒙开发 - Flappy Bird游戏应用
摘要: Flappy Bird是一款基于Flutter开发的跨平台休闲游戏,已在开源鸿蒙社区发布。游戏通过点击控制小鸟跳跃穿越管道障碍,核心功能包括物理引擎、碰撞检测和计分系统。采用Material Design 3规范设计,包含小鸟动画、管道生成等视觉元素。技术栈使用Dart语言和Flutter框架,支持鸿蒙OS平台。系统架构分为表现层、数据层和游戏逻辑层,采用状态机管理游戏流程。项目提供完整的
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
一、项目概述
运行效果图




1.1 应用简介
Flappy Bird是一款经典的休闲益智游戏,玩家通过控制一只可爱的小鸟在管道障碍物之间穿梭,挑战自己的反应速度和操作技巧。游戏采用简洁的操控方式,玩家只需点击屏幕即可控制小鸟向上跳跃,躲避不断出现的管道障碍,适合各年龄段玩家。
游戏提供精美的视觉效果,小鸟拥有翅膀扇动动画和飞行角度旋转效果,管道采用渐变配色增强立体感。随着游戏进行,玩家需要精准把握跳跃时机,让小鸟安全穿过管道之间的空隙,每成功穿过一组管道即可获得一分。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 小鸟控制 | 点击屏幕控制跳跃 | GestureDetector |
| 物理引擎 | 重力下落与跳跃 | 自定义物理系统 |
| 管道生成 | 随机生成管道障碍 | Timer + 随机算法 |
| 碰撞检测 | 检测碰撞管道/边界 | 矩形碰撞检测 |
| 计分系统 | 穿过管道获得分数 | 状态管理 |
| 最高分 | 记录游戏最高分 | 本地存储 |
| 游戏状态 | 开始/进行/结束 | 状态机管理 |
1.3 游戏元素
| 元素 | 描述 | 视觉特点 |
|---|---|---|
| 小鸟 | 玩家控制的角色 | 黄色圆形,带翅膀动画 |
| 管道 | 需要躲避的障碍物 | 绿色渐变,带高光效果 |
| 云朵 | 背景装饰元素 | 白色半透明 |
| 地面 | 底部滚动纹理 | 草地绿色方块 |
1.4 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 设计规范 | Material Design 3 | - |
| 状态管理 | setState | - |
| 目标平台 | 鸿蒙OS | API 21+ |
1.5 项目结构
lib/
└── main_flappy_bird.dart
├── FlappyBirdApp # 应用入口
├── GamePage # 游戏主页面
├── Pipe # 管道数据模型
├── BirdPainter # 小鸟绘制器
├── PipesPainter # 管道绘制器
└── AnimatedBuilder # 动画构建器
二、系统架构
2.1 整体架构图
2.2 类图设计
2.3 游戏流程图
2.4 碰撞检测流程
三、核心模块设计
3.1 数据模型设计
3.1.1 管道模型 (Pipe)
class Pipe {
final double x; // 管道X坐标
final double gapY; // 间隙中心Y坐标
final double gapHeight; // 间隙高度
bool scored; // 是否已计分
}
3.1.2 游戏参数配置
| 参数 | 默认值 | 说明 |
|---|---|---|
| _gravity | 0.0005 | 重力加速度 |
| _jumpStrength | -0.012 | 跳跃力度(负值向上) |
| _pipeGap | 180 | 管道间隙高度 |
| _pipeSpeed | 2 | 管道移动速度 |
| _pipeWidth | 60 | 管道宽度 |
| _birdSize | 40 | 小鸟尺寸 |
3.2 页面结构设计
3.2.1 游戏主页面
3.2.2 游戏状态流转
3.3 游戏逻辑设计
3.3.1 核心状态变量
class _GamePageState extends State<GamePage> with TickerProviderStateMixin {
// 小鸟状态
double _birdY = 0; // 垂直位置
double _birdVelocity = 0; // 垂直速度
double _birdRotation = 0; // 旋转角度
// 游戏参数
final double _gravity = 0.0005;
final double _jumpStrength = -0.012;
final double _birdSize = 40;
// 管道参数
List<Pipe> _pipes = [];
final double _pipeWidth = 60;
final double _pipeGap = 180;
final double _pipeSpeed = 2;
// 游戏状态
int _score = 0;
int _highScore = 0;
bool _gameStarted = false;
bool _gameOver = false;
// 动画控制器
late AnimationController _birdController;
Timer? _gameTimer;
}
3.3.2 游戏循环逻辑
void _updateGame() {
if (_gameOver) return;
setState(() {
// 应用重力
_birdVelocity += _gravity;
_birdY += _birdVelocity;
// 更新旋转角度
_birdRotation = _birdVelocity * 500;
_birdRotation = _birdRotation.clamp(-90, 90);
// 更新地面滚动
_groundOffset += _pipeSpeed;
if (_groundOffset >= 24) _groundOffset = 0;
// 生成新管道
if (_pipes.isEmpty || _pipes.last.x < 200) {
_addPipe();
}
// 更新管道位置
for (var pipe in _pipes) {
pipe.x -= _pipeSpeed;
}
// 移除屏幕外管道
_pipes.removeWhere((pipe) => pipe.x < -_pipeWidth);
// 计分检测
for (var pipe in _pipes) {
if (!pipe.scored && pipe.x + _pipeWidth < 100) {
pipe.scored = true;
_score++;
}
}
// 碰撞检测
if (_checkCollision()) {
_endGame();
}
});
}
四、UI设计规范
4.1 配色方案
游戏采用清新明亮的配色风格,营造轻松愉快的游戏氛围:
| 颜色类型 | 色值 | 用途 |
|---|---|---|
| 天空色 | #4EC0CA | 背景渐变上部 |
| 地面色 | #DED895 | 背景渐变下部 |
| 管道主色 | #73BF2E | 管道渐变起始 |
| 管道深色 | #4A8C1C | 管道渐变结束 |
| 小鸟身体 | #F7DC6F | 小鸟主体颜色 |
| 小鸟边框 | #D4AC0D | 小鸟轮廓颜色 |
| 小鸟嘴巴 | #E74C3C | 嘴巴颜色 |
4.2 字体规范
| 元素 | 字号 | 字重 | 颜色 |
|---|---|---|---|
| 游戏标题 | 48px | Bold | #FFFFFF |
| 分数显示 | 48px | Bold | #FFFFFF |
| 提示文字 | 20px | Medium | #00000087 |
| 最高分 | 16px | Regular | #9E9E9E |
| 按钮文字 | 20px | Bold | #FFFFFF |
4.3 组件规范
4.3.1 小鸟绘制
┌─────────────┐
│ ◉ ←眼睛 │
│ ╱ │
│ ●────────▷ │ ←嘴巴
│ ╲˜˜˜˜˜˜ │ ←翅膀
└─────────────┘
4.3.2 管道绘制
┌──────────────────┐
│ ████████████████ │ ←管道帽
├──────────────────┤
│ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │
│ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │ ←管道主体
│ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │
│ ... │
4.3.3 游戏界面布局
┌─────────────────────────────────────────────────┐
│ ☁️ ☁️ │
│ │
│ 100 │ ←分数
│ │
│ ┌────┐ │
│ │ │ │
│ │ │ 🐤 │ ←小鸟
│ │ │ │
│ └────┘ │
│ ┌────┐ │
│ │ │ │
│ │ │ │
│ └────┘ │
│ │
│ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │ ←地面
└─────────────────────────────────────────────────┘
4.3.4 开始界面
┌─────────────────────────────────────────────────┐
│ │
│ Flappy Bird │
│ │
│ ┌───────────────────┐ │
│ │ 👆 │ │
│ │ 点击屏幕开始游戏 │ │
│ │ 最高分: 50 │ │
│ └───────────────────┘ │
│ │
└─────────────────────────────────────────────────┘
4.3.5 结束界面
┌─────────────────────────────────────────────────┐
│ │
│ 游戏结束 │
│ │
│ ┌───────────────────┐ │
│ │ 得分: 100 │ │
│ │ 最高分: 150 │ │
│ │ ⭐ 新纪录! │ │
│ │ │ │
│ │ [ 重新开始 ] │ │
│ └───────────────────┘ │
│ │
└─────────────────────────────────────────────────┘
五、核心功能实现
5.1 小鸟跳跃
void _jump() {
if (_gameOver) {
_startGame();
return;
}
if (!_gameStarted) {
_startGame();
return;
}
setState(() {
_birdVelocity = _jumpStrength;
});
}
5.2 管道生成
void _addPipe() {
final random = math.Random();
// 间隙中心位置随机范围 [-0.4, 0.4]
final minGapY = -0.4;
final maxGapY = 0.4;
final gapY = minGapY + random.nextDouble() * (maxGapY - minGapY);
_pipes.add(Pipe(
x: 400, // 从屏幕右侧生成
gapY: gapY, // 随机间隙位置
gapHeight: _pipeGap / 400, // 间隙高度
));
}
5.3 碰撞检测
bool _checkCollision() {
// 边界碰撞检测
if (_birdY > 0.85 || _birdY < -0.95) {
return true;
}
// 管道碰撞检测
for (var pipe in _pipes) {
// 计算管道在屏幕上的位置
final pipeLeft = (pipe.x - 100) / 200;
final pipeRight = (pipe.x + _pipeWidth - 100) / 200;
// 检查小鸟是否在管道X范围内
if (pipeLeft < 0.15 && pipeRight > -0.15) {
final birdTop = _birdY - 0.08;
final birdBottom = _birdY + 0.08;
final gapTop = pipe.gapY + pipe.gapHeight / 2;
final gapBottom = pipe.gapY - pipe.gapHeight / 2;
// 检查小鸟是否在间隙外
if (birdTop > gapTop || birdBottom < gapBottom) {
return true;
}
}
}
return false;
}
5.4 小鸟绘制
class BirdPainter extends CustomPainter {
final double wingOffset;
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
// 绘制身体
final bodyPaint = Paint()..color = Color(0xFFF7DC6F);
canvas.drawCircle(center, radius, bodyPaint);
// 绘制翅膀(带动画)
final wingPath = Path();
wingPath.moveTo(center.dx - 5, center.dy + 5);
wingPath.quadraticBezierTo(
center.dx - 15, center.dy + wingOffset,
center.dx - 20, center.dy + wingOffset - 5,
);
canvas.drawPath(wingPath, wingPaint);
// 绘制眼睛
canvas.drawCircle(Offset(center.dx + 8, center.dy - 5), 8, eyeWhitePaint);
canvas.drawCircle(Offset(center.dx + 10, center.dy - 5), 4, eyeBlackPaint);
// 绘制嘴巴
final beakPath = Path();
beakPath.moveTo(center.dx + radius - 5, center.dy);
beakPath.lineTo(center.dx + radius + 10, center.dy + 3);
beakPath.lineTo(center.dx + radius - 5, center.dy + 8);
canvas.drawPath(beakPath, beakPaint);
}
}
5.5 管道绘制
class PipesPainter extends CustomPainter {
final List<Pipe> pipes;
void paint(Canvas canvas, Size size) {
for (var pipe in pipes) {
final gapCenterY = size.height * 0.5 + pipe.gapY * playableHeight * 0.8;
final gapTop = gapCenterY - pipeGap / 2;
final gapBottom = gapCenterY + pipeGap / 2;
// 绘制上方管道
_drawPipe(canvas, pipe.x, 0, gapTop, isTop: true);
// 绘制下方管道
_drawPipe(canvas, pipe.x, gapBottom, size.height - gapBottom, isTop: false);
}
}
void _drawPipe(Canvas canvas, double x, double y, double height, bool isTop) {
// 渐变填充
final pipePaint = Paint()
..shader = LinearGradient(
colors: [Color(0xFF73BF2E), Color(0xFF5DA423), Color(0xFF4A8C1C)],
).createShader(Rect.fromLTWH(x, y, pipeWidth, height));
// 绘制管道主体
canvas.drawRRect(RRect.fromRectAndRadius(rect, Radius.circular(4)), pipePaint);
// 绘制管道帽
// ...
// 绘制高光
final highlightPaint = Paint()..color = Colors.white.withOpacity(0.2);
canvas.drawRect(Rect.fromLTWH(x + 5, y, 8, height), highlightPaint);
}
}
六、游戏机制
6.1 得分系统
6.2 物理系统
小鸟的运动遵循简化的物理公式:
v n + 1 = v n + g ⋅ Δ t v_{n+1} = v_n + g \cdot \Delta t vn+1=vn+g⋅Δt
y n + 1 = y n + v n + 1 ⋅ Δ t y_{n+1} = y_n + v_{n+1} \cdot \Delta t yn+1=yn+vn+1⋅Δt
θ = arctan ( v ⋅ k ) \theta = \arctan(v \cdot k) θ=arctan(v⋅k)
其中:
- v v v 为垂直速度
- g g g 为重力加速度
- y y y 为垂直位置
- θ \theta θ 为旋转角度
- k k k 为旋转系数
6.3 难度设计
| 参数 | 简单模式 | 普通模式 | 困难模式 |
|---|---|---|---|
| 重力 | 0.0004 | 0.0005 | 0.0006 |
| 间隙 | 200 | 180 | 160 |
| 速度 | 1.5 | 2.0 | 3.0 |
七、扩展功能规划
7.1 后续版本规划
7.2 功能扩展建议
7.2.1 音效系统
游戏音效增强体验:
- 跳跃音效:点击屏幕时播放
- 得分音效:穿过管道时播放
- 碰撞音效:游戏结束时播放
- 背景音乐:游戏进行中循环播放
7.2.2 小鸟皮肤
多种小鸟外观选择:
- 经典黄鸟
- 蓝色小鸟
- 红色小鸟
- 彩虹小鸟
7.2.3 成就系统
解锁游戏成就:
- 首次游戏
- 获得10分
- 获得50分
- 获得100分
八、注意事项
8.1 开发注意事项
-
Timer管理:游戏结束时及时取消Timer,避免内存泄漏
-
碰撞检测:使用归一化坐标进行计算,确保不同屏幕尺寸下表现一致
-
性能优化:移除屏幕外的管道对象,减少渲染压力
-
状态管理:游戏状态变更时及时更新UI
8.2 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 小鸟越界 | 位置未限制 | 碰撞检测添加边界判断 |
| 碰撞不准 | 边界计算错误 | 检查归一化坐标计算 |
| 游戏卡顿 | 对象未清理 | 移除屏幕外管道 |
| 分数异常 | 重复计分 | 使用scored标记防止重复 |
8.3 游戏提示
🐤 游戏小贴士 🐤
保持节奏,不要急于点击。
观察管道间隙位置,提前规划。
小鸟下落时角度会变化,注意控制。
坚持练习,突破自己的最高分!
九、运行说明
9.1 环境要求
| 环境 | 版本要求 |
|---|---|
| Flutter SDK | >= 3.0.0 |
| Dart SDK | >= 2.17.0 |
| 鸿蒙OS | API 21+ |
9.2 运行命令
# 查看可用设备
flutter devices
# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_flappy_bird.dart
# 运行到Web服务器
flutter run -d web-server -t lib/main_flappy_bird.dart --web-port 8080
# 运行到Windows
flutter run -d windows -t lib/main_flappy_bird.dart
# 代码分析
flutter analyze lib/main_flappy_bird.dart
十、总结
Flappy Bird游戏应用通过简洁的操控方式、精美的视觉效果和富有挑战性的游戏机制,为玩家提供了一个轻松有趣的休闲体验。游戏采用清新的配色风格,小鸟角色设计可爱,管道障碍物具有立体感;核心玩法简单易懂,适合各年龄段玩家;物理系统模拟真实,操作手感流畅。
核心功能涵盖完整的游戏循环,包括小鸟跳跃控制、管道随机生成、碰撞检测和计分系统。游戏中的小鸟拥有翅膀扇动动画和飞行角度旋转效果,管道采用渐变配色和高光效果增强视觉表现,地面纹理持续滚动营造飞行速度感。
通过本游戏,希望能够为玩家带来轻松愉快的休闲时光,在简单的点击操作中体验挑战自我的乐趣。
更多推荐
所有评论(0)