HarmonyOS新特性-沉浸光感在叠叠消小游戏中的落地实践

HarmonyOS新特性-沉浸光感在叠叠消小游戏中的落地实践 HarmonyOS新特性-沉浸光感在叠叠消小游戏中的落地实践前言前段时间我用 ArkTS ArkUI 开发了一款消除类小游戏「叠叠消」核心玩法是叠层图案消除游戏跑起来 60fps 很稳但 UI 层面总觉得平——所有界面元素都是纯色背景各自为政没有统一的视觉质感。恰好 HarmonyOS NEXT 提供了「沉浸光感Immersive Light Sensing」这套系统级材质渲染能力官方描述是通过模拟真实物理光照模型在 UI 组件内部产生毛玻璃模糊、按压弹性光效、滑动透明度渐变等效果。说白了就是系统帮你渲染毛玻璃。我在三个核心场景做了落地标题栏、底部操作栏、弹窗体系。本文记录具体的改造过程和踩坑经验希望对同样在适配沉浸光感的开发者有帮助。一、沉浸光感简介在开始改造之前先简单梳理一下沉浸光感涉及的 API 和概念。1.1 涉及的 SDK 包kit.ArkUI下的uiMaterial.ImmersiveMaterial—— 底层材质渲染能力kit.UIDesignKit下的hdsMaterial—— HDS 组件的高级封装1.2 核心 API组件的systemMaterial()属性设了就开不设就关// 开启Button(撤回).systemMaterial(newuiMaterial.ImmersiveMaterial({style:uiMaterial.ImmersiveStyle.ULTRA_THIN,interactive:true,lightEffect:{color:undefined}}))// 关闭Button(撤回).systemMaterial(undefined)1.3 材质档位档位枚举值说明强MaterialLevel.EXQUISITE完整效果含毛玻璃 光晕 反射均衡默认MaterialLevel.GENTLE适度效果平衡性能与视觉弱MaterialLevel.SMOOTH轻量级仅保留核心视觉特性系统自适应MaterialLevel.ADAPTIVE系统根据设备性能自动选档实际开发中大多数场景直接用ADAPTIVE最省心。二、改造一游戏页标题栏渐变模糊 动态显隐2.1 改造前游戏页GamePage标题栏使用NavDestination纯色背景暖紫 #7C3AED固定不动的标题文字。在游戏画面向上滑动时标题栏始终占据顶部空间没有利用价值。2.2 改造方案参考官方的 Spatialization-master 参考实现使用 HDS 组件的HdsNavDestinationtitleBar属性配置。// WaterFlowDetailView.etsimport{hdsMaterial,HdsNavigation,HideMode,ScrollEffectType}fromkit.UIDesignKit;HdsNavigation(){WaterFlowView({currentTabIndex:this.currentIndex,pageKey:PageKeyEnum.IMMERSIVE_LIGHT,handleTabBarAnimation:(yOffset:number){this.handleTabBarAnimation?.(yOffset);}})}.mode(NavigationMode.Stack).hideBackButton(false).titleMode(HdsNavigationTitleMode.MINI).dynamicHideTitleBar({hideTitleArea:true,hideStatusBar:true,mode:HideMode.SCROLL_UP_TO,}).titleBar({content:{title:{mainTitle:$r(app.string.sample_3_title)},backIcon:{action:(){this.handleBackBtnAction();}},menu:this.menus,},style:{scrollEffectOpts:{enableScrollEffect:true,scrollEffectType:ScrollEffectType.GRADIENT_BLUR,blurEffectiveEndOffset:LengthMetrics.vp(this.globalInfoModel.statusBarHeight56)},systemMaterialEffect:{materialType:hdsMaterial.MaterialType.ADAPTIVE,materialLevel:this.customMaterialLevel.level,},},avoidLayoutSafeArea:true,enableComponentSafeArea:false,}).bindToScrollable([this.scroller]).ignoreLayoutSafeArea([LayoutSafeAreaType.SYSTEM],[LayoutSafeAreaEdge.TOP,LayoutSafeAreaEdge.BOTTOM])2.3 关键属性说明属性值作用scrollEffectTypeGRADIENT_BLUR标题栏随滑动从透明渐变为毛模糊materialTypeADAPTIVE自适应材质类型materialLevelthis.customMaterialLevel.level可动态切换的材质强度dynamicHideTitleBar.hideTitleAreatrue允许标题栏滑动隐藏dynamicHideTitleBar.hideStatusBartrue允许状态栏联动隐藏modeSCROLL_UP_TO上滑到底后才隐藏不是一滑就藏2.4 效果描述页面初始状态标题栏完全透明游戏画面铺满全屏。向上滑动时标题栏逐步浮现毛玻璃效果不是闪现出来。继续上滑到一定位置标题栏和状态栏整体隐藏释放更多可视面积。向下滑动时反向过渡毛玻璃渐隐消失。2.5 代码量变化改造前标题栏配置约 5 行改造后配置约 25 行净增约 20 行没有改动游戏逻辑代码三、改造二底部操作栏悬浮胶囊 左右手自适应3.1 改造前底部操作栏使用Row容器 深紫色背景#2D1B69固定在屏幕底部。视觉效果上是贴在屏幕上的一个色块游戏画面被一条实色条切断。3.2 改造方案叠叠消虽然没有多 Tab 切换的需求但 HDS 的HdsTabs悬浮栏模式barFloatingStyle恰好提供了所需的「悬浮毛玻璃胶囊」效果可以直接复用。// 参考 AdaptiveTabView.etsHdsTabs({controller:this.controller}){TabContent(){WaterFlowView({currentTabIndex:repeatItem.index,pageKey:PageKeyEnum.ADAPTIVE_TAB})}.tabBar(repeatItem.item)}.barOverlap(true).vertical(false).barPosition(BarPosition.End).barFloatingStyle({barBottomMargin:this.globalInfoModel.naviIndicatorHeight0?this.globalInfoModel.naviIndicatorHeight:$r(sys.float.padding_level8),systemMaterialEffect:{materialType:hdsMaterial.MaterialType.IMMERSIVE,materialLevel:hdsMaterial.MaterialLevel.ADAPTIVE},miniBar:{miniBarBuilder:()this.miniBarBuilder(),onBarStyleChange:(miniBarStyle:HdsBarStyle){this.isMiniBarminiBarStyleHdsBarStyle.COLLAPSE;}}})3.3 配合智感握姿adaptToHandedness属性设为true后底部栏在宽屏设备上会靠向握持手一侧。叠叠消复用了之前智感握姿场景的传感器代码// 参考 SmartReachView.etsimport{motion}fromkit.MultimodalAwarenessKit;aboutToAppear():void{try{if(canIUse(SystemCapability.MultimodalAwareness.Motion)){motion.on(holdingHandChanged,this.handleHoldingHandChange);}}catch(error){Logger.error(TAG,Failed on holdingHandChanged. cause:${error.message});}}handleHoldingHandChange(status:motion.HoldingHandStatus){this.getUIContext().animateTo({curve:curves.interpolatingSpring(0,1,288,30)},(){// barFloatingStyle 已设 adaptToHandedness无需手动控制偏移});}3.4 效果底部操作栏变成悬浮在游戏画面之上的圆角胶囊图案堆最下层的图案可以从胶囊底部透出来。adaptToHandedness在平板和折叠屏展开态下效果明显手机上屏幕较窄左右差异不大。四、改造三弹窗体系毛玻璃背景 版本兼容4.1 改造前叠叠消的弹窗种类不少通关结算、失败救场、商城购买、道具确认、设置面板等。使用CustomDialogController实现白底 阴影弹出时游戏画面完全被遮挡。4.2 工具类封装弹窗的改造不影响游戏逻辑核心代码全部封装在MaterialUtil.ets中同时做好 API 版本兼容// MaterialUtil.etsimport{uiMaterial}fromkit.ArkUI;import{deviceInfo}fromkit.BasicServicesKit;import{hdsMaterial}fromkit.UIDesignKit;exportclassMaterialUtil{/** * 给弹窗/菜单等组件添加沉浸材质 * 兼容 API 26 以下设备自动降级 */publicstaticgetMaterialOptionsT(option:T):MaterialOptionsT|T{if(deviceInfo.apiAvailable(26.0.0)hdsMaterial.getSystemMaterialTypes().length0){constmaterialOptionsoptionasMaterialOptionsT;materialOptions.systemMaterialnewuiMaterial.ImmersiveMaterial({style:uiMaterial.ImmersiveStyle.THICK,interactive:true,lightEffect:{color:undefined},});returnmaterialOptions;}returnoption;// 不支持的设备直接返回原配置}/** * 给按钮等通用组件添加沉浸材质 */publicstaticgetMaterialModifier(options:ModifierOptions):CommonModifier{if(deviceInfo.apiAvailable(26.0.0)hdsMaterial.getSystemMaterialTypes().length0){constmaterialOptions:uiMaterial.ImmersiveOptions{style:uiMaterial.ImmersiveStyle.ULTRA_THIN,interactive:true,lightEffect:{color:undefined}};if(options.materialColor){materialOptions.materialColoroptions.materialColor;}options.modifier.systemMaterial(newuiMaterial.ImmersiveMaterial(materialOptions));}else{// 低版本降级方案if(options.backgroundColor){options.modifier.backgroundColor(options.backgroundColor);}if(options.backgroundBlurStyle){options.modifier.backgroundBlurStyle(options.backgroundBlurStyle);}}returnoptions.modifier;}}interfaceMaterialOptionsTextendsThisTypeT{systemMaterial?:SystemUiMaterial;}interfaceModifierOptions{modifier:CommonModifier;style:CustomImmersiveStyle;backgroundColor?:ResourceColor;materialColor?:ResourceColor;backgroundBlurStyle?:BlurStyle;}exportenumCustomImmersiveStyle{ULTRA_THIN0,THIN1,REGULAR2,THICK3,ULTRA_THICK4}4.3 弹窗调用在通关结算弹窗中调用// 通关结算弹窗try{constuiContextthis.getUIContext();constpromptActionuiContext.getPromptAction();constcontentNodenewComponentContent(uiContext,wrapBuilder(victoryDialogBuilder));promptAction.openMenu(contentNode,{id:victoryDialog},MaterialUtil.getMaterialOptionsMenuOptions({mask:false,backgroundBlurStyle:BlurStyle.COMPONENT_THICK,})asMenuOptions);}catch(error){Logger.error(TAG,Show dialog failed:${error.message});}4.4 效果弹窗背景变为毛玻璃材质背后的游戏画面图案堆、撒花粒子隐约可见。弹窗不再是阻断式遮罩而是浮在游戏上的一层半透明玻璃板游戏连贯感大幅提升。五、多设备适配要点叠叠消需要覆盖手机、折叠屏和平板沉浸光感在不同设备上的表现和处理要点如下5.1 手机竖屏 360-430vp标题栏毛玻璃效果最明显屏幕窄、内容区滑动时标题栏的渐变过渡容易被注意到。底部悬浮胶囊的圆角在手机上比较协调。5.2 折叠屏展开态700-900vp折叠态切换时需要监听折叠状态并切换布局但沉浸材质不需要重新配置import{display}fromkit.ArkUI;display.on(foldStatusChange,(status:display.FoldStatus){if(statusdisplay.FoldStatus.EXPANDED){// 切换双列布局左侧图案堆右侧收集槽// 沉浸材质不需要重新配置——ADAPTIVE 模式会自动适应新布局}elseif(statusdisplay.FoldStatus.FOLDED){// 切回单列布局}});5.3 平板800-1200vp图案放大 30%毛玻璃的透光效果在大屏上更强烈。底部悬浮栏可以通过barBottomMargin适当调大间距增强悬浮感。六、性能与降级策略6.1 帧率影响在 Mate 70 Pro麒麟 9010上的帧率测试数据场景未开启EXQUISITE 开启帧率变化游戏静止图案堆无操作60fps60fps无感知图案点击 飞入动画60fps60fps无感知收集槽消除 粒子特效60fps58-60fps偶尔轻微掉帧通关撒花 弹窗弹出60fps55-60fps可感知但可接受中端设备Nova 系列上使用ADAPTIVE模式后系统自动降到了GENTLE帧率没有明显波动。6.2 降级策略实现functiongetMaterialLevel():hdsMaterial.MaterialLevel{if(!deviceInfo.apiAvailable(26.0.0)||hdsMaterial.getSystemMaterialTypes().length0){returnhdsMaterial.MaterialLevel.SMOOTH;// 不支持 → 最低档}// 根据设备性能选择if(isHighPerformanceDevice()){returnhdsMaterial.MaterialLevel.EXQUISITE;}returnhdsMaterial.MaterialLevel.ADAPTIVE;}6.3 降级对照表设备等级代表机型标题栏底部栏弹窗按钮高性能Mate 70 Pro / 折叠屏EXQUISITEEXQUISITEEXQUISITE完整按压反馈中性能Nova 系列GENTLEGENTLETHICK仅弹性缩放低性能畅享系列SMOOTHSMOOTHREGULAR关闭材质不支持API 26 或无能力降级backgroundColorbackgroundBlurStyle七、踩坑记录7.1 同层渲染场景变透明在 API 23 及以前版本中同层渲染Web 组件内嵌 ArkUI 控件下设置沉浸光感可能导致控件背景变透明。叠叠消没有 Web 组件所以没触发但做混合开发的同学需要注意在 Web 内嵌的 ArkUI 控件上关闭材质。// 同层渲染场景下关闭材质component.systemMaterial(undefined);7.2 HdsTabs 滚动事件处理HdsTabs的浮动栏需要通过 WaterFlow 的滚动回调通知HdsTabsController执行显示/隐藏动画。需要维护滚动方向状态避免动画堆积handleTabBarAnimation(yOffset:number):void{if(this.globalInfoModel.needDynamicHideBar){if(yOffset0!this.isScrollUp){this.isScrollUptrue;this.controller.applyHideAnimation(HdsAnimationMode.SCROLL_ANIMATION);}elseif(yOffset0this.isScrollUp){this.isScrollUpfalse;this.controller.applyShowAnimation(HdsAnimationMode.SCROLL_ANIMATION);}}}7.3 亮色模式下的白色叠层亮色模式下EXQUISITE材质可能覆盖白色叠层导致按钮文字和背景颜色接近。解决方案亮色模式自动降级到GENTLE。7.4 折叠屏切换时的材质闪烁折叠屏展开/折叠切换时布局结构变化导致底部栏材质短暂闪烁约 200ms。在切换动画执行前预置材质参数可以缓解// 折叠状态变化前预置材质this.controller.setBarFloatingStyle({systemMaterialEffect:{materialType:hdsMaterial.MaterialType.ADAPTIVE,materialLevel:hdsMaterial.MaterialLevel.ADAPTIVE,},});八、总结沉浸光感在叠叠消中的落地总结如下维度结论改动范围核心改动不到 80 行代码工具类 50 行 页面配置约 30 行影响范围三个改造场景覆盖玩家 90% 的 UI 接触面逻辑侵入零——没有改动任何游戏逻辑代码性能影响高配设备无感知中低配ADAPTIVE模式自动降级对我个人来说最大的感受是系统级材质渲染和第三方实现的最大区别在于一致性。之前使用backgroundBlurStyle手动模拟毛玻璃不同设备上效果参差不齐折叠屏切换布局时还要手动重算。现在把材质定义交给系统不用关心底层渲染实现也不需要手动适配多设备。唯一需要上心的是性能分级和降级策略。ADAPTIVE模式在大多数场景下是最稳妥的选择只有在高性能设备上可以放开到EXQUISITE档位。参考资料沉浸光感-技术创新 - 华为HarmonyOS开发者