鸿蒙应用开发学习:改进小鱼动画实现按键一直按下时控制小鱼移动和限制小鱼移出屏幕

这篇具有很好参考价值的文章主要介绍了鸿蒙应用开发学习:改进小鱼动画实现按键一直按下时控制小鱼移动和限制小鱼移出屏幕。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、前言

近期我在学习鸿蒙应用开发,跟着B站UP主黑马程序员的视频教程做了一个小鱼动画应用,UP主提供的小鱼动画源代码仅仅实现了移动组件的功能,还存在一些问题,如默认进入页面是竖屏而页面适合横屏显示;真机测试发现手机的状态栏影响到了返回键对按键事件的响应;方向键不能响应一直按着的操作;还有小鱼会移出屏幕范围。

之前已经解决了强制横屏和隐藏手机状态栏,这次则是通过一番研究,实现了按键一直按下时控制小鱼移动和限制小鱼移出屏幕这两个功能。

鸿蒙应用开发学习:改进小鱼动画实现按键一直按下时控制小鱼移动和限制小鱼移出屏幕,学习笔记,问题解决,鸿蒙应用开发学习,学习,华为,鸿蒙系统,harmonyos

二、实现方法

1. 一直按下方向键时控制小鱼移动

实现这一功能是在方向键下添加onTouch方法,对按键一直按下事件进行响应。在onTouch方法中还需要判断TouchType.Down事件和TouchType.Up事件。在TouchType.Down事件时,添加animateTo方法,实现按键时一直控制小鱼移动(需要通过setInterval方法设置定时任务让animateTo方法定期执行)。在TouchType.Up事件时,通过clearInterval清除定时任务,小鱼就不会一直移动了。以向右按键为例,改造后的代码如下:

Button('→').backgroundColor('#20101010')
            .onClick(() => {              
                animateTo(
                 { duration: 500 },
                 () => {
                   this.src = $r('app.media.fish')
                   this.fishX += this.speed
                 }
               )
            })
            .onTouch((event: TouchEvent) => {
              if (event.type === TouchType.Down) {
                this.taskId = setInterval(() => {
                  animateTo(
                    { duration: 500 },
                    () => {                      
                    this.src = $r('app.media.fish')
                    this.fishX += this.speed
                    }
                  )
                }, 200)
              }
              if (event.type === TouchType.Up) {
                clearInterval(this.taskId)
                this.taskId = -1
              }
            })

        }
        .height(240)
        .width(240)
        .justifyContent(FlexAlign.Center)
        .position({ x: 0, y: 120 })

2.限制小鱼移出屏幕

实现了上面的代码后,一直按下方向键,小鱼终于可以一直移动了,但往一个方向一直移动就会移出屏幕,为让小鱼不移出屏幕,还需要对按键操作事件进行判断,检查当前小鱼的位置,只有小鱼在限制的范围内才能执行animateTo方法移动小鱼。

按下向左方向键:对小鱼的X坐标(this.fishX)进行判断。屏幕左侧边界的X值为0,小鱼的大小为40(this.fishSize)。this.fishX是小鱼图片中心点的坐标,则当小鱼接触到屏幕左侧边界时,小鱼的中心点X坐标值为20。本软件中设置的小鱼的移动速度为20(this.speed),因此,我设置的判断条件是当this.fishX >= this.fishSize时,才能执行animateTo方法。当this.fishX == 40时,再移动一次this.fishX就变成了20,此时小鱼图片的左侧边缘正好接触到屏幕左边界。

按下向上方向键:对小鱼的Y坐标(this.fishY)进行判断。屏幕上边界Y值为0,小鱼大小为40。原理和按下向左方向机一样。我设置的判断条件是当this.fishY >= this.fishSize时,才能执行animateTo方法。

对于屏幕下方的边界和屏幕右侧的边界判断需要导入模块 import display from '@ohos.display' ,并在页面的onPageShow方法获取屏幕的尺寸信息。

onPageShow() {
    // 获取旋转的方向,具体可以查看对应文档
    let orientation = window.Orientation.LANDSCAPE;

    // 获取屏幕尺寸信息
    let promise = display.getAllDisplays()
    promise.then((data) => {
      console.info('设备屏幕信息:' + JSON.stringify(data));
      console.info('testTag', '屏幕宽度px:' + JSON.stringify(data[0].width));
      console.info('testTag', '屏幕高度px:' + JSON.stringify(data[0].height));
      this.screenWidth = px2vp(data[0].width)
      this.screenHeight = px2vp(data[0].height)
      console.info('testTag', '屏幕宽度vp:' + JSON.stringify(this.screenWidth));
      console.info('testTag', '屏幕高度vp:' + JSON.stringify(this.screenHeight));
    }).catch((err) => {
      console.error('错误信息:' + JSON.stringify(err));
    })
  }

按下向右方向机:对小鱼的X坐标(this.fishX)进行判断。屏幕右侧边界的X值为变量this.screenHeight, 则判定语句为 this.fishX <= this.screenHeight - this.fishSize 。只有符合该条件是才执行animateTo方法。

按下向下方向机:对小鱼的Y坐标(this.fishY)进行判断。屏幕右侧边界的Y值为变量this.screenWidth, 则判定语句为 this.fishY <= this.screenWidth - this.fishSize 。只有符合该条件是才执行animateTo方法。

这些判断语句都要添加到方向键的onClick方法和onTouch方法。

三、完整源代码

最后上这个文件的完整源代码:

import router from '@ohos.router';
import window from '@ohos.window'; // 用于强制设为横屏
import display from '@ohos.display'

@Entry
@Component
struct Aquarium1Page {
  onPageShow() {
    // 获取旋转的方向,具体可以查看对应文档
    let orientation = window.Orientation.LANDSCAPE;
    try {
      // 设置屏幕旋转
      globalThis.windowClass.setPreferredOrientation(orientation, (err) => {
        console.log('testTag', `onPageShow函数中setPreferredOrientation方法错误码为${err}`)
      });
    } catch (exception) {
      console.error('设置失败: ' + JSON.stringify(exception));
    }
    // 获取屏幕尺寸信息
    let promise = display.getAllDisplays()
    promise.then((data) => {
      console.info('设备屏幕信息:' + JSON.stringify(data));
      console.info('testTag', '屏幕宽度px:' + JSON.stringify(data[0].width));
      console.info('testTag', '屏幕高度px:' + JSON.stringify(data[0].height));
      this.screenWidth = px2vp(data[0].width)
      this.screenHeight = px2vp(data[0].height)
      console.info('testTag', '屏幕宽度vp:' + JSON.stringify(this.screenWidth));
      console.info('testTag', '屏幕高度vp:' + JSON.stringify(this.screenHeight));
    }).catch((err) => {
      console.error('错误信息:' + JSON.stringify(err));
    })
  }

  onPageHide() {
    // 获取旋转的方向,具体可以查看对应文档
    let orientation = window.Orientation.PORTRAIT;
    try {
      // 设置屏幕旋转
      globalThis.windowClass.setPreferredOrientation(orientation, (err) => {
        console.log('testTag', `onPageHide函数中setPreferredOrientation方法错误码为${err}`)
      });
    } catch (exception) {
      console.error('设置失败: ' + JSON.stringify(exception));
    }
  }

  // 小鱼的位置
  @State fishX: number = 200
  @State fishY: number = 180
  // 小鱼的大小
  fishSize: number = 40
  // 小鱼角度
  @State angle: number = 0
  // 小鱼图片
  @State src: Resource = $r('app.media.fish')
  // 是否开始游戏
  @State isBegin: boolean = false
  // 小鱼的速度
  speed: number = 20
  // 用于控制Interval的id
  taskId: number = -1
  // 屏幕尺寸
  screenWidth: number = px2vp(2000)
  screenHeight: number = px2vp(1080)

  build() {
    Row() {
      Stack() {
        Button('返回')
          .position({ x: 20, y: 20 })
          .backgroundColor('#20101010')
          .onClick(() => {
            router.back()
          })

        if (!this.isBegin) {
          Button('开始游戏')
            .onClick(() => {
              animateTo(
                { duration: 1000 },
                () => {
                  // 点击后显示小鱼
                  this.isBegin = true
                }
              )
            })
        } else {
          // 小鱼图片
          Image(this.src)
            .position({ x: this.fishX - 20, y: this.fishY - 20 })
            .rotate({ angle: this.angle, centerX: '50%', centerY: '50%' })
            .width(this.fishSize)
            .height(this.fishSize)
              //.animation({duration: 500, curve: Curve.Smooth})
            .transition({
              type: TransitionType.Insert,
              opacity: 0,
              translate: { x: -250 }
            })
        }
        // 操作按钮
        Row() {
          // 向左移动,小鱼身体不能超出屏幕范围
          Button('←').backgroundColor('#20101010')
            .onClick(() => {
              if (this.fishX >= this.fishSize) {
                animateTo(
                  { duration: 500 },
                  () => {
                    this.src = $r('app.media.fish_rev')
                    this.fishX -= this.speed
                  }
                )
              }
            })
            .onTouch((event: TouchEvent) => {
              if (event.type === TouchType.Down) {
                this.taskId = setInterval(() => {
                  animateTo(
                    { duration: 500 },
                    () => {
                      if (this.fishX >= this.fishSize) {
                        this.src = $r('app.media.fish_rev')
                        this.fishX -= this.speed
                      }
                    }
                  )
                }, 200)
              }
              if (event.type === TouchType.Up) {
                clearInterval(this.taskId)
                this.taskId = -1
              }
            })

          Column({ space: 40 }) {
            // 向上和向下移动,小鱼的身体均不能超出屏幕范围
            Button('↑').backgroundColor('#20101010')
              .onClick(() => {
                if (this.fishY >= this.fishSize) {
                  animateTo(
                    { duration: 500 },
                    () => {
                      this.fishY -= this.speed
                    }
                  )
                }
              })
              .onTouch((event: TouchEvent) => {
                if (event.type === TouchType.Down) {
                  this.taskId = setInterval(() => {
                    animateTo(
                      { duration: 500 },
                      () => {
                        if (this.fishY >= this.fishSize) {
                          this.fishY -= this.speed
                        }
                      }
                    )
                  }, 200)
                }
                if (event.type === TouchType.Up) {
                  console.log("testTag", `停止向上,当前fishY为:${this.fishY}`)
                  clearInterval(this.taskId)
                  this.taskId = -1
                }
              })
            Button('↓').backgroundColor('#20101010')
              .onClick(() => {
                if (this.fishY <= this.screenWidth - this.fishSize) {
                  animateTo(
                    { duration: 500 },
                    () => {
                      this.fishY += this.speed
                    }
                  )
                }
              })
              .onTouch((event: TouchEvent) => {
                if (event.type === TouchType.Down) {
                  this.taskId = setInterval(() => {
                    animateTo(
                      { duration: 500 },
                      () => {
                        if (this.fishY <= this.screenWidth - this.fishSize) {
                          this.fishY += this.speed
                        }
                      }
                    )
                  }, 200)
                }
                if (event.type === TouchType.Up) {
                  console.log("testTag", `停止向下,当前fishY为:${this.fishY}`)
                  clearInterval(this.taskId)
                  this.taskId = -1
                }
              })
          }

          Button('→').backgroundColor('#20101010')
            .onClick(() => {
              if (this.fishX <= this.screenHeight - this.fishSize) {
                animateTo(
                  { duration: 500 },
                  () => {
                    this.src = $r('app.media.fish')
                    this.fishX += this.speed
                  }
                )
              }
            })
            .onTouch((event: TouchEvent) => {
              if (event.type === TouchType.Down) {
                this.taskId = setInterval(() => {
                  animateTo(
                    { duration: 500 },
                    () => {
                      if (this.fishX <= this.screenHeight - this.fishSize) {
                        this.src = $r('app.media.fish')
                        this.fishX += this.speed
                      }
                    }
                  )
                }, 200)
              }
              if (event.type === TouchType.Up) {
                clearInterval(this.taskId)
                this.taskId = -1
              }
            })

        }
        .height(240)
        .width(240)
        .justifyContent(FlexAlign.Center)
        .position({ x: 0, y: 120 })
      }
      .height('100%').width('100%')
    }
    .width('100%')
    .height('100%')
    .backgroundImage($r('app.media.underwater_cartoon'))
    .backgroundImageSize({ height: '100%', width: '100%' })

  }
}

四、B站视频链接:

鸿蒙应用开发学习:改进小鱼动画实现按键一直按下时控制小鱼移动和限制小鱼移出屏幕-CSDN博客文章来源地址https://www.toymoban.com/news/detail-791171.html

到了这里,关于鸿蒙应用开发学习:改进小鱼动画实现按键一直按下时控制小鱼移动和限制小鱼移出屏幕的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenHarmony开源鸿蒙学习入门 - 基于3.2Release 应用开发环境安装

    基于目前官方master主支,最新文档版本3.2Release,更新应用开发环境安装文档。 一、安装IDE: 1.IDE安装的系统要求 2.IDE下载官网链接 (IDE下载链接) 3.下载完成后进行IDE安装。 【最新的IDE,HarmonyOS和OpenHarmony的IDE已经统一,只是SDK管理分开】 IDE的依赖有 node.js 和 Ohpm。 有两种

    2024年02月15日
    浏览(55)
  • OpenHarmony鸿蒙原生应用开发,ArkTS、ArkUI学习踩坑学习笔记,持续更新中。

    结论:在BIOS里面将Hyper-V打开,DevEco Studio模拟器可以成功启动。 如果在另外的文件中引用组件,需要使用export导出,并在使用的页面import该自定义组件。 1.自定义组件(被导入组件) 2.组合组件(引用自定义组件) 1、main_pages.json配置文件配置静态路由地址,配置文件

    2024年02月04日
    浏览(60)
  • HarmonyOS 鸿蒙应用开发(十一、面向鸿蒙开发的JavaScript基础)

    ArkTS 是HarmonyOS(鸿蒙操作系统)原生应用开发的首选语言。它是用于构建用户界面的一种TypeScript方言,扩展了TypeScript以适应HarmonyOS生态系统的UI开发需求。ArkTS 融合了TypeScript的静态类型系统和现代UI框架的设计理念,为开发者提供了一种更安全高效的方式来编写HarmonyOS应用。

    2024年02月20日
    浏览(40)
  • 鸿蒙实战:ArkTs 开发一个鸿蒙应用

    学习过的 ArkTs 知识点,一步一步开发一个小的鸿蒙应用示例,涉及到  ArkTs 语法、注解 @Entry 、 @Component 、 @state 、路由、生命周期、 @Prop 、 @Link 、常用组件的使用等等知识点。 要开发一个鸿蒙应用,首先我们需要知道 系统是如何找到页面的启动入口 。 鸿蒙如何启动应用

    2024年02月22日
    浏览(41)
  • 【HarmonyOS】开发一个可以看小姐姐的鸿蒙应用 鸿蒙开发入门

    先整张效果图,丑点是丑点,但可以用,买不起鸿蒙系统手机的我,只配用虚拟机。 要说目前最火的手机操作系统,要我来看的话那必然是鸿蒙无疑。16号刚刚结束了第五次鸿蒙内测,在看到这次的内测名单之后,居然有970的机器,这是不是说明俺这手里奋战了三年的荣耀

    2024年02月15日
    浏览(61)
  • 鸿蒙应用开发--事件

    代码书写步骤 根据需求调用响应的接口 获取组件ID 设置监听事件 编写点组件触发后的动作 事件分类 单击事件 双击事件 长按事件 滑动事件 调用接口 获取组件ID 设置监听事件 当前类作为接口实现类 当前类继承接口,在本类中重写父类方法。 定义接口实现类 重新写一个类

    2024年02月09日
    浏览(29)
  • 鸿蒙(HarmonyOS)应用开发指南

    1.1 简介 鸿蒙 (即 HarmonyOS ,开发代号 Ark ,正式名称为华为终端鸿蒙智能设备操作系统软件)是华为公司自 2012 年以来开发的一款可支持鸿蒙原生应用和兼容 AOSP 应用的 分布式操作系统 。该系统利用“分布式”技术将 手机、电脑、平板、电视、汽车和智能穿戴 等多款设备

    2024年02月02日
    浏览(47)
  • 鸿蒙3.0应用开发体验

    鸿蒙os3.0发布以来,华为官方开始主推ets+arkui开发模式,逐渐抛弃java,为以后去安卓化做铺垫,但目前在笔者体验来看,仍需要大力完善,还有很长的路要走! 什么是ets?ts是js的超集,而ets是ts的超集!ets后缀的文件中可以使用鸿蒙SDKapi的能力,就这么简单!而arkui则与Flu

    2024年02月09日
    浏览(34)
  • 【鸿蒙】鸿蒙操作系统应用开发入门级初体验

    目录   一 鸿蒙相关资源 二 创建新工程 三 程序设计 鸿蒙学堂:https://hmxt.org/   (1)下载鸿蒙的IDE:DevEco Studio,安装过程一路next即可; (2)安装好之后,新建工程,我这边使用Java进行开发,所以选择Empty Ability(Java),选择完成之后,点击Next: (3)工程配置,主要配置一下

    2024年02月07日
    浏览(35)
  • 鸿蒙HarmonyOS应用开发初体验

    最近华为发布mt60新机火了,作为一名移动开发程序员,对鸿蒙系统开发移动端就很感兴趣了。 开发工具:HUAWEI DevEco Studio和SDK下载和升级 | HarmonyOS开发者 下载完后按默认安装就可以了,界面跟AS很类似,之前我jdk环境配置就不在配置了,不懂的可以百度下很多教程。 这是基

    2024年02月09日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包