首页 > 其他分享 >鸿蒙NEXT开发案例:抛硬币

鸿蒙NEXT开发案例:抛硬币

时间:2024-11-12 13:19:24浏览次数:3  
标签:cellWidth 鸿蒙 硬币 lpx NEXT width 地鼠 宽度 组件

鸿蒙NEXT开发案例:抛硬币

 

【1】引言(完整代码在最后面)

本项目旨在实现一个简单的“抛硬币”功能,用户可以通过点击屏幕上的地鼠图标来模拟抛硬币的过程。应用会记录并显示硬币正面(地鼠面)和反面(数字100面)出现的次数。为了增强用户体验,我们还添加了动画效果,使抛硬币的过程更加生动有趣。

【2】环境准备

电脑系统:windows 10

开发工具:DevEco Studio NEXT Beta1 Build Version: 5.0.3.806

工程版本:API 12

真机:mate60 pro

语言:ArkTS、ArkUI

【3】应用结构

应用主要由两个部分组成:地鼠组件(Hamster)和主页面组件(CoinTossPage)。

地鼠组件(Hamster)

地鼠组件是应用的核心视觉元素之一,负责展示地鼠的形象。该组件通过@Component装饰器定义,并接收一个属性cellWidth,用于控制组件的大小。

主页面组件(CoinTossPage)

主页面组件是整个应用的入口点,负责组织和管理各个UI元素。该组件同样通过@Component装饰器定义,并包含多个状态变量用于跟踪硬币的状态和动画进度。

【4】功能解析

1. 地鼠组件:

• 通过Stack布局组合多个图形元素,创建了一个地鼠的形象。

• 每个图形元素都设置了具体的尺寸、颜色、边框等样式,并通过margin属性调整位置。

2. 主页面组件:

• 顶部有一个“抛硬币”的标题,下方是一个行布局,用于展示地鼠组件及正反两面出现的次数。

• 地鼠组件被放置在一个圆形区域内,背景采用线性渐变色。

• 点击地鼠时,会触发一系列动画效果,模拟硬币抛起再落下的过程。

• 通过计算最终的角度,判断是正面还是反面朝上,并更新相应的计数。

【完整代码】

// 定义地鼠组件

@Component

struct Hamster {

  @Prop cellWidth: number // 单元格宽度

  build() {

    Stack() { // 创建一个堆叠布局

      // 身体

      Text()

        .width(`${this.cellWidth / 2}lpx`)// 宽度为单元格宽度的一半

        .height(`${this.cellWidth / 3 * 2}lpx`)// 高度为单元格高度的2/3

        .backgroundColor("#b49579")// 背景颜色

        .borderRadius({ topLeft: '50%', topRight: '50%' })// 圆角

        .borderColor("#2a272d")// 边框颜色

        .borderWidth(1) // 边框宽度

      // 嘴巴

      Ellipse()

        .width(`${this.cellWidth / 4}lpx`)// 嘴巴的宽度

        .height(`${this.cellWidth / 5}lpx`)// 嘴巴的高度

        .fillOpacity(1)// 填充不透明度

        .fill("#e7bad7")// 填充颜色

        .stroke("#563e3f")// 边框颜色

        .strokeWidth(1)// 边框宽度

        .margin({ top: `${this.cellWidth / 6}lpx` }) // 上边距

      // 左眼睛

      Ellipse()

        .width(`${this.cellWidth / 9}lpx`)// 左眼睛的宽度

        .height(`${this.cellWidth / 6}lpx`)// 左眼睛的高度

        .fillOpacity(1)// 填充不透明度

        .fill("#313028")// 填充颜色

        .stroke("#2e2018")// 边框颜色

        .strokeWidth(1)// 边框宽度

        .margin({ bottom: `${this.cellWidth / 3}lpx`, right: `${this.cellWidth / 6}lpx` }) // 下边距和右边距

      // 右眼睛

      Ellipse()

        .width(`${this.cellWidth / 9}lpx`)// 右眼睛的宽度

        .height(`${this.cellWidth / 6}lpx`)// 右眼睛的高度

        .fillOpacity(1)// 填充不透明度

        .fill("#313028")// 填充颜色

        .stroke("#2e2018")// 边框颜色

        .strokeWidth(1)// 边框宽度

        .margin({ bottom: `${this.cellWidth / 3}lpx`, left: `${this.cellWidth / 6}lpx` }) // 下边距和左边距

      // 左眼瞳

      Ellipse()

        .width(`${this.cellWidth / 20}lpx`)// 左眼瞳的宽度

        .height(`${this.cellWidth / 15}lpx`)// 左眼瞳的高度

        .fillOpacity(1)// 填充不透明度

        .fill("#fefbfa")// 填充颜色

        .margin({ bottom: `${this.cellWidth / 2.5}lpx`, right: `${this.cellWidth / 6}lpx` }) // 下边距和右边距

      // 右眼瞳

      Ellipse()

        .width(`${this.cellWidth / 20}lpx`)// 右眼瞳的宽度

        .height(`${this.cellWidth / 15}lpx`)// 右眼瞳的高度

        .fillOpacity(1)// 填充不透明度

        .fill("#fefbfa")// 填充颜色

        .margin({ bottom: `${this.cellWidth / 2.5}lpx`, left: `${this.cellWidth / 6}lpx` }) // 下边距和左边距

    }.width(`${this.cellWidth}lpx`).height(`${this.cellWidth}lpx`) // 设置组件的宽度和高度

  }

}

// 定义页面组件

@Entry

@Component

struct CoinTossPage {

  @State cellWidth: number = 50 // 单元格宽度

  @State headsCount: number = 0 // 正面朝上的次数

  @State tailsCount: number = 0 // 反面朝上的次数

  @State rotationAngle: number = 0 // 旋转角度

  @State verticalOffset: number = 0 // 纵向位移

  @State isAnimRun: boolean = false // 动画是否正在执行

  build() {

    Column() {

      // 页面标题

      Text('抛硬币')

        .height(50)// 高度设置为50

        .width('100%')// 宽度设置为100%

        .textAlign(TextAlign.Center)// 文本居中对齐

        .fontColor("#fefefe")// 字体颜色

        .fontSize(20); // 字体大小

      // 显示地鼠和计数

      Row({ space: 20 }) {

        Stack() {

          Hamster({ cellWidth: this.cellWidth }) // 创建地鼠组件

        }

        .borderRadius('50%') // 设置圆角

        .width(`${this.cellWidth}lpx`) // 设置宽度

        .height(`${this.cellWidth}lpx`) // 设置高度

        .linearGradient({

          // 设置线性渐变背景

          direction: GradientDirection.LeftBottom,

          colors: [['#ebcf2f', 0.0], ['#fef888', 0.5], ['#ebcf2f', 1.0]]

        });

        // 显示反面朝上的次数

        Text(`${this.tailsCount}`)

          .fontSize(20)

          .fontColor("#fefefe");

        Stack() {

          // 显示100

          Text("100")

            .fontColor("#9f7606")

            .fontSize(`${this.cellWidth / 2}lpx`);

        }

        .borderRadius('50%') // 设置圆角

        .width(`${this.cellWidth}lpx`) // 设置宽度

        .height(`${this.cellWidth}lpx`) // 设置高度

        .linearGradient({

          // 设置线性渐变背景

          direction: GradientDirection.LeftBottom,

          colors: [['#ebcf2f', 0.0], ['#fef888', 0.5], ['#ebcf2f', 1.0]]

        });

        // 显示正面朝上的次数

        Text(`${this.headsCount}`)

          .fontSize(20)

          .fontColor("#fefefe");

      }.width('100%').justifyContent(FlexAlign.Center); // 设置宽度和内容居中对齐

      Stack() {

        Stack() {

          // 创建放大版地鼠组件

          Hamster({ cellWidth: this.cellWidth * 3 })

            .visibility(this.isHeadsFaceUp() ? Visibility.Visible : Visibility.Hidden); // 根据状态显示或隐藏

          // 显示100

          Text("100")

            .fontColor("#9f7606")// 字体颜色

            .fontSize(`${this.cellWidth / 2 * 3}lpx`)// 字体大小

            .visibility(!this.isHeadsFaceUp() ? Visibility.Visible : Visibility.Hidden)// 根据状态显示或隐藏

            .rotate({

              // 旋转180度

              x: 1,

              y: 0,

              z: 0,

              angle: 180

            });

        }

        .borderRadius('50%') // 设置圆角

        .width(`${this.cellWidth * 3}lpx`) // 设置宽度

        .height(`${this.cellWidth * 3}lpx`) // 设置高度

        .linearGradient({

          // 设置线性渐变背景

          direction: GradientDirection.LeftBottom,

          colors: [['#ebcf2f', 0.0], ['#fef888', 0.5], ['#ebcf2f', 1.0]]

        })

        .rotate({

          // 根据当前角度旋转

          x: 1,

          y: 0,

          z: 0,

          angle: this.rotationAngle

        })

        .translate({ x: 0, y: this.verticalOffset }) // 设置纵向位移

        .onClick(() => { // 点击事件处理

          if (this.isAnimRun) {

            return;

          }

          this.isAnimRun = true

          let maxAnimationSteps = 2 * (10 + Math.floor(Math.random() * 10)); // 计算最大动画次数

          let totalAnimationDuration = 2000; // 动画总时长

          // 第一次动画,向上抛出

          animateToImmediately({

            duration: totalAnimationDuration / 2, // 动画时长为总时长的一半

            onFinish: () => { // 动画完成后的回调

              // 第二次动画,向下落

              animateToImmediately({

                duration: totalAnimationDuration / 2,

                onFinish: () => {

                  this.rotationAngle = this.rotationAngle % 360; // 确保角度在0到360之间

                  // 判断当前显示的面

                  if (this.isHeadsFaceUp()) { // 如果是地鼠面

                    this.tailsCount++; // 反面朝上的次数加1

                  } else { // 如果是反面

                    this.headsCount++; // 正面朝上的次数加1

                  }

                  this.isAnimRun = false

                }

              }, () => {

                this.verticalOffset = 0; // 重置纵向位移

              });

            }

          }, () => {

            // 设置纵向位移,模拟抛硬币的效果

            this.verticalOffset = -100 * (1 + Math.floor(Math.random() * 5)); // 随机设置向上的位移

          });

          // 循环动画,增加旋转效果

          for (let i = 0; i < maxAnimationSteps; i++) {

            animateToImmediately({

              delay: i * totalAnimationDuration / maxAnimationSteps, // 设置每次动画的延迟

              duration: 100, // 每次动画的持续时间

              onFinish: () => {

                // 动画完成后的回调

              }

            }, () => {

              this.rotationAngle += 90; // 每次增加90度旋转

            });

          }

        });

      }.width('100%').layoutWeight(1).align(Alignment.Bottom).padding({ bottom: 80 }); // 设置组件的

宽度、权重、对齐方式和底部内边距

    }

    .height('100%') // 设置整个页面的高度

    .width('100%') // 设置整个页面的宽度

    .backgroundColor("#0b0d0c"); // 设置背景颜色

  }

  // 判断当前是否显示地鼠面

  isHeadsFaceUp() {

    let normalizedAngle = this.rotationAngle % 360; // 规范化角度

标签:cellWidth,鸿蒙,硬币,lpx,NEXT,width,地鼠,宽度,组件
From: https://blog.csdn.net/weixin_55010563/article/details/143670736

相关文章

  • 鸿蒙高质量代码静态检测200条一
    @typescript-eslint/adjacent-overload-signatures建议函数重载的签名保持连续@typescript-eslint/await-thenable不允许对不是“Thenable”对象的值使用await关键字,相反对“Thenable”对象必须使用await,例如对Promise对象。@typescript-eslint/array-type定义数......
  • 鸿蒙开发之用户输入(TextInput)
    前言:日常开发中如果需要接收用户输入,就可以使用输入组件来完成TextInput:单行输入框:常用参数:参数名类型是否必填说明placeholderResourceStr否设置无输入时的提示文本。textResourceStr否设置输入框当前的文本内容。从APIversion10开始,该参数......
  • 博客搭建之路:next主题数学公式问题
    next主题数学公式问题我写的都是一些编程相关的文章,有些文章里是存在数学公式的,我在Typora软件中写的时候显示的是对的,但是hexo将markdown转为html后在页面上就没有数学公式的格式了。查找next配置发现有一个渲染数学公式的配置math:#Default(true)willloadmathjax/k......
  • 基于HarmonyOS Next的医疗数据防泄漏与身份认证方案:Device Certificate Kit的深度应用
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。在医疗信息化快速发展的今天,医疗......
  • HarmonyOS Next企业级设备认证解决方案:基于Device Certificate Kit的多层级身份验证
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。在企业数字化转型的浪潮中,大量设......
  • HarmonyOS Next在智能家居领域的安全架构:设备身份认证与数据防泄漏方案
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。在智能家居蓬勃发展的今天,各种智......
  • 基于HarmonyOS Next的营销防薅羊毛设计:Device Certificate Kit的活动防护策略
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。在电商和营销活动日益频繁的今天,......
  • HarmonyOS Next在游戏防作弊系统中的应用:利用Device Certificate Kit对外挂的智能识别
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。在当今蓬勃发展的游戏产业中,游戏公平性......
  • 基于HarmonyOS Next的营销防薅羊毛设计:Device Certificate Kit的活动防护策略
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。在电商和营销活动日益频繁的今天,黑灰产......
  • 鸿蒙NEXT开发案例:指尖轮盘
     【1】引言“指尖轮盘”是一个简单而有趣的互动游戏(类似抓阄),这个应用通过触摸屏幕的方式,让玩家参与一个激动人心的游戏,最终选出幸运的赢家。未来可以进一步扩展功能,如增加游戏模式、优化动画效果、增加音效等,提升用户体验。【2】环境准备电脑系统:windows10开发工具:DevEco......