鸿蒙5桌面电子宠物小组件开发指南 原创

进修的泡芙
发布于 2025-6-20 14:53
浏览
0收藏

鸿蒙5桌面电子宠物小组件开发指南

一、项目概述

本文基于HarmonyOS 5的原子化服务和分布式技术,开发一款桌面电子宠物小组件,借鉴《鸿蒙跨端U同步》中游戏多设备同步的技术原理,实现宠物状态的多设备同步和互动。该电子宠物能够展示丰富动画效果、响应多设备交互,并通过分布式能力实现状态同步。

二、系统架构

±--------------------+ ±--------------------+ ±--------------------+
桌面小组件 <-----> 原子化服务 <-----> 分布式数据总线
(Widget) (Atomic Service) (Distributed Bus)
±---------±---------+ ±---------±---------+ ±---------±---------+

±---------v----------+ ±---------v----------+ ±---------v----------+
动画渲染引擎 宠物状态管理 多设备同步服务
(Animation Engine) (State Manager) (Sync Service)

±--------------------+ ±--------------------+ ±--------------------+

三、核心代码实现
宠物数据模型

// src/main/ets/model/PetModel.ts
export class VirtualPet {
petId: string; // 宠物唯一ID
name: string; // 宠物名称
type: PetType; // 宠物类型
level: number; // 等级
happiness: number; // 快乐值(0-100)
hunger: number; // 饥饿值(0-100)
energy: number; // 能量值(0-100)
experience: number; // 经验值
lastFed: number; // 最后喂食时间
lastPlayed: number; // 最后玩耍时间
isSleeping: boolean; // 是否在睡觉
currentAnimation: string; // 当前动画状态
position: { x: number, y: number }; // 屏幕位置
deviceId: string; // 所属设备ID

constructor(name: string, type: PetType = PetType.CAT) {
this.petId = ‘pet_’ + Math.random().toString(36).substring(2, 15);
this.name = name;
this.type = type;
this.level = 1;
this.happiness = 70;
this.hunger = 50;
this.energy = 80;
this.experience = 0;
this.lastFed = Date.now();
this.lastPlayed = Date.now();
this.isSleeping = false;
this.currentAnimation = ‘idle’;
this.position = { x: 0.5, y: 0.7 };
this.deviceId = ‘’;
feed(): void {

this.hunger = Math.min(100, this.hunger + 30);
this.happiness = Math.min(100, this.happiness + 10);
this.lastFed = Date.now();
this.currentAnimation = 'eating';

play(): void {

this.happiness = Math.min(100, this.happiness + 20);
this.energy = Math.max(0, this.energy - 15);
this.experience += 10;
this.lastPlayed = Date.now();
this.currentAnimation = 'playing';

sleep(): void {

this.isSleeping = true;
this.energy = Math.min(100, this.energy + 5);
this.currentAnimation = 'sleeping';

wakeUp(): void {

this.isSleeping = false;
this.currentAnimation = 'idle';

updateStatus(): void {

const now = Date.now();
const hoursSinceFed = (now - this.lastFed) / (1000  60  60);
const hoursSincePlayed = (now - this.lastPlayed) / (1000  60  60);

if (!this.isSleeping) {
  this.hunger = Math.max(0, this.hunger - hoursSinceFed * 5);
  this.happiness = Math.max(0, this.happiness - hoursSincePlayed * 3);
  this.energy = Math.max(0, this.energy - hoursSincePlayed * 2);

else {

  this.energy = Math.min(100, this.energy + hoursSincePlayed * 8);

if (this.experience >= this.level * 100) {

  this.level++;
  this.experience = 0;
  this.currentAnimation = 'happy';

// 自动恢复空闲状态

if (this.currentAnimation !== 'idle' && 
    this.currentAnimation !== 'sleeping' &&
    now - Math.max(this.lastFed, this.lastPlayed) > 3000) {
  this.currentAnimation = 'idle';

}

toJson(): string {
return JSON.stringify({
petId: this.petId,
name: this.name,
type: this.type,
level: this.level,
happiness: this.happiness,
hunger: this.hunger,
energy: this.energy,
experience: this.experience,
lastFed: this.lastFed,
lastPlayed: this.lastPlayed,
isSleeping: this.isSleeping,
currentAnimation: this.currentAnimation,
position: this.position,
deviceId: this.deviceId
});
static fromJson(jsonStr: string): VirtualPet {

const json = JSON.parse(jsonStr);
const pet = new VirtualPet(json.name, json.type);
pet.petId = json.petId;
pet.level = json.level;
pet.happiness = json.happiness;
pet.hunger = json.hunger;
pet.energy = json.energy;
pet.experience = json.experience;
pet.lastFed = json.lastFed;
pet.lastPlayed = json.lastPlayed;
pet.isSleeping = json.isSleeping;
pet.currentAnimation = json.currentAnimation;
pet.position = json.position;
pet.deviceId = json.deviceId;
return pet;

}

export enum PetType {
CAT = ‘cat’,
DOG = ‘dog’,
RABBIT = ‘rabbit’,
DRAGON = ‘dragon’
export enum PetAnimation {

IDLE = ‘idle’,
EATING = ‘eating’,
PLAYING = ‘playing’,
SLEEPING = ‘sleeping’,
HAPPY = ‘happy’,
SAD = ‘sad’

分布式同步服务

// src/main/ets/service/DistributedSyncService.ts
import { distributedData } from ‘@ohos.data.distributedData’;
import { BusinessError } from ‘@ohos.base’;
import { VirtualPet } from ‘…/model/PetModel’;
import { deviceManager } from ‘@ohos.distributedDeviceManager’;

export class DistributedSyncService {
private static instance: DistributedSyncService;
private kvManager: distributedData.KVManager;
private kvStore: distributedData.KVStore;
private readonly STORE_ID = ‘pet_store’;
private readonly PET_KEY_PREFIX = ‘pet_’;
private subscribers: ((data: VirtualPet) => void)[] = [];

private constructor() {
this.initDistributedData();
public static getInstance(): DistributedSyncService {

if (!DistributedSyncService.instance) {
  DistributedSyncService.instance = new DistributedSyncService();

return DistributedSyncService.instance;

private initDistributedData(): void {

const config: distributedData.KVManagerConfig = {
  bundleName: 'com.example.virtualpet',
  userInfo: {
    userId: '0',
    userType: distributedData.UserType.SAME_USER_ID

};

try {
  distributedData.createKVManager(config, (err: BusinessError, manager: distributedData.KVManager) => {
    if (err) {
      console.error(Failed to create KVManager. Code: {err.code}, message: {err.message});
      return;

this.kvManager = manager;

    const options: distributedData.Options = {
      createIfMissing: true,
      encrypt: true,
      backup: false,
      autoSync: true,
      kvStoreType: distributedData.KVStoreType.SINGLE_VERSION,
      schema: '',
      securityLevel: distributedData.SecurityLevel.S2
    };

    this.kvManager.getKVStore(this.STORE_ID, options, (err: BusinessError, store: distributedData.KVStore) => {
      if (err) {
        console.error(Failed to get KVStore. Code: {err.code}, message: {err.message});
        return;

this.kvStore = store;

      this.registerDataListener();
    });
  });

catch (e) {

  console.error(An unexpected error occurred. Code: {e.code}, message: {e.message});

}

private registerDataListener(): void {
try {
this.kvStore.on(‘dataChange’, distributedData.SubscribeType.SUBSCRIBE_TYPE_ALL, (data: distributedData.ChangeData) => {
if (data.key.startsWith(this.PET_KEY_PREFIX)) {
const pet = VirtualPet.fromJson(data.value.value as string);
this.notifySubscribers(pet);
});

catch (e) {

  console.error(Failed to register data listener. Code: {e.code}, message: {e.message});

}

public subscribe(callback: (data: VirtualPet) => void): void {
this.subscribers.push(callback);
public unsubscribe(callback: (data: VirtualPet) => void): void {

this.subscribers = this.subscribers.filter(sub => sub !== callback);

private notifySubscribers(data: VirtualPet): void {

this.subscribers.forEach(callback => callback(data));

public syncPet(pet: VirtualPet): void {

if (!this.kvStore) {
  console.error('KVStore is not initialized');
  return;

deviceManager.getLocalDeviceInfo((err: BusinessError, info) => {

  if (err) {
    console.error(Failed to get device info. Code: {err.code}, message: {err.message});
    return;

pet.deviceId = info.deviceId;

  const key = this.PET_KEY_PREFIX + pet.petId;

  try {
    this.kvStore.put(key, pet.toJson(), (err: BusinessError) => {
      if (err) {
        console.error(Failed to put pet. Code: {err.code}, message: {err.message});

});

catch (e) {

    console.error(An unexpected error occurred. Code: {e.code}, message: {e.message});

});

public async getPet(petId: string): Promise<VirtualPet | null> {

return new Promise((resolve) => {
  if (!this.kvStore) {
    resolve(null);
    return;

try {

    this.kvStore.get(this.PET_KEY_PREFIX + petId, (err: BusinessError, value: distributedData.Value) => {
      if (err) {
        console.error(Failed to get pet. Code: {err.code}, message: {err.message});
        resolve(null);
        return;

resolve(VirtualPet.fromJson(value.value as string));

    });

catch (e) {

    console.error(An unexpected error occurred. Code: {e.code}, message: {e.message});
    resolve(null);

});

}

原子化服务实现

// src/main/ets/service/PetAtomicService.ts
import { VirtualPet } from ‘…/model/PetModel’;
import { DistributedSyncService } from ‘./DistributedSyncService’;
import { featureAbility } from ‘@ohos.ability.featureAbility’;

export class PetAtomicService {
private static instance: PetAtomicService;
private syncService = DistributedSyncService.getInstance();
private currentPet: VirtualPet | null = null;

private constructor() {
this.initService();
public static getInstance(): PetAtomicService {

if (!PetAtomicService.instance) {
  PetAtomicService.instance = new PetAtomicService();

return PetAtomicService.instance;

private initService(): void {

// 注册原子化服务
featureAbility.registerAbilityLifecycleCallback({
  onStart: (want) => {
    console.log('PetAtomicService started');
  },
  onStop: () => {
    console.log('PetAtomicService stopped');

});

// 加载或创建宠物
this.loadOrCreatePet();

private async loadOrCreatePet(): Promise<void> {

// 尝试从分布式数据加载已有宠物
const petId = localStorage.getItem('current_pet_id');
if (petId) {
  this.currentPet = await this.syncService.getPet(petId);

// 如果没有找到宠物,创建新宠物

if (!this.currentPet) {
  this.currentPet = new VirtualPet('小可爱', PetType.CAT);
  localStorage.setItem('current_pet_id', this.currentPet.petId);

// 同步宠物状态

this.syncService.syncPet(this.currentPet);

public getCurrentPet(): VirtualPet | null {

return this.currentPet;

public feedPet(): void {

if (!this.currentPet) return;

this.currentPet.feed();
this.syncService.syncPet(this.currentPet);

public playWithPet(): void {

if (!this.currentPet) return;

this.currentPet.play();
this.syncService.syncPet(this.currentPet);

public putPetToSleep(): void {

if (!this.currentPet) return;

this.currentPet.sleep();
this.syncService.syncPet(this.currentPet);

public wakeUpPet(): void {

if (!this.currentPet) return;

this.currentPet.wakeUp();
this.syncService.syncPet(this.currentPet);

public updatePetStatus(): void {

if (!this.currentPet) return;

this.currentPet.updateStatus();
this.syncService.syncPet(this.currentPet);

}

桌面小组件实现

// src/main/ets/widget/PetWidget.ets
import { VirtualPet } from ‘…/model/PetModel’;
import { PetAtomicService } from ‘…/service/PetAtomicService’;
import { lottie } from ‘@ohos.lottie’;

@Component
export struct PetWidget {
@State pet: VirtualPet | null = null;
@State touchX: number = 0;
@State touchY: number = 0;
private atomicService = PetAtomicService.getInstance();
private animationPlayer: lottie.AnimationItem | null = null;

aboutToAppear(): void {
this.pet = this.atomicService.getCurrentPet();
this.initAnimation();

// 每10秒更新一次状态
setInterval(() => {
  this.atomicService.updatePetStatus();
  this.pet = this.atomicService.getCurrentPet();
}, 10000);

private initAnimation(): void {

if (!this.pet) return;

this.animationPlayer = lottie.loadAnimation({
  container: this.$element('animationContainer'),
  renderer: 'svg',
  loop: true,
  autoplay: true,
  path: resources/animations/{this.pet.type}/{this.pet.currentAnimation}.json
});

private updateAnimation(): void {

if (!this.pet || !this.animationPlayer) return;

this.animationPlayer.destroy();
this.initAnimation();

build() {

Stack() {
  // 宠物动画容器
  Column() {
    // Lottie动画将通过animationPlayer动态加载

.id(‘animationContainer’)

  .width(100)
  .height(100)
  .position({ x: this.touchX, y: this.touchY })
  .onTouch((event: TouchEvent) => {
    // 拖动宠物
    if (event.type === TouchType.Move) {
      this.touchX = event.touches[0].x / this.$width();
      this.touchY = event.touches[0].y / this.$height();
      if (this.pet) {
        this.pet.position = { x: this.touchX, y: this.touchY };
        this.atomicService.syncPet(this.pet);

}

  })
  .onClick(() => {
    // 点击互动
    this.atomicService.playWithPet();
    this.pet = this.atomicService.getCurrentPet();
    this.updateAnimation();
  })

  // 控制按钮
  Row() {
    Button('喂食')
      .width(60)
      .height(30)
      .onClick(() => {
        this.atomicService.feedPet();
        this.pet = this.atomicService.getCurrentPet();
        this.updateAnimation();
      })
    
    Button(this.pet?.isSleeping ? '唤醒' : '睡觉')
      .width(60)
      .height(30)
      .margin({ left: 10 })
      .onClick(() => {
        if (this.pet?.isSleeping) {
          this.atomicService.wakeUpPet();

else {

          this.atomicService.putPetToSleep();

this.pet = this.atomicService.getCurrentPet();

        this.updateAnimation();
      })

.position({ x: ‘50%’, y: ‘90%’ })

  .justifyContent(FlexAlign.Center)

.width(‘100%’)

.height('100%')

}

四、与游戏同步技术的结合点
状态同步机制:借鉴游戏中玩家状态同步技术,实现宠物状态的多设备同步

实时交互响应:类似游戏中的实时互动,实现多设备对宠物的同步操作

数据压缩传输:采用游戏中的高效数据压缩算法,减少状态同步数据量

设备角色分配:主设备作为状态权威,类似游戏中的主机角色

冲突解决策略:采用类似游戏的时间戳优先策略解决状态冲突

五、关键特性实现
动画状态管理:

  // 平滑过渡动画状态

private transitionAnimation(newAnim: PetAnimation): void {
if (this.currentAnimation === newAnim) return;

 // 播放过渡动画
 const transitionAnim = this.getTransitionAnimation(this.currentAnimation, newAnim);
 if (transitionAnim) {
   transitionAnim.playOnce(() => {
     this.playAnimation(newAnim);
   });

else {

   this.playAnimation(newAnim);

}

多设备交互:

  // 处理来自其他设备的交互

private handleRemoteInteraction(deviceId: string, action: string): void {
if (deviceId === this.currentDeviceId) return;

 switch (action) {
   case 'feed':
     this.pet.onFedRemotely();
     break;
   case 'play':
     this.pet.onPlayedRemotely();
     break;

this.updatePetDisplay();

离线状态处理:

  // 恢复离线期间的状态变化

private recoverOfflineChanges(): void {
const offlineTime = Date.now() - this.lastSyncTime;
if (offlineTime > 60000) { // 离线超过1分钟
const hours = offlineTime / (1000 60 60);
this.pet.simulateOfflineChanges(hours);
}

自适应动画质量:

  // 根据设备性能调整动画质量

private adjustAnimationQuality(): void {
const perfLevel = device.getPerformanceLevel();
this.animationQuality = perfLevel === ‘high’ ? ‘high’ : ‘low’;
this.loadAnimations(this.animationQuality);

六、性能优化策略
动画资源按需加载:

  // 只加载当前需要的动画资源

private loadRequiredAnimations(petType: PetType): void {
this.unloadAllAnimations();
const requiredAnims = [
PetAnimation.IDLE,
PetAnimation.EATING,
PetAnimation.PLAYING,
PetAnimation.SLEEPING
];
requiredAnims.forEach(anim => this.loadAnimation(petType, anim));

状态更新批处理:

  // 批量处理状态更新

private batchUpdates(): void {
if (this.updateBatchTimer) return;

 this.updateBatchTimer = setTimeout(() => {
   this.syncService.syncPet(this.currentPet);
   this.updateBatchTimer = null;
 }, 500); // 每500ms批量同步一次

内存敏感模式:

  // 低内存设备启用简化模式

private checkMemoryStatus(): void {
const memoryInfo = device.getMemoryInfo();
if (memoryInfo.level === ‘low’) {
this.enableLowMemoryMode();
}

后台运行优化:

  // 后台运行时减少更新频率

private handleAppStateChange(state: string): void {
if (state === ‘background’) {
this.updateInterval = 30000; // 30秒
else {

   this.updateInterval = 10000; // 10秒

}

七、项目扩展方向
宠物换装系统:支持自定义宠物外观

社交互动功能:宠物之间的互动玩法

AR宠物展示:通过AR技术将宠物投射到现实环境

智能语音交互:支持语音指令控制宠物

健康监测集成:结合健康数据影响宠物状态

八、总结

本桌面电子宠物小组件实现了以下核心功能:
基于原子化服务的轻量级宠物模拟

丰富的Lottie动画效果展示

多设备状态同步与互动

响应式用户交互体验

自适应不同设备性能

通过借鉴游戏中的多设备同步技术,我们构建了一个生动有趣的桌面宠物应用。该项目展示了HarmonyOS分布式能力在互动娱乐领域的创新应用,为开发者提供了实现多设备协同互动应用的参考方案。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
收藏
回复
举报
回复
    相关推荐