当前位置: 首页 > news >正文

【鸿蒙实战】20分钟手把手教你开发骰子模拟器

【鸿蒙实战】20分钟手把手教你开发骰子模拟器

保姆级教程!从零开始,带你用 HarmonyOS NEXT 和 ArkTS 实现一个功能完整的骰子模拟器应用。

一、项目预览

先看看我们要做什么:

  • 🎲 点击投掷骰子,显示 1-6 点
  • ⚡ 流畅的翻滚动画效果
  • 🎨 5 种主题配色可选
  • 📊 自动记录投掷历史
  • 💡 支持点击骰子或按钮两种操作

二、准备工作

2.1 环境要求

工具版本
DevEco Studio5.0+
HarmonyOS SDKAPI 23+
Node.js14.19.1+

2.2 创建项目

步骤 1:打开 DevEco Studio,点击File → New → Create Project

步骤 2:选择Empty Ability模板

步骤 3:填写项目信息:

  • Bundle name:com.example.myapplication
  • Save 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:定义组件和状态变量:

@Entry@Componentstruct Index{// ========== 状态变量 ==========@StatecurrentValue:number=1;// 当前点数@StateisRolling:boolean=false;// 是否在滚动@StatetotalRolls:number=0;// 总投掷次数@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.isRolling=true;// 2. 快速切换数字产生动画letframe=0;constinterval=setInterval(()=>{this.currentValue=Math.floor(Math.random()*6)+1;frame++;// 3. 8 帧后停止if(frame>=8){clearInterval(interval);constfinalValue=Math.floor(Math.random()*6)+1;this.currentValue=finalValue;this.isRolling=false;this.totalRolls++;// 4. 记录历史this.addToHistory(finalValue);}},60);}

步骤 4:添加记录历史的方法:

addToHistory(value:number):void{constnow=newDate();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(leti=0;i<this.history.length;i++){temp.push(this.history[i]);}this.history=temp;// 限制 10 条if(this.history.length>10){consttemp2=[];for(leti=0;i<10;i++){temp2.push(this.history[i]);}this.history=temp2;}}

3.4 绘制骰子点数

步骤 5:使用@Builder定义可复用的 UI:

@BuilderbuildDiceFace(){Column(){if(this.currentValue===1){Text('●').fontSize(48).fontColor(this.dotColor)}elseif(this.currentValue===2){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.currentValue===3){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.currentValue===4){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.currentValue===5){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()方法中组装 UI:

build(){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.diceColor===theme.bg?2:1,color:this.diceColor===theme.bg?'#007AFF':theme.border}).justifyContent(FlexAlign.Center).onClick(()=>{this.diceColor=theme.bg;this.dotColor=theme.dot;})})}// 历史if(this.history.length>0){Row(){Text('📋 投掷记录').fontSize(16).fontWeight(FontWeight.Bold)Blank()Text('清空').fontSize(13).fontColor('#FF3B30').onClick(()=>{this.history=[];this.totalRolls=0;})}.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:检查diceColordotColor是否都更新了。

Q4: 如何修改动画速度?

A:调整setInterval的间隔时间:

  • 更快:改小间隔(如 40ms)
  • 更慢:改大间隔(如 100ms)

Q5: 如何添加更多主题?

A:diceColors数组中添加:

{name:'紫罗兰',bg:'#AF52DE',dot:'#FFFFFF',border:'#8B3AA8'}

七、项目总结

核心知识点

知识点说明
@State状态管理
@BuilderUI 复用
setInterval动画实现
ForEach列表渲染
if条件渲染

项目信息:

  • SDK:API 23
  • 开发工具:DevEco Studio 5.0+

http://www.zskr.cn/news/1447077.html

相关文章:

  • 如何结合多种方法记忆高中英语单词
  • AgentRAG与ReAct推理链:从检索增强到推理增强
  • 2026年6月更新:温州法兰品牌业内推荐与采购指南 - 博客万
  • 服务网格(Service mesh istio)
  • 如何通过动环监控系统提升机房管理效率与安全性?
  • 企业AI建站工具选型指南:如何避开陷阱,找到最适合你的那一款
  • 2026年工业铝型材定制靠谱厂家推荐 工业铝型材+自动化设备定制厂家TOP5排行榜+联系方式 - 海棠依旧大
  • 千米快修服务全解析:手机电脑维修、配件销售及企业IT外包一站式服务指南 - 品牌推荐官
  • 不写代码也能让AI跨系统查数据?企业本体语义模型实战
  • 鸣潮自动化助手终极指南:5步实现智能挂机,解放双手轻松游戏
  • B2B 全球化模式深耕 华曦达绑定 300 + 运营商构建高壁垒渠道生态
  • Halcon实战:手把手教你用Variation Model搞定印刷品瑕疵检测(附完整代码)
  • 从零设计智能水泵控制器:PCB实战与JLCPCB打样全解析
  • 化学多维校正基础理论及其在复杂体系中的定量应用方案【附仿真】
  • 移动应用开发中Android和iOS性能优化关键策略对比分析
  • 引客云·可信增长决策智能体部署方案
  • Sora 2复原误差预警系统上线(附23处世界遗产验证报告):当PSNR<28.5dB时,自动触发多源考古证据交叉校验
  • 选豆包AI推广:借助原生生态挖掘精准客源的实战路径 - 品牌2026
  • 刺绣臂章选型全解析:从工艺到供应商的客观指南 - 奔跑123
  • 手机号定位查询:3秒快速定位归属地,告别陌生来电的困惑
  • RFID/条码读取器键盘模拟信号路由:从软件拦截到硬件改造的完整方案
  • :广州名包回收避坑攻略!2026正规渠道测评,高价不亏价 - 薛定谔的梨花猫
  • 基于ESP-NOW与WS2812B的无线智能RGB灯DIY全解析
  • 2026年桑拿设备厂家推荐:苏州子轩桑拿设备全系产品适配多场景需求 - 品牌推荐官
  • 从统计机器翻译到AI猜字谜:NLP技术如何赋能传统文化计算
  • MiniMax M3横空出世,MonkeyCode让你的AI编程提效10倍
  • 2026年6月广东不锈钢品牌加盟—TOP5排名榜单推荐 - 界川
  • 2026年智慧消防系统推荐:力安科技消防控制系统与远程值守解决方案 - 品牌推荐官
  • STM8L101驱动SX1268 LoRa模块的实测工程包(含可调参数驱动、原理图与配置速查)
  • 2026吉林长春延边MCN机构排行:头部实力梯队盘点 - 奔跑123