在鸿蒙(HarmonyOS)设备(如手机、平板、智慧屏)上开发游戏时,玩家常希望“在手机上玩到一半,平板上能继续”——这需要​​跨设备数据同步​​。鸿蒙的​​分布式数据库(Distributed Data Object, DDO)​​正是解决这一问题的核心技术:它基于分布式软总线,让不同设备像“共享同一个硬盘”一样同步数据。本文将以“保存/加载游戏进度”为例,手把手教你用鸿蒙分布式数据库实现跨设备数据同步,全程无复杂术语,新手也能轻松上手!


一、为什么选择鸿蒙分布式数据库?

传统游戏数据同步需自己搭建服务器或使用第三方云服务,而鸿蒙分布式数据库的优势在于:

  • ​无需额外服务器​​:利用设备间的分布式软总线直接通信;
  • ​自动同步​​:数据修改后,其他设备自动感知并更新;
  • ​跨端兼容​​:手机、平板、PC等设备统一API,一套代码搞定。

二、环境准备:从0到1搭建开发环境

1. 安装必要工具

2. 配置游戏项目

新建一个鸿蒙“Empty Ability”项目(API 9+),并在entry/src/main/module.json5中声明分布式能力:

{
  "module": {
    "reqPermissions": [
      // 声明需要访问分布式数据库的权限
      { "name": "ohos.permission.DISTRIBUTED_DATASYNC" }
    ],
    "deviceTypes": ["phone", "tablet"] // 支持手机和平板
  }
}

三、核心步骤:用分布式数据库保存游戏进度

我们以“保存玩家金币、等级、装备”为例,分四步实现跨设备同步。

步骤1:定义游戏进度数据结构(鸿蒙原生代码)

鸿蒙分布式数据库通过@Distributed注解标记可同步的数据对象。首先创建一个GameProgress类,描述游戏进度:

// GameProgress.ets(数据模型)
import distributedDataObject from '@ohos.data.distributedDataObject';

// 使用@Distributed注解标记可同步的数据对象
@distributedDataObject.Distributed(scope = distributedDataObject.Scope.GLOBAL) // 全局可见
export class GameProgress {
  // 玩家金币数
  coins: number = 0;
  // 玩家等级
  level: number = 1;
  // 装备列表(示例用字符串数组)
  equipments: string[] = [];

  // 构造函数(可选)
  constructor(coins?: number, level?: number, equipments?: string[]) {
    this.coins = coins ?? 0;
    this.level = level ?? 1;
    this.equipments = equipments ?? [];
  }
}

步骤2:初始化分布式数据库(鸿蒙原生代码)

在游戏中需要访问分布式数据库时,初始化DistributedDataManager并获取GameProgress对象:

// GameManager.ets(游戏管理器)
import distributedDataObject from '@ohos.data.distributedDataObject';
import { GameProgress } from './GameProgress';

@Entry
@Component
struct GameManager {
  // 获取全局唯一的分布式数据对象(通过类名)
  private gameProgress: GameProgress = distributedDataObject.getGlobalObject(GameProgress);

  // 保存进度到分布式数据库(关键方法)
  saveProgress(coins: number, level: number, equipments: string[]) {
    // 更新数据
    this.gameProgress.coins = coins;
    this.gameProgress.level = level;
    this.gameProgress.equipments = equipments;
    // 提交修改(触发跨设备同步)
    this.gameProgress.flush(); // 强制同步到云端/其他设备
  }

  // 从分布式数据库加载进度(关键方法)
  loadProgress(): { coins: number, level: number, equipments: string[] } {
    // 直接读取已同步的数据(首次加载可能为空,需处理默认值)
    return {
      coins: this.gameProgress.coins,
      level: this.gameProgress.level,
      equipments: this.gameProgress.equipments
    };
  }
}

步骤3:在游戏界面中调用保存/加载(ArkTS)

在游戏的主界面中,添加“保存进度”和“加载进度”按钮,并绑定上述方法:

// Index.ets(游戏主界面)
import GameManager from './GameManager';

@Entry
@Component
struct GameMain {
  private gameManager = new GameManager();
  @State private coins: number = 0;
  @State private level: number = 1;
  @State private equipments: string[] = [];

  build() {
    Column() {
      // 显示当前游戏进度
      Text(`金币:${this.coins}`).fontSize(24)
      Text(`等级:${this.level}`).fontSize(24)
      Text(`装备:${this.equipments.join(', ')}`).fontSize(24)

      // 模拟游戏操作(赚金币、升级)
      Button('赚10金币')
        .onClick(() => {
          this.coins += 10;
        })
      Button('升1级')
        .onClick(() => {
          this.level += 1;
        })

      // 保存进度按钮
      Button('保存进度到云端')
        .onClick(() => {
          this.gameManager.saveProgress(
            this.coins, 
            this.level, 
            this.equipments
          );
          promptAction.showToast({ message: '保存成功!' });
        })

      // 加载进度按钮
      Button('从云端加载进度')
        .onClick(() => {
          const progress = this.gameManager.loadProgress();
          this.coins = progress.coins;
          this.level = progress.level;
          this.equipments = progress.equipments;
          promptAction.showToast({ message: '加载成功!' });
        })
    }
  }
}

步骤4:测试跨设备同步(手机+平板)

  1. ​设备准备​​:确保手机和平板登录同一华为账号,且开启“超级终端”(设置→超级终端→开启多设备协同);
  2. ​部署应用​​:在DevEco Studio中,将应用同时安装到手机和平板;
  3. ​测试流程​​:
    • 在手机上点击“赚10金币”→“保存进度到云端”;
    • 切换到平板,点击“从云端加载进度”,观察金币数是否同步;
    • 在平板上修改等级→保存,再回到手机加载,验证双向同步。

四、常见问题与解决方案(新手避坑)

Q1:数据同步失败,提示“设备未连接”?

  • ​原因​​:设备未开启分布式软总线或未加入同一超级终端;
  • ​解决​​:
    1. 检查手机/平板是否开启“超级终端”(设置→超级终端→开启);
    2. 手动将设备“拉近”(如手机靠近平板),触发自动连接。

Q2:首次加载进度为空?

  • ​原因​​:分布式数据库首次使用时,其他设备尚未同步数据;
  • ​解决​​:
    1. 先在“源设备”(如手机)保存一次进度;
    2. 其他设备需等待几秒(数据同步需要时间),或手动刷新。

Q3:数据修改后未自动同步?

  • ​原因​​:未调用flush()方法强制同步;
  • ​解决​​:在修改数据后,务必调用gameProgress.flush()(如保存按钮的点击事件中)。
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐