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

一、项目概述

运行效果图

1

2

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

4

5

1.1 应用简介

打地鼠是一款经典的休闲益智游戏,考验玩家的反应速度和手眼协调能力。游戏采用清新的绿色草地主题,配合可爱的地鼠形象,为玩家带来轻松愉快的游戏体验。无论是打发碎片时间,还是挑战高分记录,这款游戏都能让玩家沉浸其中。

游戏设有三种地鼠类型:普通地鼠、金色地鼠和炸弹。普通地鼠击中得10分,金色地鼠击中得50分但出现时间短,炸弹击中扣30分需要避开。配合连击系统和三种难度选择,让游戏既有休闲性又有挑战性。60秒限时模式让每一局都紧张刺激,历史记录功能帮助玩家追踪自己的进步。

1.2 核心功能

功能模块 功能描述 实现方式
游戏主体 60秒限时打地鼠 Timer定时器
三种地鼠 普通/金色/炸弹 MoleType枚举
难度选择 简单/中等/困难 Difficulty枚举
连击系统 连续击中奖励 combo计数器
历史记录 游戏成绩排行 GameResult模型
暂停继续 游戏状态管理 GameState枚举

1.3 地鼠类型概览

地鼠类型 英文标识 分值 出现概率 停留时间
普通地鼠 normal +10 80% 1.5秒
金色地鼠 golden +50 10% 0.8秒
炸弹 bomb -30 10% 2.0秒

1.4 难度设置

难度 英文标识 地鼠出现间隔
简单 easy 1200毫秒
中等 medium 800毫秒
困难 hard 500毫秒

1.5 技术栈

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

1.6 项目结构

lib/
└── main_whack_a_mole.dart
    ├── WhackAMoleApp          # 应用入口
    ├── GameState              # 游戏状态枚举
    ├── Difficulty             # 难度枚举
    ├── MoleType               # 地鼠类型枚举
    ├── Mole                   # 地鼠模型
    ├── GameResult             # 游戏结果模型
    ├── HomePage               # 主页面
    │   ├── _buildStartScreen()  # 开始界面
    │   ├── _buildGameScreen()   # 游戏界面
    │   └── _buildGameField()    # 游戏区域
    └── 动画控制器             # 击中动画效果

二、系统架构

2.1 整体架构图

Data Layer

Game Logic

Presentation Layer

开始界面

游戏界面

结束界面

历史记录

地鼠生成器
_spawnMole

计时器
_countdownTimer

碰撞检测
_hitMole

分数计算
_score

Mole
地鼠数据

GameResult
游戏结果

MoleType
地鼠类型

2.2 类图设计

contains

manages

records

uses

uses

has

WhackAMoleApp

+Widget build()

HomePage

-GameState _gameState

-Difficulty _difficulty

-int _score

-int _timeLeft

-int _combo

-int _maxCombo

-List<Mole?> _moles

-Timer? _gameTimer

-Timer? _moleTimer

-Timer? _countdownTimer

-List<GameResult> _history

+Widget build()

-void _startGame()

-void _pauseGame()

-void _resumeGame()

-void _endGame()

-void _spawnMole()

-void _hitMole()

Mole

+int holeIndex

+MoleType type

+DateTime appearTime

+bool isHit

+int get score

+int get duration

GameResult

+int score

+int hits

+int misses

+int goldenHits

+int bombHits

+int combo

+DateTime date

«enumeration»

GameState

idle

playing

paused

finished

«enumeration»

Difficulty

easy

medium

hard

«enumeration»

MoleType

normal

golden

bomb

2.3 数据流程图

击中地鼠

击中炸弹

错过

游戏开始

启动计时器

地鼠生成循环

玩家点击

加分+连击

扣分+重置连击

增加错过数

更新UI

时间是否结束

保存结果

显示结束界面

2.4 游戏流程

计时器 地鼠生成器 游戏界面 开始界面 用户 计时器 地鼠生成器 游戏界面 开始界面 用户 loop [每隔一定时间] 选择难度 点击开始 切换界面 启动60秒倒计时 启动生成循环 随机位置生成地鼠 点击地鼠 计算得分 时间结束 显示结果弹窗

三、核心模块设计

3.1 数据模型设计

3.1.1 地鼠模型 (Mole)
class Mole {
  final int holeIndex;       // 所在洞口索引(0-8)
  final MoleType type;       // 地鼠类型
  final DateTime appearTime; // 出现时间
  bool isHit;                // 是否被击中
  
  int get score;             // 得分(根据类型)
  int get duration;          // 停留时间(毫秒)
}
3.1.2 游戏结果模型 (GameResult)
class GameResult {
  final int score;           // 总得分
  final int hits;            // 击中次数
  final int misses;          // 错过次数
  final int goldenHits;      // 金色地鼠击中数
  final int bombHits;        // 炸弹击中数
  final int combo;           // 最大连击
  final DateTime date;       // 游戏日期
}
3.1.3 游戏状态枚举 (GameState)

应用启动

开始游戏

暂停

继续

时间结束

返回首页

再来一局

idle

playing

paused

finished

3.2 游戏逻辑设计

3.2.1 地鼠生成算法

生成地鼠

获取空闲洞口

有空闲洞口?

等待下次生成

随机选择洞口

随机选择地鼠类型

创建Mole对象

设置消失定时器

更新UI显示

3.2.2 地鼠类型概率
80% 10% 10% 地鼠类型出现概率 普通地鼠 金色地鼠 炸弹
3.2.3 得分计算规则
情况 分数变化 连击变化
击中普通地鼠 +10 +1
击中金色地鼠 +50 +1
击中炸弹 -30 重置为0
错过普通地鼠 0 重置为0
连击达到5的倍数 +连击数×5 -

3.3 页面结构设计

3.3.1 开始界面

开始界面

游戏图标

游戏标题

难度选择

开始按钮

历史记录入口

简单

中等

困难

3.3.2 游戏界面

游戏界面

顶部状态栏

游戏区域

底部控制栏

分数显示

倒计时

连击数

3x3洞口网格

地鼠显示

暂停/继续

结束游戏

3.4 状态管理

3.4.1 核心状态变量
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
  GameState _gameState = GameState.idle;      // 游戏状态
  Difficulty _difficulty = Difficulty.medium; // 难度
  int _score = 0;                              // 当前分数
  int _timeLeft = 60;                          // 剩余时间
  int _combo = 0;                              // 当前连击
  int _maxCombo = 0;                           // 最大连击
  int _hits = 0;                               // 击中数
  int _misses = 0;                             // 错过数
  int _goldenHits = 0;                         // 金色击中数
  int _bombHits = 0;                           // 炸弹击中数
  final List<Mole?> _moles = List.filled(9, null); // 9个洞口
  final List<GameResult> _history = [];        // 历史记录
}
3.4.2 计时器管理
void _startGame() {
  // 初始化状态
  _score = 0;
  _timeLeft = 60;
  _combo = 0;
  
  // 启动倒计时
  _countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
    _timeLeft--;
    if (_timeLeft <= 0) _endGame();
  });
  
  // 启动地鼠生成
  _moleTimer = Timer.periodic(Duration(milliseconds: _getSpawnInterval()), (timer) {
    _spawnMole();
  });
}

四、UI设计规范

4.1 配色方案

游戏采用草地主题配色:

颜色类型 色值 用途
主色 Brown (Material) 按钮、标题
草地绿 Green.shade300-600 背景渐变
泥土棕 Brown.shade300-600 洞口、地鼠
金色 Amber 金色地鼠、星星
炸弹灰 Grey.shade700 炸弹

4.2 字体规范

元素 字号 字重 颜色
游戏标题 48px Bold #FFFFFF
分数数字 24px Bold #FFFFFF
倒计时 24px Bold #FFFFFF
连击数 20px Bold #FFFFFF
按钮文字 16-20px Bold #FFFFFF

4.3 组件规范

4.3.1 开始界面
┌─────────────────────────────────────────────────┐
│                                                 │
│                   🐹                            │
│                                                 │
│                 打地鼠                          │
│           点击地鼠得分,小心炸弹!              │
│                                                 │
│         ┌─────────────────────────┐            │
│         │    选择难度              │            │
│         │  简单   中等   困难      │            │
│         └─────────────────────────┘            │
│                                                 │
│         ┌─────────────────────────┐            │
│         │       开始游戏          │            │
│         └─────────────────────────┘            │
│                                                 │
│               历史记录                         │
│                                                 │
└─────────────────────────────────────────────────┘
4.3.2 游戏界面
┌─────────────────────────────────────────────────┐
│  ⭐ 320              ⏱ 45s             🔥 x5   │
├─────────────────────────────────────────────────┤
│                                                 │
│   ┌───┐    ┌───┐    ┌───┐                     │
│   │ 🐹 │    │   │    │ ⭐ │                     │
│   └───┘    └───┘    └───┘                     │
│                                                 │
│   ┌───┐    ┌───┐    ┌───┐                     │
│   │   │    │ 💣 │    │   │                     │
│   └───┘    └───┘    └───┘                     │
│                                                 │
│   ┌───┐    ┌───┐    ┌───┐                     │
│   │ 🐹 │    │   │    │ 🐹 │                     │
│   └───┘    └───┘    └───┘                     │
│                                                 │
├─────────────────────────────────────────────────┤
│         ⏸ 暂停          ⏹ 结束                 │
└─────────────────────────────────────────────────┘
4.3.3 地鼠类型
┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│             │  │             │  │             │
│     🐹      │  │     ⭐      │  │     💣      │
│             │  │    +50      │  │    -30      │
│   普通+10   │  │   金色+50   │  │   炸弹-30   │
└─────────────┘  └─────────────┘  └─────────────┘

4.4 动画效果

4.4.1 击中动画
_hitAnimationController = AnimationController(
  duration: const Duration(milliseconds: 200),
  vsync: this,
);
_hitAnimation = Tween<double>(begin: 1.0, end: 0.5).animate(
  CurvedAnimation(parent: _hitAnimationController, curve: Curves.easeOut),
);
4.4.2 动画时序图
1970-01-01 1970-01-01 1970-01-01 1970-01-01 1970-01-01 1970-01-01 1970-01-01 1970-01-01 1970-01-01 1970-01-01 1970-01-01 1970-01-01 1970-01-01 1970-01-01 缩小动画 消失效果 动画效果 击中动画时序

五、核心功能实现

5.1 地鼠生成

void _spawnMole() {
  if (_gameState != GameState.playing) return;

  // 获取空闲洞口
  final availableHoles = <int>[];
  for (int i = 0; i < _moles.length; i++) {
    if (_moles[i] == null) {
      availableHoles.add(i);
    }
  }

  if (availableHoles.isEmpty) return;

  // 随机选择洞口和类型
  final holeIndex = availableHoles[_random.nextInt(availableHoles.length)];
  final moleType = _getRandomMoleType();

  setState(() {
    _moles[holeIndex] = Mole(
      holeIndex: holeIndex,
      type: moleType,
      appearTime: DateTime.now(),
    );
  });

  // 设置消失定时器
  Future.delayed(Duration(milliseconds: _moles[holeIndex]!.duration), () {
    if (_moles[holeIndex] != null && !_moles[holeIndex]!.isHit) {
      setState(() {
        if (_moles[holeIndex]!.type != MoleType.bomb) {
          _misses++;
          _combo = 0;
        }
        _moles[holeIndex] = null;
      });
    }
  });
}

5.2 击中判定

void _hitMole(int index) {
  if (_gameState != GameState.playing) return;
  if (_moles[index] == null || _moles[index]!.isHit) return;

  final mole = _moles[index]!;
  _hitAnimationController.forward(from: 0);

  setState(() {
    mole.isHit = true;
    _score += mole.score;
    _hits++;

    if (mole.type == MoleType.golden) {
      _goldenHits++;
    } else if (mole.type == MoleType.bomb) {
      _bombHits++;
      _combo = 0;
    } else {
      _combo++;
      if (_combo > _maxCombo) {
        _maxCombo = _combo;
      }
      // 连击奖励
      if (_combo > 0 && _combo % 5 == 0) {
        _score += _combo * 5;
      }
    }
  });

  // 延迟移除
  Future.delayed(const Duration(milliseconds: 200), () {
    setState(() {
      _moles[index] = null;
    });
  });
}

5.3 难度控制

int _getSpawnInterval() {
  switch (_difficulty) {
    case Difficulty.easy:
      return 1200;    // 简单:1.2秒
    case Difficulty.medium:
      return 800;     // 中等:0.8秒
    case Difficulty.hard:
      return 500;     // 困难:0.5秒
  }
}

5.4 游戏结束处理

void _endGame() {
  _gameTimer?.cancel();
  _moleTimer?.cancel();
  _countdownTimer?.cancel();

  final result = GameResult(
    score: _score,
    hits: _hits,
    misses: _misses,
    goldenHits: _goldenHits,
    bombHits: _bombHits,
    combo: _maxCombo,
    date: DateTime.now(),
  );

  setState(() {
    _history.insert(0, result);
    _gameState = GameState.finished;
  });

  _showResultDialog();
}

六、游戏设计知识

6.1 游戏平衡性设计

6.1.1 得分平衡

普通地鼠

+10分
80%概率

金色地鼠

+50分
10%概率
快速消失

炸弹

-30分
10%概率
需要躲避

期望得分计算

E = 0.8 × 10 + 0.1 × 50 + 0.1 × ( − 30 ) = 8 + 5 − 3 = 10 E = 0.8 \times 10 + 0.1 \times 50 + 0.1 \times (-30) = 8 + 5 - 3 = 10 E=0.8×10+0.1×50+0.1×(30)=8+53=10

6.1.2 难度曲线
难度 地鼠间隔 预期击中率 60秒预期得分
简单 1.2秒 70% ~350分
中等 0.8秒 55% ~400分
困难 0.5秒 40% ~450分

6.2 反应时间分析

6.2.1 人类反应时间

~100ms

~100ms

~100ms

视觉刺激

大脑处理

运动指令

手指动作

平均反应时间:约300ms

6.2.2 地鼠停留时间设计
地鼠类型 停留时间 设计考量
普通 1500ms 允许1-2次点击尝试
金色 800ms 需要快速反应
炸弹 2000ms 有足够时间识别躲避

6.3 连击系统设计

6.3.1 连击奖励机制

连击数

是否为5的倍数?

额外奖励: 连击数×5

无额外奖励

鼓励持续击中

6.3.2 连击中断条件
条件 连击变化 设计目的
击中普通地鼠 +1 鼓励持续击中
击中金色地鼠 +1 高价值奖励
击中炸弹 重置为0 惩罚误操作
错过地鼠 重置为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 核心游戏逻辑 三种地鼠类型 历史记录功能 音效系统 道具系统 成就系统 多人对战 排行榜 自定义皮肤 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 打地鼠游戏开发计划

7.2 功能扩展建议

7.2.1 道具系统
道具 效果 持续时间
时间冻结 暂停倒计时 5秒
双倍得分 得分翻倍 10秒
慢动作 地鼠停留时间加倍 8秒
护盾 免疫炸弹伤害 15秒
7.2.2 成就系统
class Achievement {
  final String id;
  final String name;
  final String description;
  final int reward;
  final bool isUnlocked;
}
7.2.3 多人对战
模式 说明
同时对战 两人同时游戏比分数
轮流挑战 轮流挑战高分
合作模式 共同击中目标数量

八、注意事项

8.1 开发注意事项

  1. 计时器管理:页面销毁时必须取消所有Timer,避免内存泄漏

  2. 状态同步:地鼠出现和消失需要正确同步UI状态

  3. 触摸响应:确保点击区域足够大,提升用户体验

  4. 动画流畅:击中动画不应影响游戏性能

8.2 游戏体验优化

🎮 游戏体验建议 🎮

  • 提供清晰的视觉反馈
  • 音效增强打击感
  • 合理的难度曲线
  • 适时的奖励激励

8.3 常见问题

问题 原因 解决方案
地鼠重叠 生成逻辑问题 检查空闲洞口
计时不准 Timer精度 使用Stopwatch
点击无响应 状态未更新 检查游戏状态
内存泄漏 Timer未取消 dispose中取消

九、运行说明

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_whack_a_mole.dart

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

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

十、总结

打地鼠游戏通过经典的玩法设计和丰富的游戏元素,为玩家提供了轻松愉快的休闲体验。游戏采用清新的草地主题,配合可爱的地鼠形象,营造出轻松愉快的游戏氛围;代码结构清晰,遵循Flutter最佳实践;游戏逻辑设计合理,难度曲线平滑。

核心玩法涵盖三种地鼠类型、三种难度选择、连击奖励系统和历史记录功能,满足不同玩家的游戏需求。特别值得一提的是金色地鼠和炸弹的设计,金色地鼠高分快速消失考验反应,炸弹扣分需要躲避增加策略性,让游戏既有休闲性又有挑战性。

连击系统是游戏的一大亮点,连续击中地鼠可以获得额外奖励,激励玩家保持专注和快速反应。60秒限时模式让每一局都紧张刺激,历史记录功能帮助玩家追踪自己的进步,不断挑战更高分数。

快速反应,精准打击,挑战高分!


Logo

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

更多推荐