关于openharmony:OpenHarmony有氧拳击之应用端开发

44次阅读

共计 5526 个字符,预计需要花费 14 分钟才能阅读完成。

一、简介

继《OpenHarmony 有氧拳击设施端的开发》后,本次为大家带来酷炫的利用端开发。如下,开发者随同着音乐,律动出拳后,那开发板每每播放“挨打”成果,这到底是怎么一回事?让咱们一探背地原理。
这款拳击游戏开始时会播放音乐,而后以随机速度着落“击拳方块”。当小哥哥在击拳区域内挥拳时,游戏会判断方块的地位,依据不同地位确定播放一般击中或完满击中的动画成果。

二、动画

游戏中一共应用两种动画:属性动画和 Lottie 动画,别离实现着落和击中的成果。“击拳方块”着落成果是利用属性动画进行批改偏移量来实现。游戏同时设置定时器,定时获取挥拳状态和“击拳方块”的所处地位,用于判断以后挥拳是否得分。若得分则依据击中区间来播放不同成果的 Lottie 动画。

三、“着落”动画

1、属性动画介绍
从上图能够看到,游戏中“击拳方块”是自上而下匀速挪动。这种简略管制通用属性进行动画变动的动画,便很适宜应用属性动画来实现。属性动画是指组件的通用属性发生变化时,会依据开始状态和通用属性扭转后的状态作为动画关键帧,在指定工夫内实现突变成果。换言之咱们只须要确定设置好组件在动画完结时的组件属性,而后调用 animateTo(value: AnimationOptions, event: ()=> void),即可创立属性动画。
AnimationOptions 对象阐明
● 属性

● 接口

2、动画实现
编写“击拳方块”UI 组件,并将组件的绝对布局偏移量 offset 属性,绑定到 @state leftY1 变量中, 那么通过批改 leftY1 的值即可实现批改组件所在位置。

@State leftY1: string = '50%'
    @Builder LeftBoxing(offsetY: string) {Image($r('app.media.icon_boxing_left'))
            .width(144)
            .height(110)
            .offset({x: "-30%", y: offsetY})
            .touchable(true)
    }
    build() {Stack() {
            // .....
             // 左侧
            this.LeftBoxing(this.leftY1)
            // .....
    }

3、创立动画
调用 animateTo 显式动画来播放动画实现单个“击拳方块”自上而下地挪动,再通过设置 delay 参数实现 4 个“击拳方块”按程序别离挪动。

    async leftAnimate(){
        // 设置图标下滑动画
        // 动画持续时间
        let leftDuration = this.getRandomDuration()
        this.leftDuration = leftDuration
        // 提早时长
        let leftDelay = leftDuration / (this.boxingCount - 1)
        // 设置开始工夫
        let now = new Date
        this.animateLeftTimestamp = now.getTime()
        // 左侧 animateTo 动画
        animateTo({duration: leftDuration, curve: Curve.Linear,delay:0 * leftDelay ,iterations: 1}, () => {this.leftY1 = "50%"})
        animateTo({duration: leftDuration, curve: Curve.Linear,delay:1 * leftDelay, iterations: 1}, () => {this.leftY2 = "50%"})
        animateTo({duration: leftDuration, curve: Curve.Linear,delay:2 * leftDelay, iterations: 1}, () => {this.leftY3 = "50%"})
        animateTo({duration: leftDuration, curve: Curve.Linear,delay:3 * leftDelay, iterations: 1}, () => {this.leftY4 = "50%"})
        let totalTime = leftDuration + 3 * leftDelay
        await this.sleep(totalTime)
        this.resetAnimate(true)
        this.leftAnimate()}

4、设置击中区域监听
设置定时器定时查问以后是否挥拳,若检测到挥拳再通过计算以后动画运行工夫来判断“击拳方块”地位,从而执行击中或完满击中的逻辑,以下为监听逻辑。

 setScoreListen(){this.intervalNumber = setInterval(async()=>{let res = await BoxingGameNAPI.recvMsg();
            if(res?.message.length > 0){if(res.message.includes('left') && !this.leftAnimateLock){
                    // 检测到左手挥拳
                    this.judgeLeft()}
            }
        },200)
    }

    judgeLeft(){let nowTime = new Date().getTime()
        // 首次到达指标顶部工夫
        let firstTime = this.animateLeftTimestamp + (this.percentToPoint(this.targetOffsetY)+this.percentToPoint('50%') - this.percentToPoint('10%')) * this.leftDuration
        // 完结工夫
        let endTime = this.animateLeftTimestamp + this.leftDuration * 2
        if(nowTime > firstTime - 200 && nowTime < endTime){
            // 得分工夫界线
            let leftDelay =  this.leftDuration /(this.boxingCount -1)
            let handleTime = (nowTime - firstTime) % leftDelay
            let judgeTime = this.leftDuration /6
            CommonLog.info(TAG,`leftDelay:${leftDelay},handleTime:${handleTime},judgeTime:${judgeTime}`)
            // 完满击中
            if (judgeTime/4 < handleTime && handleTime  < (judgeTime *(3/4))) {}else if(handleTime < judgeTime){// 一般击中}else{// 不得分}
        }else{// 未到达区域}
    }

四、击中动画

像前文提到的“着落”动画适宜应用属性动画,那么当咱们须要实现更简单,如上图的动画成果时,该如何来实现呢?
Lottie 介绍
Lottie 是一款可能为应用程序增加动画的开源组件,它能够解析 AE(After Effects)导出的 json 文件,让简单的动画资源轻松运行在应用程序中。如图所示,动画文件通过 AE 的 bodymovin 插件将动画转换成通用的 json 格局形容文件后,利用开发者只需应用 Lottie 解析 json 文件,就能将动画绘制进去。
Lottie 长处:

  1. 只需应用 Lottie 解析 json 文件就能实现动画的加载,基本上实现了 0 代码开发;
  2.  利用开发者能够通过批改 json 文件的参数,将动画运行到不同的应用程序中,实现动画的一次设计多端应用;
  3. 利用开发者可从网络如 https://lottiefiles.com/ 间接下载 json 文件,实时更新动画资源;
  4. Lottie 基于 canvas 画布进行根底的 2D 渲染,让动画晦涩度更高;
  5. Lottie 能够将 UX 设计师给出的简单动画成果 100% 还原到应用程序中;
  6. Lottie 提供了丰盛的 API,让开发者能轻松管制动画,大大提高了开发效率。
    如何应用 Lottie?
  7. 导入 Lottie
    在 Terminal 窗口应用 npm install @ohos/lottieETS 命令下载 Lottie,并在页面中导入 @ohos/lottieETS,如下:
    import lottie from '@ohos/lottieETS'

搁置动画资源将 After Effects 导出的 json 动画资源文件保留到我的项目 common/lottie 门路中,具体门路如下:entry/src/main/ets/MainAbility/common/lottie/animation.json

  1. 创立 Lottie 动画 Lottie 基于 canvas 画布进行根底的 2D 渲染,创立 canvas 画布后设置相干播放参数即可创立并播放 Lottie 动画,Lottie 更多信息可参考 Lottie 接口。创立 canvas 画布:
   @Builder TargetArea(controller:CanvasRenderingContext2D,lottieName:string) {Stack() {Canvas(controller)
                .aspectRatio(1)
                .width(300)
                .offset({y:  this.targetOffsetY})
                .onAppear(() => {})
            Animator('__lottie_ets') // declare Animator('__lottie_ets') when use lottie
        }.height('100%').width(220)
    }

设置 Lottie 动画参数:

setLottie(controller:CanvasRenderingContext2D,lottieName:string,animatePath:string){
        lottie.loadAnimation({
            container: controller,
            renderer: 'canvas',
            loop: false,
            autoplay: false,
            name: lottieName,
            path: animatePath,
        })
        lottie.setSpeed(1,lottieName)
    }

在“着落”动画击拳监听中退出播放不同成果的 Lottie 动画逻辑:

  judgeLeft(){
       ......
        if(nowTime > firstTime - 200 && nowTime < endTime){
           ......
            // 完满击中
            if (judgeTime/4 < handleTime && handleTime  < (judgeTime *(3/4))) {lottie.destroy('animate_left')
                this.setLottie(this.controllerLeft,'animate_left',this.animatePerfectPath)
                lottie.play('animate_left') // 播放完满击中动画
                // 等动画执行实现后能力进入下一次挥拳断定
                this.leftAnimateLock = true
                setTimeout(()=>{lottie.stop()
                    lottie.destroy('animate_left')
                    this.leftAnimateLock = false
                },this.lottieDuration)
            }else if(handleTime < judgeTime){
                // 击中
                lottie.destroy('animate_left')
                this.setLottie(this.controllerLeft,'animate_left',this.animateJustPath)
                lottie.play('animate_left')// 播放击中动画
                this.leftAnimateLock = true
                setTimeout(()=>{lottie.stop()
                    lottie.destroy('animate_left')
                    this.leftAnimateLock = false
                },this.lottieDuration)
            }
        }
    }

五、总结

本文次要讲述了拳击互动游戏中,如何应用属性动画实现简略属性变动的动画成果,如游戏中“击拳方块”自上往下挪动;应用 Lottie 组件实现简单壮丽的动画成果,如游戏中的击拳成果。
本样例是 OpenHarmony 常识体系工作组(相干链接在文章开端)为宽广开发者分享的样例。常识体系工作组联合日常生活,给开发者布局了各种场景的 Demo 样例,如智能家居场景、影音娱乐场景、静止衰弱场景等。欢送宽广开发者一起参加 OpenHarmony 的开发,更加欠缺样例,互相学习,互相提高。

六、参考链接

本样例代码下载链接
https://growing.openharmony.c…
属性动画
https://docs.openharmony.cn/p…
https://docs.openharmony.cn/p…
Lottie
https://docs.openharmony.cn/p…
https://mp.weixin.qq.com/s/2a…
OpenHarmony 常识体系共建开发仓
https://gitee.com/openharmony…
OpenHarmony 学习门路
https://growing.openharmony.c…
小熊派 BearPi-HM Nano 开发板学习门路
https://growing.openharmony.c…
https://gitee.com/bearpi/bear…
润和 DAYU200(RK3568)开发板介绍
https://growing.openharmony.c…
OpenHarmony 有氧拳击之设施端开发
https://mp.weixin.qq.com/s/qV…

正文完
 0