大家好,我是Feri,深耕嵌入式、鸿蒙、AI和Java的资深程序员,带过团队创过业,一直专注帮程序员少走弯路!
最近玩ArkUI基础组件时发现:只用按钮、图片+ArkTS随机数/函数,就能做出小朋友超爱的石头剪刀布小游戏——全程仅需2小时,新手跟着敲也能搞定,君志所向,一往无前,今天就手把手带大家实现!
🔥 先划重点:玩着学鸿蒙,吃透核心知识点
做这个小游戏不只是图乐,还能吃透ArkUI/ArkTS的核心考点: ✅ Button/Image组件+点击手势:搞定前端交互逻辑 ✅ @State状态管理:实现“数据变、UI自动更”的鸿蒙核心思想 ✅ Math.random()随机数:处理电脑随机出拳逻辑 ✅ 自定义函数封装:让代码更简洁、易维护
🎯 需求拆解:把游戏拆成3个核心问题
做任何项目先拆需求,石头剪刀布看似简单,核心就3件事:
- 交互层:用户能手动选石头/剪刀/布(用可点击的Image组件实现)
- 逻辑层:电脑随机出拳(一行Math.random()就能搞定)
- 数据层:判断输赢+实时计分(自定义函数+状态更新)
🎨 界面设计:3个区域搭出清爽布局
用ArkUI基础组件搭界面,结构清晰又好看,新手也能看懂:
- 🎮 用户决策区:可点击的Image组件,点一下切换石头/剪刀/布,交互超直观
- 🖥️ 视觉反馈区:分“电脑面板”和“用户面板”,用Image+Text展示双方出拳结果
- 📊 数据展示区:Text组件实时显示比分,带蓝色边框标注本轮结果,输赢一眼看清
💻 保姆级编码:逐行解析核心代码
直接上完整代码+关键注释,每个模块都讲透,不怕你看不懂!
第一步:定义状态变量(数据驱动UI的核心)
先用@State声明需要的变量,只有被@State修饰的变量,才能驱动UI自动更新:
@Entry
@Component
struct Demo1Page {
@State message: string = 'Hello World';
// 石头/剪刀/布图片数组(提前把图片放进media文件夹)
imgs:Resource[]=[$r("app.media.st"),$r("app.media.jd"),$r("app.media.bu")];
// 电脑相关状态:图片、提示文本、分数
@State cimg:Resource=$r("app.media.startIcon"); // 初始占位图
@State cmsg:string=""; // 电脑出拳提示
@State cscore:number=0; // 电脑分数
// 用户相关状态:图片索引(计算用)、图片、提示文本、分数
uindex:number=0; // 仅用于切换图片,无需@State
@State uimg:Resource=this.imgs[0]; // 用户选择的图片
@State umsg:string=""; // 用户出拳提示
@State uscore:number=0; // 用户分数
// 本轮比赛结果
@State result:string='';
// 下面是build布局和核心逻辑...
}
第二步:搭建界面布局(可视化部分)
用Column+Row嵌套实现页面结构,鸿蒙布局就是这么简单:
build() {
Column(){
// 标题:醒目红色大字
Text("石头剪刀布")
.fontColor(Color.Red)
.fontSize(30)
// 比分展示行:左右分布,一眼看清双方分数
Row(){
Text("电脑:"+this.cscore).margin({left:20})
Text("用户:"+this.uscore).margin({right:20})
}
.width("100%")
.justifyContent(FlexAlign.SpaceBetween)
.margin({top:10,bottom:20})
// 电脑出拳展示区:绿色文本+大图
Column({space:20}){
Text(this.cmsg).fontColor(Color.Green).fontSize(20)
Image(this.cimg).height(200)
}.width("100%")
// 本轮结果:蓝色边框标注,更醒目
Text("本轮比赛结果:"+this.result)
.margin(20)
.padding(10)
.border({style:BorderStyle.Solid,color:Color.Blue,width:3})
// 用户出拳选择区:点击图片切换类型
Column({space:20}){
Text(this.umsg).fontColor(Color.Red).fontSize(20)
Image(this.uimg)
.onClick(()=>{
// 核心技巧:取模实现循环切换(0→1→2→0...)
this.uindex++;
this.uimg=this.imgs[this.uindex%this.imgs.length];
this.umsg="用户选择的是:"+getMsg(this.uindex%this.imgs.length);
})
.height(200)
// 提示文字:灰色小字更友好
Text("亲,请选择你要出的结果,点击图片即可切换类型")
.fontColor(Color.Gray)
.fontSize(12)
}.width("100%")
// 开始游戏按钮:触发核心逻辑
Button("开始游戏")
.onClick(()=>{
// 1. 电脑随机出拳(0-2的随机整数)
let cindex=Math.floor(Math.random()*this.imgs.length);
this.cimg=this.imgs[cindex];
this.cmsg="电脑本轮的结果:"+getMsg(cindex);
// 2. 计算用户当前选择的索引
let ui:number=this.uindex%this.imgs.length;
// 3. 输赢判断核心逻辑(记口诀:石头赢剪刀、剪刀赢布、布赢石头)
if(ui===cindex){
// 平局:双方各加1分
this.uscore++;
this.cscore++;
this.result="平局";
}else if(
(ui===0&&cindex===1) || (ui===1&&cindex===2) || (ui===2&&cindex===0)
){
// 用户赢:用户+1,电脑-1
this.uscore++;
this.cscore--;
this.result="用户赢了";
}else {
// 用户输:电脑+1,用户-1
this.cscore++;
this.uscore--;
this.result="用户输了";
}
})
.width("80%")
.margin({top:20})
}
.height('100%')
.width('100%')
}
第三步:自定义函数(索引转文字,代码更简洁)
把数字索引转换成“石头/剪刀/布”文字,避免重复代码:
// 工具函数:0=石头,1=剪刀,2=布
function getMsg(index:number):string{
let r:string="未知";
switch (index){
case 0:r="石头";break;
case 1:r="剪刀";break;
case 2:r="布";break;
}
return r;
}
🎮 效果展示:点击就能玩!
👉 操作流程:点击用户图片切换出拳类型 → 点“开始游戏” → 电脑随机出拳 → 比分和结果实时更新,小朋友玩得停不下来!
🚀 进阶小彩蛋(可选)
学会基础版后,还能加这些功能升级,可玩性翻倍:
- ✨ 加动画:给Image加缩放动画(scaleTo),出拳时更有互动感;
- 🎯 加胜负条件:先到10分的一方获胜,弹出提示框;
- 🔄 加重置功能:新增“重新开始”按钮,一键清空比分。
✨ 最后说两句
这个小游戏看似简单,却覆盖了鸿蒙开发的核心:组件使用、状态管理、事件处理、逻辑封装。花2小时敲一遍,不仅能巩固ArkUI基础,还能体会“数据驱动UI”的鸿蒙核心思想。
如果大家想考取鸿蒙开发者认证的,欢迎加入我的专属考试链接中:developer.huawei.com/consumer/cn…
后续还会用ArkUI做更多趣味小项目(贪吃蛇、打地鼠),帮你在玩中学鸿蒙,成长路上不孤单,君志所向,一往无前!