欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net

一、项目概述

运行效果图

image-20260404225123119image-20260404225132797

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

image-20260404225253103

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 整体架构图

Game Logic

Data Layer

Presentation Layer

游戏主页面

开始界面

游戏界面

结束界面

Pipe
管道模型

游戏状态
分数/最高分

游戏循环
_gameTimer

碰撞检测
_checkCollision

管道生成
_addPipe

物理更新
_updateGame

2.2 类图设计

creates

manages

uses

uses

contains

FlappyBirdApp

+Widget build()

GamePage

+Widget build()

_GamePageState

-double _birdY

-double _birdVelocity

-double _birdRotation

-List<Pipe> _pipes

-int _score

-int _highScore

-bool _gameStarted

-bool _gameOver

-Timer _gameTimer

+void _startGame()

+void _updateGame()

+void _jump()

+void _endGame()

+bool _checkCollision()

+void _addPipe()

Pipe

+double x

+double gapY

+double gapHeight

+bool scored

BirdPainter

+double wingOffset

+void paint()

+bool shouldRepaint()

PipesPainter

+List<Pipe> pipes

+double pipeWidth

+double pipeGap

+void paint()

+bool shouldRepaint()

2.3 游戏流程图

点击

碰撞

无碰撞

穿过管道

未穿过

重新开始

退出

应用启动

显示开始界面

玩家点击

开始游戏

游戏循环

更新物理

更新管道位置

生成新管道

碰撞检测

游戏结束

得分检测

加分

继续

显示结束界面

玩家选择

结束

2.4 碰撞检测流程

游戏状态 管道检测 边界检测 游戏循环 游戏状态 管道检测 边界检测 游戏循环 alt [碰撞管道] [安全通过] alt [越界碰撞] [未越界] 检测小鸟位置 判断是否越界 触发游戏结束 遍历管道列表 计算小鸟边界 计算管道间隙 判断是否在间隙内 触发游戏结束 继续游戏

三、核心模块设计

3.1 数据模型设计

3.1.1 管道模型 (Pipe)
class Pipe {
  final double x;          // 管道X坐标
  final double gapY;       // 间隙中心Y坐标
  final double gapHeight;  // 间隙高度
  bool scored;             // 是否已计分
}
3.1.2 游戏参数配置
25% 25% 25% 25% 游戏参数分布 重力加速度 跳跃力度 管道间隙 管道速度
参数 默认值 说明
_gravity 0.0005 重力加速度
_jumpStrength -0.012 跳跃力度(负值向上)
_pipeGap 180 管道间隙高度
_pipeSpeed 2 管道移动速度
_pipeWidth 60 管道宽度
_birdSize 40 小鸟尺寸

3.2 页面结构设计

3.2.1 游戏主页面

GamePage

背景层

游戏对象层

UI层

覆盖层

天空渐变

云朵装饰

地面纹理

小鸟

管道列表

分数显示

开始界面

结束界面

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 得分系统

得分条件

穿过管道

管道离开小鸟区域

标记已计分

分数+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(vk)

其中:

  • 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 后续版本规划

2024-01-07 2024-01-14 2024-01-21 2024-01-28 2024-02-04 2024-02-11 2024-02-18 2024-02-25 2024-03-03 2024-03-10 2024-03-17 核心游戏 基础UI 碰撞检测 音效系统 小鸟皮肤 排行榜 多人模式 成就系统 云端存档 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 Flappy Bird开发计划

7.2 功能扩展建议

7.2.1 音效系统

游戏音效增强体验:

  • 跳跃音效:点击屏幕时播放
  • 得分音效:穿过管道时播放
  • 碰撞音效:游戏结束时播放
  • 背景音乐:游戏进行中循环播放
7.2.2 小鸟皮肤

多种小鸟外观选择:

  • 经典黄鸟
  • 蓝色小鸟
  • 红色小鸟
  • 彩虹小鸟
7.2.3 成就系统

解锁游戏成就:

  • 首次游戏
  • 获得10分
  • 获得50分
  • 获得100分

八、注意事项

8.1 开发注意事项

  1. Timer管理:游戏结束时及时取消Timer,避免内存泄漏

  2. 碰撞检测:使用归一化坐标进行计算,确保不同屏幕尺寸下表现一致

  3. 性能优化:移除屏幕外的管道对象,减少渲染压力

  4. 状态管理:游戏状态变更时及时更新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游戏应用通过简洁的操控方式、精美的视觉效果和富有挑战性的游戏机制,为玩家提供了一个轻松有趣的休闲体验。游戏采用清新的配色风格,小鸟角色设计可爱,管道障碍物具有立体感;核心玩法简单易懂,适合各年龄段玩家;物理系统模拟真实,操作手感流畅。

核心功能涵盖完整的游戏循环,包括小鸟跳跃控制、管道随机生成、碰撞检测和计分系统。游戏中的小鸟拥有翅膀扇动动画和飞行角度旋转效果,管道采用渐变配色和高光效果增强视觉表现,地面纹理持续滚动营造飞行速度感。

通过本游戏,希望能够为玩家带来轻松愉快的休闲时光,在简单的点击操作中体验挑战自我的乐趣。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐