
HarmonyOS ArkTS 实战实现一个掷骰子模拟器项目效果本文实现的是一个基于 HarmonyOS 和 ArkTS 的掷骰子模拟器。项目中使用 ArkUI 组件完成页面布局通过State管理状态数据实现1-6个骰子选择、投掷动画、骰子点数显示、总和计算和投掷历史等功能。最终运行效果如下页面主要包含以下内容顶部应用标题骰子显示区域用圆点显示点数投掷动画效果骰子数量选择大投掷按钮点数总和显示投掷历史记录页面整体采用 ArkUI 声明式布局。本文重点是演示如何在 HarmonyOS 项目中使用 ArkTS 和 ArkUI 实现一个趣味小工具单页面应用。项目代码主要写在entry/src/main/ets/pages/Index.ets文件中适合作为 HarmonyOS ArkTS 入门到进阶之间的练习案例。前言掷骰子是很多桌游和游戏中必不可少的环节有时候手边没有骰子手机上的骰子模拟器就很方便。一个好的骰子模拟器不仅能随机出点数还要有投掷的动画效果增加真实感和趣味性。从应用开发角度来看这个项目不依赖后端接口也不需要数据库但能练习 ArkTS 中的状态管理、动画效果、组件封装、随机数和列表渲染等内容。本文基于 HarmonyOS 和 ArkTS 实现一个掷骰子模拟器。用户可以选择1-6个骰子点击投掷按钮骰子会有旋转动画最后显示随机点数计算总和并记录投掷历史。这个项目的核心不是简单的随机数而是流畅的投掷动画和直观的骰子显示。每一次投掷都有视觉反馈让用户有真实掷骰子的感觉这正是 ArkUI 动画的魅力所在。一、项目目标本次实践主要实现以下目标创建 HarmonyOS ArkTS 页面使用Entry和Component定义页面组件使用State管理页面状态自定义骰子组件用圆点显示点数支持1-6个骰子选择投掷时的旋转动画随机生成1-6点数自动计算点数总和记录投掷历史骰子点数用圆点图形表示使用Builder封装骰子面和历史项完成一个可以运行的掷骰子模拟器页面。这个项目虽然是单页面应用但它实现了有趣的动画效果和完整的投掷功能比普通静态页面更适合练习 ArkTS。二、技术栈类型内容开发方向HarmonyOS 应用开发开发语言ArkTSUI 框架ArkUISDK 版本HarmonyOS API 23 及以上工程模型Stage 模型核心组件Text / Button / Column / Row / Flex / Circle状态管理State数据处理随机数 / 动画效果 / 历史记录项目入口entry/src/main/ets/pages/Index.ets运行平台模拟器或真机本项目是 HarmonyOS 原生 ArkTS 项目。页面主体由 ArkUI 组件构建核心逻辑写在Index.ets文件中不依赖后端接口也不需要额外配置数据库。三、为什么选择掷骰子模拟器项目掷骰子模拟器适合作为 ArkTS 练习项目主要有以下几个原因。第一趣味性强。掷骰子有随机性和动画效果玩起来很有趣。第二视觉效果好。骰子用圆点表示点数动画旋转界面美观。第三适合练习自定义组件。骰子可以封装成独立组件练习组件化思想。第四适合练习动画效果。投掷时的旋转动画是基础动画练习。第五适合练习随机数。随机生成1-6的点数模拟真实骰子。第六扩展空间比较大。基础功能完成后可以继续增加不同面数的骰子4面/8面/10面/20面、骰子皮肤、掷骰子声音、多轮游戏和统计分析。在本项目中骰子数量和每个骰子的点数是核心数据。所有显示和计算都基于这些数据。四、功能规则说明骰子数量1-6个默认2个。点数范围每个骰子1-6点均匀随机。动画效果投掷时骰子旋转360度持续500毫秒。总和计算自动计算所有骰子点数之和。历史记录最多记录最近20次投掷结果显示每次的点数和总和。骰子显示白色圆角正方形黑色圆点表示点数标准骰子点数排列。五、项目结构本项目主要修改首页文件entry └── src └── main └── ets └── pages └── Index.ets其中文件作用Index.ets编写页面结构、状态数据和骰子逻辑本文不涉及复杂路由也不需要额外创建多个页面。对于练习项目来说把主要逻辑集中在一个Index.ets文件中更方便理解。六、核心实现思路本项目的核心流程如下使用State保存骰子数量、每个骰子点数、是否正在动画用户选择骰子数量点击投掷按钮触发旋转动画动画期间快速切换点数制造滚动效果动画结束后确定最终点数用圆点图形显示每个骰子的点数计算点数总和将结果添加到历史记录点击历史可以查看详情。项目中最重要的状态变量如下State diceCount: number 2 State diceValues: number[] [1, 1] State isRolling: boolean false State history: { values: number[], total: number }[] []其中状态变量作用diceCount骰子数量diceValues每个骰子的点数isRolling是否正在投掷动画中history投掷历史记录骰子点数数组是本项目中最重要的数据所有显示都基于它。七、Index.ets 完整代码打开文件entry/src/main/ets/pages/Index.ets将其中内容替换为下面代码EntryComponentstruct Index{StatediceCount:number2StatediceValues:number[][1,1]StateisRolling:booleanfalseStatehistory:{values:number[],total:number}[][]Staterotation:number0privatecountOptions:number[][1,2,3,4,5,6]privaterollDice():void{if(this.isRolling)returnthis.isRollingtruethis.rotation0letrollIntervalsetInterval((){this.diceValuesthis.diceValues.map((){returnMath.floor(Math.random()*6)1})},80)animateTo({duration:500,curve:Curve.EaseOut,onFinish:(){clearInterval(rollInterval)this.isRollingfalseletfinalValuesthis.diceValues.map((){returnMath.floor(Math.random()*6)1})this.diceValuesfinalValueslettotalfinalValues.reduce((sum,v)sumv,0)this.history[{values:[...finalValues],total},...this.history].slice(0,20)}},(){this.rotation360})}privatesetDiceCount(count:number):void{if(this.isRolling)returnthis.diceCountcountthis.diceValuesnewArray(count).fill(1)}privategetTotal():number{returnthis.diceValues.reduce((sum,v)sumv,0)}BuilderDiceFace(value:number){Stack(){Column(){if(value2){Row(){Circle().width(12).height(12).fill(#1F2937)Blank()if(value3){Circle().width(12).height(12).fill(#1F2937)}}.width(100%).layoutWeight(1)}if(value1||value3||value5){Row(){Blank()Circle().width(12).height(12).fill(#1F2937)Blank()}.width(100%).layoutWeight(1)}if(value2){Blank().layoutWeight(1)Row(){if(value4){Circle().width(12).height(12).fill(#1F2937)}Blank()Circle().width(12).height(12).fill(#1F2937)}.width(100%).layoutWeight(1)}}.width(100%).height(100%).padding(16)}.width(80).height(80).backgroundColor(Color.White).borderRadius(16).shadow({radius:8,color:#08000000,offsetX:0,offsetY:4}).rotate({angle:this.rotation}).animation({duration:500,curve:Curve.EaseOut})}BuilderHistoryItem(item:{values:number[],total:number},index:number){Row(){Text(#${this.history.length-index}).fontSize(14).fontColor(#9CA3AF).width(40)Text(item.values.join( )).fontSize(15).fontColor(#4B5563).layoutWeight(1)Text(${item.total}).fontSize(16).fontWeight(FontWeight.Bold).fontColor(#0A59F7)}.width(100%).padding({top:12,bottom:12}).border({width:{bottom:1},color:#F3F4F6})}build(){Column(){Text(掷骰子).fontSize(28).fontWeight(FontWeight.Bold).fontColor(#182431).margin({top:22})Text(基于 HarmonyOS ArkTS 的骰子模拟器).fontSize(14).fontColor(#6B7280).margin({top:8,bottom:20})Column(){Flex({wrap:FlexWrap.Wrap,justifyContent:FlexAlign.Center}){ForEach(this.diceValues,(value:number,index:number){this.DiceFace(value).margin({right:12,bottom:12,left:index%30?12:0})},(v:number,i:number)${i}-${v})}.width(100%).padding({top:24,bottom:20})Text(点数总和${this.getTotal()}).fontSize(24).fontWeight(FontWeight.Bold).fontColor(#0A59F7).margin({bottom:20})Button(this.isRolling?投掷中...: 投掷骰子).width(100%).height(56).fontSize(18).fontColor(Color.White).backgroundColor(this.isRolling?#9CA3AF:#EF4444).borderRadius(28).enabled(!this.isRolling).onClick((){this.rollDice()})}.width(100%).padding(20).backgroundColor(Color.White).borderRadius(16).margin({bottom:16}).shadow({radius:8,color:#08000000,offsetX:0,offsetY:2})Column(){Text(骰子数量).fontSize(16).fontWeight(FontWeight.Medium).fontColor(#182431).width(100%).margin({bottom:12})Flex({justifyContent:FlexAlign.SpaceBetween}){ForEach(this.countOptions,(count:number){Button(${count}个).width(48).height(48).fontSize(15).fontColor(this.diceCountcount?Color.White:#4B5563).backgroundColor(this.diceCountcount?#0A59F7:#F3F4F6).borderRadius(24).onClick((){this.setDiceCount(count)})},(c:number)c.toString())}.width(100%)}.width(100%).padding(16).backgroundColor(Color.White).borderRadius(16).margin({bottom:16}).shadow({radius:8,color:#08000000,offsetX:0,offsetY:2})if(this.history.length0){Column(){Text(投掷历史).fontSize(16).fontWeight(FontWeight.Medium).fontColor(#182431).width(100%).margin({bottom:8})ForEach(this.history,(item:{values:number[],total:number},index:number){this.HistoryItem(item,index)},(item:{values:number[],total:number},i:number)i.toString())}.width(100%).padding(16).backgroundColor(Color.White).borderRadius(16).shadow({radius:8,color:#08000000,offsetX:0,offsetY:2})}}.width(100%).height(100%).padding({left:18,right:18}).backgroundColor(#F5F7FA)}}八、代码实现说明1. 骰子点数绘制用标准骰子圆点布局1点中间一个点2点左上和右下3点左上、中间、右下4点四个角5点四个角加中间6点左右各三个点2. 投掷动画使用animateTo实现360度旋转动画同时用setInterval快速切换点数制造滚动效果动画结束后确定最终点数。3. 随机数生成每个骰子独立生成1-6的随机数模拟真实骰子的均匀分布。4. 数量选择支持1-6个骰子选择后重置所有骰子为1点。5. 总和计算使用reduce计算所有骰子点数之和大字体蓝色显示。6. 历史记录每次投掷结果保存到历史显示点数组合和总和最多保存20条。九、运行项目代码编写完成后在DevEco Studio中运行项目。选择不同骰子数量点击投掷按钮观察骰子旋转动画检查点数是否正确总和计算是否准确历史记录是否正常。十、开发中遇到的问题动画流畅度用快速切换点数旋转动画模拟真实掷骰子效果骰子布局正确绘制1-6点的标准圆点位置防重复点击动画进行中禁止再次点击响应式布局多个骰子时自动换行适配不同数量十一、总结本文基于HarmonyOS和ArkTS实现了一个掷骰子模拟器。项目通过自定义骰子组件和动画效果实现有趣的投掷体验支持多骰子、点数统计和历史记录。这个项目展示了ArkTS中组件封装、动画效果和随机数处理的基本方法适合作为入门练习项目。