Flutter 框架跨平台鸿蒙开发 - 连连看游戏应用

连连看游戏应用


欢迎加入开源鸿蒙跨平台社区:

https://openharmonycrossplatform.csdn.net

一、项目概述

运行效果图



1.1 应用简介

连连看是一款经典的消除类益智游戏,玩家需要在棋盘上找到两个相同的图案,并且它们之间可以用不超过两个拐点的路径连接起来,成功连接后即可消除。游戏以紫色为主色调,传递神秘、优雅的品牌形象。

应用支持多种水果图案,包含计时、计分、提示、洗牌等功能,通过精美的动画效果和流畅的交互体验,为玩家带来愉悦的游戏感受。

1.2 核心功能

功能模块 功能描述 实现方式
游戏棋盘 8x6格子的游戏区域 GridView
路径检测 判断两个图案是否可连接 算法检测
连接动画 显示连接路径动画 CustomPainter
计时系统 倒计时游戏时间 Timer
计分系统 根据时间和步数计分 公式计算
提示功能 提示可消除的配对 遍历查找
洗牌功能 重新排列未消除的图案 随机打乱

1.3 游戏规则

规则名称 规则描述
配对消除 选择两个相同图案进行消除
路径限制 连接路径最多只能有两个拐点
时间限制 每关有180秒的时间限制
得分规则 基础分+时间奖励分

1.4 技术栈

技术领域 技术选型 版本要求
开发框架 Flutter >= 3.0.0
编程语言 Dart >= 2.17.0
设计规范 Material Design 3 -
状态管理 setState -
目标平台 鸿蒙OS / Web API 21+

1.5 项目结构

复制代码
lib/
└── main_link_game.dart
    ├── LinkGameApp           # 应用入口
    ├── TileType              # 图案类型模型
    ├── Tile                  # 格子数据模型
    ├── MainPage              # 主页面(底部导航)
    ├── GamePage              # 游戏页面
    ├── LevelsPage            # 关卡选择页面
    └── ProfilePage           # 个人中心页面

二、系统架构

2.1 整体架构图

Data Layer
Business Layer
Presentation Layer
主页面

MainPage
游戏页面
关卡页面
个人中心
游戏棋盘
计分系统
计时系统
提示功能
洗牌功能
关卡列表
难度选择
游戏记录
排行榜
路径检测算法
连接动画
得分计算
Tile

格子模型
TileType

图案模型

2.2 类图设计

contains
manages
uses
LinkGameApp
+Widget build()
TileType
+int id
+String emoji
+Color color
Tile
+int row
+int col
+int typeId
+bool isMatched
+bool isSelected
MainPage
-int _currentIndex
+Widget build()
GamePage
-List<List<Tile>> _board
-Tile? _selectedTile
-int _score
-int _moves
-int _timeLeft
-bool _isPlaying
+void _initGame()
+void _onTileTap()
+List<Offset>? _findPath()
+void _useHint()
+void _shuffle()

2.3 游戏流程图

点击








超时
开始游戏
生成棋盘
显示图案
选择图案
标记选中
是否已选中其他图案?
等待选择第二个
图案是否相同?
切换选中状态
路径是否可连接?
显示连接路径
消除图案
是否全部消除?
游戏胜利
游戏失败

2.4 路径检测算法







开始检测
是否相邻?
直接连接
是否可一个拐点连接?
一个拐点路径
是否可两个拐点连接?
两个拐点路径
无法连接
返回路径
返回null


三、核心模块设计

3.1 数据模型设计

3.1.1 图案类型模型 (TileType)
dart 复制代码
class TileType {
  final int id;              // 类型ID
  final String emoji;        // 表情符号
  final Color color;         // 背景颜色
}
3.1.2 格子模型 (Tile)
dart 复制代码
class Tile {
  final int row;             // 行号
  final int col;             // 列号
  int typeId;                // 图案类型ID
  bool isMatched;            // 是否已消除
  bool isSelected;           // 是否被选中
}
3.1.3 图案类型列表

应用包含16种水果图案:

ID 图案 背景色
1 🍎 浅红色
2 🍊 浅橙色
3 🍋 浅黄色
4 🍇 浅紫色
5 🍓 粉红色
6 🍑 浅橙色
7 🥝 浅绿色
8 🍒 红色
9 🍌 黄色
10 🥭 橙色
11 🍍 浅黄色
12 🫐 浅蓝色
13 🍉 红色
14 🥥 浅棕色
15 🍈 浅绿色
16 🍐 浅绿色

3.2 路径检测算法

3.2.1 直接路径检测
dart 复制代码
List<Offset>? _findDirectPath(Tile start, Tile end) {
  // 检查是否在同一行或同一列
  if (start.row == end.row) {
    // 检查行路径是否畅通
    for (int c = min(start.col, end.col) + 1; c < max(start.col, end.col); c++) {
      if (!_isCellEmpty(start.row, c)) return null;
    }
    return [Offset(start.col, start.row), Offset(end.col, end.row)];
  }
  // 类似处理列路径...
}
3.2.2 一个拐点路径检测
dart 复制代码
List<Offset>? _findOneCornerPath(Tile start, Tile end) {
  // 尝试通过中间点连接
  if (_isCellEmpty(start.row, end.col)) {
    final corner = Tile(row: start.row, col: end.col);
    final path1 = _findDirectPath(start, corner);
    final path2 = _findDirectPath(corner, end);
    if (path1 != null && path2 != null) {
      return [Offset(start.col, start.row), Offset(end.col, start.row), Offset(end.col, end.row)];
    }
  }
  // 尝试另一种拐点...
}
3.2.3 两个拐点路径检测
dart 复制代码
List<Offset>? _findTwoCornerPath(Tile start, Tile end) {
  // 遍历所有可能的中间列
  for (int c = -1; c <= cols; c++) {
    if (_isCellEmpty(start.row, c) || c == -1 || c == cols) {
      // 检查路径是否畅通...
    }
  }
  // 遍历所有可能的中间行...
}

3.3 得分计算

得分=基础分+时间奖励 得分 = 基础分 + 时间奖励 得分=基础分+时间奖励

基础分=10 基础分 = 10 基础分=10

时间奖励=⌊剩余时间10⌋ 时间奖励 = \lfloor \frac{剩余时间}{10} \rfloor 时间奖励=⌊10剩余时间⌋


四、UI设计规范

4.1 配色方案

应用采用紫色为主色调,传递神秘、优雅的品牌形象:

颜色类型 色值 用途
主色 #673AB7 (Purple) 导航、强调元素
渐变起始 #673AB7 头部渐变
渐变结束 #9575CD 头部渐变
成功色 #4CAF50 消除成功
警告色 #FF9800 时间警告
背景色 #F5F5F5 页面背景

4.2 字体规范

元素 字号 字重 颜色
页面标题 20px Medium #000000
得分数字 24px Bold 主题色
时间数字 16px Medium #757575
图案表情 28px Regular -

4.3 组件规范

4.3.1 游戏格子
复制代码
┌─────────────────────┐
│                     │
│    🍎              │
│                     │
│   [选中时显示边框]  │
│                     │
└─────────────────────┘
4.3.2 连接路径
复制代码
┌─────────────────────────────────────────┐
│                                         │
│   🍎 ──────────────┐                   │
│                     │                   │
│                     │                   │
│                     └────────── 🍎     │
│                                         │
└─────────────────────────────────────────┘
4.3.3 游戏信息栏
复制代码
┌─────────────────────────────────────────┐
│  得分: 150      步数: 12      时间: 120s │
└─────────────────────────────────────────┘

五、核心功能实现

5.1 棋盘生成实现

dart 复制代码
List<List<Tile>> _generateBoard() {
  final totalTiles = rows * cols;
  final pairCount = totalTiles ~/ 2;
  final typesNeeded = min(pairCount, tileTypes.length);
  
  List<int> types = [];
  for (int i = 0; i < pairCount; i++) {
    final typeId = (i % typesNeeded) + 1;
    types.add(typeId);
    types.add(typeId);  // 成对添加
  }
  
  types.shuffle();  // 随机打乱
  
  // 创建棋盘...
}

5.2 路径查找实现

dart 复制代码
List<Offset>? _findPath(Tile start, Tile end) {
  if (start.typeId != end.typeId) return null;
  if (start.isMatched || end.isMatched) return null;
  
  // 尝试直接连接
  final directPath = _findDirectPath(start, end);
  if (directPath != null) return directPath;
  
  // 尝试一个拐点连接
  final oneCornerPath = _findOneCornerPath(start, end);
  if (oneCornerPath != null) return oneCornerPath;
  
  // 尝试两个拐点连接
  final twoCornerPath = _findTwoCornerPath(start, end);
  if (twoCornerPath != null) return twoCornerPath;
  
  return null;
}

5.3 连接动画实现

dart 复制代码
class PathPainter extends CustomPainter {
  final List<Offset> path;
  final Animation<double> animation;
  
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.green
      ..strokeWidth = 4
      ..style = PaintingStyle.stroke;
    
    final pathToDraw = Path();
    for (int i = 0; i < path.length - 1; i++) {
      final start = path[i];
      final end = path[i + 1];
      pathToDraw.moveTo(start.dx, start.dy);
      pathToDraw.lineTo(end.dx, end.dy);
    }
    
    canvas.drawPath(pathToDraw, paint);
  }
}

5.4 提示功能实现

dart 复制代码
void _useHint() {
  for (int r1 = 0; r1 < rows; r1++) {
    for (int c1 = 0; c1 < cols; c1++) {
      if (_board[r1][c1].isMatched) continue;
      for (int r2 = 0; r2 < rows; r2++) {
        for (int c2 = 0; c2 < cols; c2++) {
          if (r1 == r2 && c1 == c2) continue;
          if (_board[r2][c2].isMatched) continue;
          if (_board[r1][c1].typeId != _board[r2][c2].typeId) continue;
          
          final path = _findPath(_board[r1][c1], _board[r2][c2]);
          if (path != null) {
            // 高亮显示这对图案
            return;
          }
        }
      }
    }
  }
  // 没有可消除的配对
}

5.5 洗牌功能实现

dart 复制代码
void _shuffle() {
  List<Tile> unmatchedTiles = [];
  for (var row in _board) {
    for (var tile in row) {
      if (!tile.isMatched) {
        unmatchedTiles.add(tile);
      }
    }
  }
  
  List<int> types = unmatchedTiles.map((t) => t.typeId).toList();
  types.shuffle();  // 随机打乱类型
  
  for (int i = 0; i < unmatchedTiles.length; i++) {
    unmatchedTiles[i].typeId = types[i];
  }
}

六、交互设计

6.1 图案选择流程

动画 状态 棋盘 用户 动画 状态 棋盘 用户 alt [图案相同] [图案不同] alt [无选中图案] [已有选中图案] 点击图案 检查当前选中状态 标记为选中 检查图案是否相同 显示连接路径 消除图案 更新棋盘 切换选中状态

6.2 游戏计时流程

点击开始
倒计时
点击暂停
点击继续
全部消除
时间耗尽
准备开始
游戏中
暂停
胜利
失败

6.3 关卡进度流程

胜利


失败


开始关卡
显示目标
游戏进行中
是否完成?
计算得分
显示结果
是否继续?
进入下一关
返回关卡列表
显示失败
是否重试?


七、扩展功能规划

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 基础游戏 路径检测 动画效果 计分系统 多种图案 关卡系统 音效系统 多人对战 排行榜 成就系统 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 连连看游戏开发计划

7.2 功能扩展建议

7.2.1 多人对战模式

增强游戏趣味:

  • 实时对战
  • 轮流操作
  • 道具干扰
7.2.2 关卡编辑器

自定义关卡:

  • 自定义图案
  • 自定义布局
  • 分享关卡
7.2.3 成就系统

增加游戏粘性:

  • 连胜成就
  • 速度成就
  • 收集成就

八、注意事项

8.1 开发注意事项

  1. 路径检测:确保路径检测算法正确处理边界情况

  2. 动画流畅:连接动画需要流畅不卡顿

  3. 状态同步:选中状态和消除状态需要及时更新

  4. 性能优化:大量图案时注意渲染性能

8.2 常见问题

问题 原因 解决方案
路径检测错误 边界条件处理不当 检查边界判断逻辑
动画卡顿 重绘过于频繁 使用RepaintBoundary
无法消除 洗牌后无可消除配对 检测并重新洗牌
内存泄漏 动画未释放 正确释放AnimationController

8.3 使用提示

🎮 连连看游戏技巧 🎮

眼疾手快:快速找到相同图案。

规划路径:注意路径是否有阻挡。

善用提示:卡住时使用提示功能。

合理洗牌:图案太乱时及时洗牌。


九、运行说明

9.1 环境要求

环境 版本要求
Flutter SDK >= 3.0.0
Dart SDK >= 2.17.0
鸿蒙OS API 21+

9.2 运行命令

bash 复制代码
# 查看可用设备
flutter devices

# 运行到Web服务器
flutter run -d web-server -t lib/main_link_game.dart --web-port 8102

# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_link_game.dart

# 运行到Windows
flutter run -d windows -t lib/main_link_game.dart

# 代码分析
flutter analyze lib/main_link_game.dart

十、总结

连连看游戏通过经典的消除玩法,为玩家提供了一个休闲益智的娱乐体验。游戏支持16种水果图案,8x6的游戏棋盘,玩家需要在限定时间内消除所有图案。

核心功能涵盖游戏棋盘、路径检测、连接动画、计时计分、提示洗牌五大模块。游戏棋盘随机生成成对的图案;路径检测算法支持直连、一个拐点、两个拐点三种连接方式;连接动画通过CustomPainter绘制路径;计时计分系统增加游戏紧张感;提示和洗牌功能帮助玩家突破困境。

游戏采用Material Design 3设计规范,以紫色为主色调,界面优雅简洁。通过本游戏,希望能够为玩家带来愉悦的休闲时光。

经典连连看,休闲益智

相关推荐
程序员老刘3 小时前
AI时代我们是否还需要学编程?丨《Flutter跨平台开发核心技巧与应用》新书上市啦
flutter·ai编程·客户端
浮芷.3 小时前
Flutter 框架跨平台鸿蒙开发 - flutter版本样式的美食菜谱应用
flutter·harmonyos·美食
Swift社区3 小时前
鸿蒙游戏开发踩坑实录
华为·harmonyos
小雨天気.4 小时前
Flutter 框架跨平台鸿蒙开发 - 生活中的书法练习应用开发文档
flutter·生活·harmonyos
2301_822703205 小时前
开源鸿蒙跨平台Flutter开发:FASTA 格式解析进阶:序列校验与异常处理机制实现
flutter·华为·开源·鸿蒙
AI_零食5 小时前
Flutter 框架跨平台鸿蒙开发 - 鸿蒙麻将游戏应用
学习·flutter·游戏·华为·交互·harmonyos
dragon7255 小时前
Flutter错误处理机制
前端·flutter
互联网散修6 小时前
鸿蒙原生实战:智感握姿 – 左右手自动适配新闻列表
华为·harmonyos·手持握姿检测
独特的螺狮粉6 小时前
Flutter 框架跨平台鸿蒙开发 - 睡眠白噪音开发纪录
flutter·华为·harmonyos·鸿蒙