【鸿蒙实战】20分钟手把手教你开发骰子模拟器 【鸿蒙实战】20分钟手把手教你开发骰子模拟器保姆级教程从零开始带你用 HarmonyOS NEXT 和 ArkTS 实现一个功能完整的骰子模拟器应用。一、项目预览先看看我们要做什么 点击投掷骰子显示 1-6 点⚡ 流畅的翻滚动画效果 5 种主题配色可选 自动记录投掷历史 支持点击骰子或按钮两种操作二、准备工作2.1 环境要求工具版本DevEco Studio5.0HarmonyOS SDKAPI 23Node.js14.19.12.2 创建项目步骤 1打开 DevEco Studio点击File → New → Create Project步骤 2选择Empty Ability模板步骤 3填写项目信息Bundle name:com.example.myapplicationSave location:D:\harmonyos\project\project11\MyApplication步骤 4点击 Finish等待项目初始化2.3 项目结构MyApplication/ ├── entry/ │ └── src/main/ │ ├── ets/ │ │ ├── entryability/ │ │ │ └── EntryAbility.ets │ │ └── pages/ │ │ └── Index.ets ⭐ 主页面 │ └── resources/ └── build-profile.json5我们主要编辑Index.ets文件。三、代码实现3.1 定义数据模型步骤 1打开Index.ets定义两个接口// 投掷记录interfaceDiceRecord{value:number;// 点数1-6time:string;// 时间HH:MM:SS}// 主题配置interfaceDiceTheme{name:string;// 主题名称bg:string;// 背景色dot:string;// 点数色border:string;// 边框色}3.2 创建组件和状态步骤 2定义组件和状态变量EntryComponentstruct Index{// 状态变量 StatecurrentValue:number1;// 当前点数StateisRolling:booleanfalse;// 是否在滚动StatetotalRolls:number0;// 总投掷次数Statehistory:DiceRecord[][];// 历史记录StatediceColor:string#FFFFFF;// 骰子背景色StatedotColor:string#1C1C1E;// 点数颜色// 主题数据 readonlydiceColors:DiceTheme[][{name:经典白,bg:#FFFFFF,dot:#1C1C1E,border:#D1D1D6},{name:复古红,bg:#FF3B30,dot:#FFFFFF,border:#C41A1A},{name:深邃蓝,bg:#007AFF,dot:#FFFFFF,border:#0040DD},{name:翡翠绿,bg:#34C759,dot:#FFFFFF,border:#248A3D},{name:暗夜黑,bg:#1C1C1E,dot:#FFFFFF,border:#000000},];}说明State状态变量变化时 UI 自动更新readonly常量数组不需要响应式3.3 实现投掷逻辑步骤 3添加投掷方法rollDice():void{// 1. 防止重复触发if(this.isRolling)return;this.isRollingtrue;// 2. 快速切换数字产生动画letframe0;constintervalsetInterval((){this.currentValueMath.floor(Math.random()*6)1;frame;// 3. 8 帧后停止if(frame8){clearInterval(interval);constfinalValueMath.floor(Math.random()*6)1;this.currentValuefinalValue;this.isRollingfalse;this.totalRolls;// 4. 记录历史this.addToHistory(finalValue);}},60);}步骤 4添加记录历史的方法addToHistory(value:number):void{constnownewDate();consttimeStr${now.getHours().toString().padStart(2,0)}:${now.getMinutes().toString().padStart(2,0)}:${now.getSeconds().toString().padStart(2,0)};constnewRecord:DiceRecord{value:value,time:timeStr};// 插入到数组开头consttemp[newRecord];for(leti0;ithis.history.length;i){temp.push(this.history[i]);}this.historytemp;// 限制 10 条if(this.history.length10){consttemp2[];for(leti0;i10;i){temp2.push(this.history[i]);}this.historytemp2;}}3.4 绘制骰子点数步骤 5使用Builder定义可复用的 UIBuilderbuildDiceFace(){Column(){if(this.currentValue1){Text(●).fontSize(48).fontColor(this.dotColor)}elseif(this.currentValue2){Row(){Column(){Text(●).fontSize(24).fontColor(this.dotColor)}.width(50%)Column(){Text(●).fontSize(24).fontColor(this.dotColor)}.width(50%)}.width(120).justifyContent(FlexAlign.SpaceAround)}elseif(this.currentValue3){Row(){Column(){Text(●).fontSize(20).fontColor(this.dotColor)}.width(33%)Column(){Text(●).fontSize(24).fontColor(this.dotColor)}.width(33%)Column(){Text(●).fontSize(20).fontColor(this.dotColor)}.width(33%)}.width(140).justifyContent(FlexAlign.SpaceAround)}elseif(this.currentValue4){Column({space:12}){Row({space:24}){Text(●).fontSize(24).fontColor(this.dotColor)Text(●).fontSize(24).fontColor(this.dotColor)}Row({space:24}){Text(●).fontSize(24).fontColor(this.dotColor)Text(●).fontSize(24).fontColor(this.dotColor)}}}elseif(this.currentValue5){Column({space:10}){Row({space:18}){Text(●).fontSize(20).fontColor(this.dotColor)Text(●).fontSize(20).fontColor(this.dotColor)Text(●).fontSize(20).fontColor(this.dotColor)}Row({space:18}){Text().fontSize(20)Text(●).fontSize(24).fontColor(this.dotColor)Text().fontSize(20)}Row({space:18}){Text(●).fontSize(20).fontColor(this.dotColor)Text(●).fontSize(20).fontColor(this.dotColor)Text(●).fontSize(20).fontColor(this.dotColor)}}}else{Column({space:8}){Row({space:14}){Text(●).fontSize(20).fontColor(this.dotColor)Text(●).fontSize(20).fontColor(this.dotColor)Text(●).fontSize(20).fontColor(this.dotColor)}Row({space:14}){Text(●).fontSize(20).fontColor(this.dotColor)Text(●).fontSize(20).fontColor(this.dotColor)Text(●).fontSize(20).fontColor(this.dotColor)}Row({space:14}){Text(●).fontSize(20).fontColor(this.dotColor)Text(●).fontSize(20).fontColor(this.dotColor)Text(●).fontSize(20).fontColor(this.dotColor)}}}}.width(160).height(160).justifyContent(FlexAlign.Center)}3.5 构建界面步骤 6在build()方法中组装 UIbuild(){Column(){// 标题Text( 骰子模拟器).fontSize(26).fontWeight(FontWeight.Bold).margin({top:30,bottom:4})Text(已投掷${this.totalRolls}次).fontSize(14).fontColor(#8E8E93).margin({bottom:20})// 骰子Column(){this.buildDiceFace()}.width(180).height(180).backgroundColor(this.diceColor).borderRadius(24).border({width:3,color:#D1D1D6}).shadow({radius:12,color:#20000000,offsetY:4}).opacity(this.isRolling?0.7:1.0).onClick((){this.rollDice();})// 按钮Button(this.isRolling? 投掷中...: 掷骰子).type(ButtonType.Capsule).width(200).height(50).backgroundColor(#007AFF).margin({top:24}).enabled(!this.isRolling).onClick((){this.rollDice();})// 主题Text(选择主题).fontSize(14).fontColor(#8E8E93).margin({top:20,bottom:8})Row({space:10}){ForEach(this.diceColors,(theme:DiceTheme){Row(){Text(theme.name).fontSize(11).fontColor(theme.bg#1C1C1E?#FFFFFF:#1C1C1E)}.width(60).height(28).backgroundColor(theme.bg).borderRadius(14).border({width:this.diceColortheme.bg?2:1,color:this.diceColortheme.bg?#007AFF:theme.border}).justifyContent(FlexAlign.Center).onClick((){this.diceColortheme.bg;this.dotColortheme.dot;})})}// 历史if(this.history.length0){Row(){Text( 投掷记录).fontSize(16).fontWeight(FontWeight.Bold)Blank()Text(清空).fontSize(13).fontColor(#FF3B30).onClick((){this.history[];this.totalRolls0;})}.width(100%).margin({top:20,bottom:8})Column({space:4}){ForEach(this.history,(record:DiceRecord){Row(){Text(${record.value}).fontSize(18).fontWeight(FontWeight.Bold)Blank()Text(record.time).fontSize(12).fontColor(#8E8E93)}.width(100%).padding(10).backgroundColor(#F2F2F7).borderRadius(10)})}.width(100%)}}.width(100%).height(100%).backgroundColor(#FFFFFF).padding(20)}四、运行测试五、功能演示5.1 投掷骰子点击骰子或按钮骰子快速翻滚 8 次后停下。5.2 切换主题点击主题按钮骰子颜色立即切换。主题颜色经典白白底黑点复古红红底白点深邃蓝蓝底白点翡翠绿绿底白点暗夜黑黑底白点5.3 查看历史自动记录最近 10 次投掷显示点数和时间。六、常见问题Q1: 点击没反应A:检查isRolling状态确保动画结束后才能再次点击。Q2: 历史记录不显示A:检查history.length 0条件确保有数据。Q3: 主题切换不生效A:检查diceColor和dotColor是否都更新了。Q4: 如何修改动画速度A:调整setInterval的间隔时间更快改小间隔如 40ms更慢改大间隔如 100msQ5: 如何添加更多主题A:在diceColors数组中添加{name:紫罗兰,bg:#AF52DE,dot:#FFFFFF,border:#8B3AA8}七、项目总结核心知识点知识点说明State状态管理BuilderUI 复用setInterval动画实现ForEach列表渲染if条件渲染项目信息SDKAPI 23开发工具DevEco Studio 5.0