ETS版的数字华容道

想了解更多内容,字华请访问:
和华为官方合作共建的容道鸿蒙技术社区
https://harmonyos.51cto.com
前言
相信大家伙都对新玩意ets挺好奇的,我也不例外。字华前几天我们木棉花小组一同用ETS写了数字华容道的容道格子布局,然后我就用日常的字华空余时间简单完善了一下这个demo啦,但是容道我对ets没有很懂,欢迎各位评论区指导一下哈O(∩_∩)O
概述
这是字华文件架构

效果图如下



正文
1. 新建一个空白工程
DevEco Studio下载安装成功后,打开DevEco Studio,容道点击左上角的字华File,点击New,容道再选择New Project,字华选择Empty Ability,容道然后点击Next,给项目命名ETS,选择设备类型Phone,字华选择语言类型ets最后点击Finish

2. 主页面设置
导入router模块以实现页面跳转,容道在Flex容器组件下添加Text组件,字华Button组件,点击Button可跳转至页面(uri的服务器托管地址),最后设置容器整体的宽高
import router from @system.router; @Entry @Component struct Index { build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Text(数字华容道) .fontSize(40) .margin({top:20,bottom:20}) Button(4x4) .fontSize(30) .margin({top:20,bottom:20}) .width(280) .height(60) .onClick(() => { router.push({ uri: pages/forth }) }) Button(5x5) .fontSize(30) .margin({top:20,bottom:20}) .width(280) .height(60) .onClick(() => { router.push({ uri: pages/fifth }) }) } .width(100%) .height(100%) } }3. 4x4游戏页面的设置
右击pages>>New>>eTS Page,新建一个页面,命名‘forth’,删除组件Text.然后在最下方自定义组件setText和setTime,前者是游戏格子一行的布局,后者是显示时间的组件;export是为了将自定义组件导入第二个页面‘5x5’而加的
@Component export struct setText{ @Link t:number[] build(){ Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { ForEach(this.t,(item:number)=>Text(item==0 ? :item.toString()) .fontSize(50) .fontWeight(FontWeight.Bold) .backgroundColor(#678912) .fontColor(#FFFFFF) .width(60) .height(60) .margin({ left: 5, right: 5, top: 5, bottom: 5 }) .textAlign(TextAlign.Center), item =>item.toString()) }} } @Component export struct setTime{ @Link h:string @Link m:string @Link s:string @Link ms:string build(){ Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Text(this.h+:+this.m+:+this.s+:+this.ms).fontSize(40).textAlign(TextAlign.Center).margin({top:10,bottom:10}) } } }定义变量
var row_0=3 var column_0=3 var timer=null var stop=true import router from @system.router; @Entry @Component struct Forth { @State grids:number[][]=[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,0]] @State grids1:number[]=[this.grids[0][0],this.grids[0][1],this.grids[0][2],this.grids[0][3]] @State grids2:number[]=[this.grids[1][0],this.grids[1][1],this.grids[1][2],this.grids[1][3]] @State grids3:number[]=[this.grids[2][0],this.grids[2][1],this.grids[2][2],this.grids[2][3]] @State grids4:number[]=[this.grids[3][0],this.grids[3][1],this.grids[3][2],this.grids[3][3]] @State strhour:string=0 @State strmin:string=0 @State strsec:string=0 @State strmsec:string=0 @State hour:number = 0; @State min:number = 0; @State sec:number = 0; @State msec:number = 0;定义变量后,在Forth的build()里增加组件完成格子布局和计时器布局,组件竖直排列
Column(){ setTime({h:$strhour,m:$strmin,s:$strsec,ms:$strmsec}) setText({t:$grids1}) setText({t:$grids2}) setText({t:$grids3}) setText({t:$grids4}) }在build上方定义函数change,通过方向值来判断实现数字的移动
change(direction){ if(direction==down) { if(row_0>0 && row_0<4){ let temp = this.grids[row_0-1][column_0] this.grids[row_0-1][column_0] = 0 this.grids[row_0][column_0] = temp row_0--} }然后在build里添加4个按钮组件,分别是“上、下、左、源码下载右”,其中左跟右同一水平放置
Button(上) .width(60) .height(60) .fontSize(30) .margin({ left: 5, right: 5, top: 3, bottom: 5 }) .align(Alignment.Center) .backgroundColor(#974B31) .fontColor(#FFFFFF) .onClick((event: ClickEvent) => { this.change(up) this.grids1 = [this.grids[0][0], this.grids[0][1], this.grids[0][2], this.grids[0][3]] this.grids2 = [this.grids[1][0], this.grids[1][1], this.grids[1][2], this.grids[1][3]] this.grids3 = [this.grids[2][0], this.grids[2][1], this.grids[2][2], this.grids[2][3]] this.grids4 = [this.grids[3][0], this.grids[3][1], this.grids[3][2], this.grids[3][3]] }) Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Button(左) .width(60) .height(60) .fontSize(30) .margin({ left: 5, right: 5, top: 3, bottom: 5 }) .align(Alignment.Center) .backgroundColor(#974B31) .fontColor(#FFFFFF) .onClick((event: ClickEvent) => { this.change(left) this.grids1 = [this.grids[0][0], this.grids[0][1], this.grids[0][2], this.grids[0][3]] this.grids2 = [this.grids[1][0], this.grids[1][1], this.grids[1][2], this.grids[1][3]] this.grids3 = [this.grids[2][0], this.grids[2][1], this.grids[2][2], this.grids[2][3]] this.grids4 = [this.grids[3][0], this.grids[3][1], this.grids[3][2], this.grids[3][3]] }) Button(右) .width(60) .height(60) .fontSize(30) .margin({ left: 5, right: 5, top: 3, bottom: 5 }) .align(Alignment.Center) .backgroundColor(#974B31) .fontColor(#FFFFFF) .onClick((event: ClickEvent) => { this.change(right) this.grids1 = [this.grids[0][0], this.grids[0][1], this.grids[0][2], this.grids[0][3]] this.grids2 = [this.grids[1][0], this.grids[1][1], this.grids[1][2], this.grids[1][3]] this.grids3 = [this.grids[2][0], this.grids[2][1], this.grids[2][2], this.grids[2][3]] this.grids4 = [this.grids[3][0], this.grids[3][1], this.grids[3][2], this.grids[3][3]] }) } Button(下) .width(60) .height(60) .fontSize(30) .margin({ left: 5, right: 5, top: 3, bottom: 5 }) .align(Alignment.Center) .backgroundColor(#974B31) .fontColor(#FFFFFF) .onClick((event: ClickEvent) => { this.change(down) this.grids1 = [this.grids[0][0], this.grids[0][1], this.grids[0][2], this.grids[0][3]] this.grids2 = [this.grids[1][0], this.grids[1][1], this.grids[1][2], this.grids[1][3]] this.grids3 = [this.grids[2][0], this.grids[2][1], this.grids[2][2], this.grids[2][3]] this.grids4 = [this.grids[3][0], this.grids[3][1], this.grids[3][2], this.grids[3][3]] })实现数字的随机打乱和计时器的流动
为了使时间显示得好看点,若时间为个位数时十位补0,然后设置函数run_time用以定时器内循环
onPageShow(){ this.settime(this.msec,this.sec,this.min,this.hour) } ttime(msec,sec,min,hour){ if (msec < 10) { this.strmsec = "0" + msec.toString(); } else if (msec >= 10) { this.strmsec =msec.toString(); } if (sec < 10){ this.strsec = "0" + sec.toString(); } else if (sec >= 10) { this.strsec =sec.toString(); } if (min < 10){ this.strmin = "0" + min.toString(); } else if (min >= 10) { this.strmin = min.toString(); } if (hour < 10){ this.strhour = "0" + hour.toString(); } else if (hour >= 10) { this.strhour = hour.toString(); } } run_time(){ this.msec+=1 if(this.msec==100){ this.msec=0 this.sec+=1 } if(this.sec==60){ this.sec=0 this.min+=1 } if(this.min==60){ this.min=0 this.hour+=1 } this.settime(this.msec,this.sec,this.min,this.hour) }随机打乱数字,重新开始时清空上一个定时器,并时间重置为0
init(){ let array=["left","up","right","down"]; for (let i = 0; i < 100; i++){ let randomIndex = Math.floor(Math.random() * 4); let direction = array[randomIndex]; this.change(direction) this.grids1 = [this.grids[0][0], this.grids[0][1], this.grids[0][2], this.grids[0][3]] this.grids2 = [this.grids[1][0], this.grids[1][1], this.grids[1][2], this.grids[1][3]] this.grids3 = [this.grids[2][0], this.grids[2][1], this.grids[2][2], this.grids[2][3]] this.grids4 = [this.grids[3][0], this.grids[3][1], this.grids[3][2], this.grids[3][3]] this.msec=0 this.hour=0 this.sec=0 this.min=0 clearInterval(timer) timer=null } }在“上”按钮组件上方添加以下代码
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Button(开始游戏) .width(160) .height(60) .fontSize(30) .margin({ left: 3, right: 3, top: 3, bottom: 5 }) .align(Alignment.Center) .backgroundColor(#974B31) .fontColor(#FFFFFF) .onClick((event: ClickEvent) => { this.init() timer = setInterval(() => this.run_time(), 10) }) Button(返回) .width(88) .height(60) .fontSize(27) .margin({ left: 3, right: 3, top: 3, bottom: 5 }) .align(Alignment.Center) .backgroundColor(#974B31) .fontColor(#FFFFFF) .onClick(() => { router.push({ uri: pages/index }) }) Button(暂停) .width(88) .height(60) .fontSize(27) .margin({ left: 3, right: 3, top: 3, bottom: 5 }) .align(Alignment.Center) .backgroundColor(#974B31) .fontColor(#FFFFFF) .onClick(() => { if(stop==true){ clearInterval(timer) timer=null stop=false } else if(stop==false){ stop=true timer = setInterval(() => this.run_time(), 10) } }) }设置游戏结束函数gameover,当游戏成功时清空定时器,且方向按钮无点击事件
gameover() { for (let column = 0; column < column_0; column++) { if (this.grids1[column] != this.grids[0][column]){ return false } if(this.grids2[column]!=this.grids[1][column]){ return false } if(this.grids3[column]!=this.grids[2][column]){ return false } if(this.grids4[column]!=this.grids[3][column]){ return false } } return true }在四个方向按钮的点击事件中加入游戏是否成功的判断
.onClick((event: ClickEvent) => { if(!this.gameover()) { this.change(up) this.grids1 = [this.grids[0][0], this.grids[0][1], this.grids[0][2], this.grids[0][3]] this.grids2 = [this.grids[1][0], this.grids[1][1], this.grids[1][2], this.grids[1][3]] this.grids3 = [this.grids[2][0], this.grids[2][1], this.grids[2][2], this.grids[2][3]] this.grids4 = [this.grids[3][0], this.grids[3][1], this.grids[3][2], this.grids[3][3]] } if(this.gameover()){ clearInterval(timer) timer=null }4. 5x5的页面设置
套路跟4x4一样,新建一个页面,然后导入4x4页面自定义的两个组件,改一下数组数据,这里直接上代码
var row_0=4 var column_0=4 var timer=null; var stop=true import router from @system.router; import {setText,setTime} from ./forth.ets @Entry @Component struct Fifth { @State grids:number[][]=[[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20],[21,22,23,24,0]] @State grids1:number[]=[this.grids[0][0],this.grids[0][1],this.grids[0][2],this.grids[0][3],this.grids[0][4]] @State grids2:number[]=[this.grids[1][0],this.grids[1][1],this.grids[1][2],this.grids[1][3],this.grids[1][4]] @State grids3:number[]=[this.grids[2][0],this.grids[2][1],this.grids[2][2],this.grids[2][3],this.grids[2][4]] @State grids4:number[]=[this.grids[3][0],this.grids[3][1],this.grids[3][2],this.grids[3][3],this.grids[3][4]] @State grids5:number[]=[this.grids[4][0],this.grids[4][1],this.grids[4][2],this.grids[4][3],this.grids[4][4]] @State strhour:string=0 @State strmin:string=0 @State strsec:string=0 @State strmsec:string=0 @State hour:number = 0; @State min:number = 0; @State sec:number = 0; @State msec:number = 0; onPageShow(){ this.settime(this.msec,this.sec,this.min,this.hour) } gameover() { for (let column = 0; column < column_0; column++) { if (this.grids1[column] != this.grids[0][column]){ return false } if(this.grids2[column]!=this.grids[1][column]){ return false } if(this.grids3[column]!=this.grids[2][column]){ return false } if(this.grids4[column]!=this.grids[3][column]){ return false } } return true } init(){ let array=["left","up","right","down"]; for (let i = 0; i < 100; i++){ let randomIndex = Math.floor(Math.random() * 5); let direction = array[randomIndex]; this.change(direction) this.grids1=[this.grids[0][0],this.grids[0][1],this.grids[0][2],this.grids[0][3],this.grids[0][4]] this.grids2=[this.grids[1][0],this.grids[1][1],this.grids[1][2],this.grids[1][3],this.grids[1][4]] this.grids3=[this.grids[2][0],this.grids[2][1],this.grids[2][2],this.grids[2][3],this.grids[2][4]] this.grids4=[this.grids[3][0],this.grids[3][1],this.grids[3][2],this.grids[3][3],this.grids[3][4]] this.grids5=[this.grids[4][0],this.grids[4][1],this.grids[4][2],this.grids[4][3],this.grids[4][4]] this.msec=0 this.hour=0 this.sec=0 this.min=0 clearInterval(timer) timer=null } } change(direction){ if(direction==down) { if(row_0>0 && row_0<5){ let temp = this.grids[row_0-1][column_0] this.grids[row_0-1][column_0] = 0 this.grids[row_0][column_0] = temp row_0--} } if(direction==up){ if(row_0>-1 && row_0<4){ let temp = this.grids[row_0+1][column_0] this.grids[row_0+1][column_0] = 0 this.grids[row_0][column_0]=temp row_0++} } if(direction==right){ if(column_0>0 && column_0<5){ let temp = this.grids[row_0][column_0-1] this.grids[row_0][column_0-1] = 0 this.grids[row_0][column_0]=temp column_0--} } if(direction==left){ if(column_0>-1 && column_0<4){ let temp = this.grids[row_0][column_0+1] this.grids[row_0][column_0+1] = 0 this.grids[row_0][column_0]=temp column_0++} } } settime(msec,sec,min,hour){ if (msec < 10) { this.strmsec = "0" + msec.toString(); } else if (msec >= 10) { this.strmsec =msec.toString(); } if (sec < 10){ this.strsec = "0" + sec.toString(); } else if (sec >= 10) { this.strsec =sec.toString(); } if (min < 10){ this.strmin = "0" + min.toString(); } else if (min >= 10) { this.strmin = min.toString(); } if (hour < 10){ this.strhour = "0" + hour.toString(); } else if (hour >= 10) { this.strhour = hour.toString(); } } run_time(){ this.msec+=1 if(this.msec==100){ this.msec=0 this.sec+=1 } if(this.sec==60){ this.sec=0 this.min+=1 } if(this.min==60){ this.min=0 this.hour+=1 } this.settime(this.msec,this.sec,this.min,this.hour) } build() { Column(){ setTime({h:$strhour,m:$strmin,s:$strsec,ms:$strmsec}) setText({t:$grids1}) setText({t:$grids2}) setText({t:$grids3}) setText({t:$grids4}) setText({t:$grids5}) Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Button(开始游戏) .width(150) .height(50) .fontSize(28) .margin({ left: 5, right: 5, top: 3, bottom: 5 }) .align(Alignment.Center) .backgroundColor(#974B31) .fontColor(#FFFFFF) .onClick((event: ClickEvent) => { this.init() timer = setInterval(() => this.run_time(),10) }) Button(返回) .width(90) .height(50) .fontSize(28) .margin({ left: 5, right: 5, top: 3, bottom: 5 }) .align(Alignment.Center) .backgroundColor(#974B31) .fontColor(#FFFFFF) .onClick(() => { router.push({ uri: pages/index }) }) Button(暂停) .width(88) .height(60) .fontSize(27) .margin({ left: 3, right: 3, top: 3, bottom: 5 }) .align(Alignment.Center) .backgroundColor(#974B31) .fontColor(#FFFFFF) .onClick(() => { if(stop==true){ clearInterval(timer) timer=null stop=false } else if(stop==false){ stop=true timer = setInterval(() => this.run_time(), 10) } }) } Button(上) .width(60) .height(48) .fontSize(28) .margin({ left: 5, right: 5, top: 3, bottom: 5 }) .align(Alignment.Center) .backgroundColor(#974B31) .fontColor(#FFFFFF) .onClick((event: ClickEvent) => { if(!this.gameover()) { this.change(up) this.grids1=[this.grids[0][0],this.grids[0][1],this.grids[0][2],this.grids[0][3],this.grids[0][4]] this.grids2=[this.grids[1][0],this.grids[1][1],this.grids[1][2],this.grids[1][3],this.grids[1][4]] this.grids3=[this.grids[2][0],this.grids[2][1],this.grids[2][2],this.grids[2][3],this.grids[2][4]] this.grids4=[this.grids[3][0],this.grids[3][1],this.grids[3][2],this.grids[3][3],this.grids[3][4]] this.grids5=[this.grids[4][0],this.grids[4][1],this.grids[4][2],this.grids[4][3],this.grids[4][4]] } if(this.gameover()){ clearInterval(timer) timer=null } }) Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Button(左) .width(60) .height(48) .fontSize(28) .margin({ left: 20, right: 20}) .align(Alignment.Center) .backgroundColor(#974B31) .fontColor(#FFFFFF) .onClick((event: ClickEvent) => { if(!this.gameover()) { this.change(left) this.grids1=[this.grids[0][0],this.grids[0][1],this.grids[0][2],this.grids[0][3],this.grids[0][4]] this.grids2=[this.grids[1][0],this.grids[1][1],this.grids[1][2],this.grids[1][3],this.grids[1][4]] this.grids3=[this.grids[2][0],this.grids[2][1],this.grids[2][2],this.grids[2][3],this.grids[2][4]] this.grids4=[this.grids[3][0],this.grids[3][1],this.grids[3][2],this.grids[3][3],this.grids[3][4]] this.grids5=[this.grids[4][0],this.grids[4][1],this.grids[4][2],this.grids[4][3],this.grids[4][4]] } if(this.gameover()){ clearInterval(timer) timer=null } }) Button(右) .width(60) .height(48) .fontSize(28) .margin({ left: 20, right: 20}) .align(Alignment.Center) .backgroundColor(#974B31) .fontColor(#FFFFFF) .onClick((event: ClickEvent) => { if(!this.gameover()) { this.change(right) this.grids1=[this.grids[0][0],this.grids[0][1],this.grids[0][2],this.grids[0][3],this.grids[0][4]] this.grids2=[this.grids[1][0],this.grids[1][1],this.grids[1][2],this.grids[1][3],this.grids[1][4]] this.grids3=[this.grids[2][0],this.grids[2][1],this.grids[2][2],this.grids[2][3],this.grids[2][4]] this.grids4=[this.grids[3][0],this.grids[3][1],this.grids[3][2],this.grids[3][3],this.grids[3][4]] this.grids5=[this.grids[4][0],this.grids[4][1],this.grids[4][2],this.grids[4][3],this.grids[4][4]] } if(this.gameover()){ clearInterval(timer) timer=null } }) } Button(下) .width(60) .height(48) .fontSize(28) .margin({ left: 5, right: 5, top: 3, bottom: 5 }) .align(Alignment.Center) .backgroundColor(#974B31) .fontColor(#FFFFFF) .onClick((event: ClickEvent) => { if(!this.gameover()) { this.change(down) this.grids1=[this.grids[0][0],this.grids[0][1],this.grids[0][2],this.grids[0][3],this.grids[0][4]] this.grids2=[this.grids[1][0],this.grids[1][1],this.grids[1][2],this.grids[1][3],this.grids[1][4]] this.grids3=[this.grids[2][0],this.grids[2][1],this.grids[2][2],this.grids[2][3],this.grids[2][4]] this.grids4=[this.grids[3][0],this.grids[3][1],this.grids[3][2],this.grids[3][3],this.grids[3][4]] this.grids5=[this.grids[4][0],this.grids[4][1],this.grids[4][2],this.grids[4][3],this.grids[4][4]] } if(this.gameover()){ clearInterval(timer) timer=null } }) }.width(100%).height(100%) } }结语
以上就是我这次的小分享啦❀❀!
文章相关附件可以点击下面的原文链接前往下载
https://harmonyos.51cto.com/resource/1428
想了解更多内容,请访问:
和华为官方合作共建的站群服务器鸿蒙技术社区
https://harmonyos.51cto.com

相关文章
腾讯会议电脑使用技巧教程(掌握腾讯会议,提升工作效率的关键技巧)
摘要:随着远程办公的普及,腾讯会议成为了许多企业和个人办公中不可或缺的工具。然而,很多人对于如何在电脑上高效地使用腾讯会议还不够熟悉。本文将为大家分享一些腾讯会议电脑使用的技巧,帮助您更...2025-11-04探索性能卓越的G4560处理器——高性价比选择(以7代G4560为基础,解析其卓越性能与经济实惠)
摘要:在当今科技迅猛发展的时代,人们对于电脑性能和价格的需求变得越来越高,而7代G4560处理器作为一款高性价比的选择,引起了广泛的关注。本文将深入探索G4560处理器的性能特点,逐个揭...2025-11-04盛通印刷商印快线(印刷业新进展,盛通印刷商印快线一站式服务助您高效印刷)
摘要:随着科技的发展和全球化的进程,印刷行业迎来了新的挑战和机遇。在这个竞争激烈的市场上,如何提供快速高质量的印刷解决方案成为了企业和个人的共同追求。作为一家领先的印刷服务提供商,盛通印...2025-11-04盛通印刷商印快线(印刷业新进展,盛通印刷商印快线一站式服务助您高效印刷)
摘要:随着科技的发展和全球化的进程,印刷行业迎来了新的挑战和机遇。在这个竞争激烈的市场上,如何提供快速高质量的印刷解决方案成为了企业和个人的共同追求。作为一家领先的印刷服务提供商,盛通印...2025-11-04Pixelbook教程(探索Pixelbook的功能与技巧,体验极致的电脑操作体验)
摘要:随着科技的不断发展,电脑已经成为了人们工作和娱乐生活中必不可少的一部分。而谷歌的Pixelbook作为一款强大而多功能的笔记本电脑,以其独特的设计和出色的性能受到了众多用户的喜爱。...2025-11-04- 摘要:随着科技的进步,笔记本电脑已经成为我们日常生活中不可或缺的工具之一。然而,有时候我们可能会遇到联想笔记本无故黑屏无反应的问题,这不仅会让我们感到困扰,还可能会对工作和学习造成很大的...2025-11-04
 

最新评论