HarmonyOS - ArkUI(JS)实现数字记忆小游戏 原创 精华

中软国际鸿蒙生态
发布于 2022-8-25 14:13
浏览
5收藏

作者:陈甜甜

前言

最近在逛论坛的时候看到这样的一个测试题:“实现一个点击数字的小游戏:依次点击容器中随机生成的数字元素,生成的数字元素会在5S后消失,你将凭借记忆点击按照数字升序依次点击生成的数字方可通过该关卡游戏”,看到了各位大佬用原生js实现的小游戏还挺有意思,想着自己对FA的开发还是不太熟悉,就尝试用HarmonyOS来实现一下这个游戏。

项目说明

工具版本:DevEco Studio 3.0 Beta3

SDK版本:3.1.5.5

效果展示

HarmonyOS - ArkUI(JS)实现数字记忆小游戏-鸿蒙开发者社区

游戏简介

进入游戏页面,启动计时功能,并且随机生成小球,默认数量为六个。时间到达5s后小球内部的数字内容会消失,凭借用户的记忆按照数字升序依次点击数字点可顺利通关,否则通关失败。

实现步骤

1. 整体页面布局

包括顶部游戏简介,中间小球展示区,和底部对应的重新开始按钮和下一关按钮。

2. 小球的生成

通过动态渲染的方式生成小球,并且小球数量随着关卡级别升高而增加。

3. 时间设置

一进入游戏界面就开始计时,五秒后小球上的数字消失需要玩家进行记忆点击,对玩家依次点击触发的小球数字进行去重和排序处理。

4. 闯关是否成功

排序处理后进行判断,如果排序是从小到大依次点击的顺序,则代表用户闯关成功,否则闯关失败,并弹出对应的弹窗。

5. 重新开始和关卡升级

用户触发重新开始时,回到默认的初始化关卡,对之前的小球操作等进行清零,点击下一关时对应的小球数量增加,时间不变,最多可增加到十个小球。

代码实现

1. hml部分

<div class="container">
    <div class="header">
        <div class="titleMessage">
            <text style="font-size: 16px;">游戏玩法提示小tips:5s后数字内容会消失,凭借你的记忆按照数字升序依次点击数字点可顺利通关。</text>
        </div>
    </div>
    <div id="cointainer">
        <div for="{{ circleList }}" class="parm {{$item.className}}" @click="recordNmuber($item.text)" style="top:{{$item.top}};left:{{$item.left}};backgroundColor:{{$item.rgrbColor}}">
            <text class="{{cricleClassName}}">{{$item.text}}</text>
        </div>
    </div>
    <div class="todo">
        <text class="again" @click="restart(6)">重新开始</text>
        <text class="again" @click="nextPass" style="margin-left: 20px" >下一关</text>
    </div>
    <div class="againtime">
        <text>time:</text><text>
        <span>{{time}}</span>
    </text>
    </div>
    <div class="goFail" if="{{ isSuccess == false }}"  >
        <text class="goFail-text">
            <span>很遗憾通关失败~~</span>
        </text>
    </div>
    <div class="goFail" if="{{ isSuccess == true }}"  >
        <text class="goFail-text">
            <span>恭喜你通关成功呀</span>
        </text>
    </div>
</div>

2. css部分

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
    height: 100%;
    width: 100%;
    position: relative;
}
.header {
   display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
}
.titleMessage{
    margin-top: 40px;
    width: 100%;
    height: 80px;
    background-color: cornsilk;
    border-radius: 15px;
   padding: 0 10px ;
}
#cointainer {
    display: flex;
   align-items: center;
    margin-top: 20px;
    height: 500px;
    width: 400px;
    background-color: rgb(37, 37, 37);
    position: relative;
}
.todo {
    justify-content: center;
    align-items: center;
    position: absolute;
    top: 84%;
}
.again{
    text-align: center;
    font-size: 18px;
    width: 90px;
    height: 40px;
    background-color: burlywood;
}
.againtime{
    position: absolute;
    top: 91%;
    margin-left: 100px;
    text-align: center;
    font-size: 18px;
    width: 170px;
    height: 40px;
    background-color: dimgray;
    border-radius: 5px;
    padding-left: 19px;
}
.parm{
    width: 80px;
    height: 80px;
    border-radius: 80;
    justify-content: center;
    align-items: center;
    position: absolute;
}
.cricle_text_none{
    display: none;
}
.goFail{
    background-color: beige;
    height: 80px;
    width: 200px;
    border-radius: 20px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    justify-content: center;
    align-items: center;
}
.goFail-text{
    font-size: 16px;
}

3. js部分

export default {
    data: {
        circleList : [],
        containner:'',
        timmer1:'',
        timmer2:'',
        time:'',
        pass:6,
        asw:[],
        cricleClassName:'',
        recodArr:[],
        isSuccess:null,
    },
    onInit() {
        this.containner = this.$element('cointainer') //获取游戏画板容器元素
        this.timmer2 = setInterval(this.sumTime, 10);
        console.log(this.time)
        this.creatGame(this.pass);
    },
    sumTime() {
    //时间保留两位小数点。
        this.time = (Number(this.time) + 0.01).toFixed(2);
    //当时间超过5秒后,让小球上的数字消失。
        if(Number(this.time)>5) this.cricleClassName = 'cricle_text_none'
    },
    //点击小球时候触发的事件处理函数
    recordNmuber(num){
    //时间小于5秒时点击小球不计入到数组中
        if(this.time<5) return
    //大于五秒时点击小球将对应的数字push到一个新数组里。
         this.recodArr.push(num)
        console.log(JSON.stringify(this.recodArr))
    //去重操作
         let newArr = this.noRepeat(this.recodArr)
        console.log(newArr)
    //对数组进行排序
        if(newArr.length===this.pass) {
            let str = ''
            for (var index = 0; index < this.pass; index++) {
                if(index+1 ===this.pass) {
                    str+=String(index+1)
                }
                if((index+1)<this.pass){
                    str+=(String(index+1) + ',')
                }
            }
            console.log(str)
    //如果是为数字升序则弹出通关成功弹窗,并清空计时器,否则将弹出通关失败弹窗
            if(String(newArr) === String(str)) {
                console.log('true')
                this.isSuccess=true
                clearInterval(this.timmer2);
            }else{
                console.log('false')
                this.isSuccess=false
                clearInterval(this.timmer2);
            }
        }
    },
    //数组去重方法
    noRepeat(arr) {
		//定义一个新的临时数组
		let newArr=[];
		//遍历当前数组
		for(var i=0;i<arr.length;i++) {
		  //如果当前数组的第i已经保存进了临时数组,那么跳过,
		  //否则把当前项push到临时数组里面
		  if(newArr.indexOf(arr[i]) === -1) {  //indexOf() 判断数组中有没有字符串值,如果没有则返回 -1
		     newArr.push(arr[i]);
		  }
    	}
    return newArr
  },
    //circle构造器
    getPosition() {
        let parm = { x: 0, y: 0 };
    //随机生成circle的坐标。
        parm.x = Math.round(Math.random() * 200);
        parm.y = Math.round(Math.random() * 400);
        return parm;
    },
    //创建不重叠circle
      createCircle(total) {
        if (this.circleList.length === 0) {
            this.circleList.push(this.getPosition());
        }
        //限制创建次数200
        for (let i = 0; i < 200; i++) {
            if (this.circleList.length < total) {
                let circle = this.getPosition();
                let distan = [];
                for (let n = 0; n < this.circleList.length; n++) {
                    let dis =
                        Math.abs(circle.x - this.circleList[n].x) ** 2 +
                        Math.abs(circle.y - this.circleList[n].y) ** 2;
                    distan.push(dis);
                }
                if (Math.min(...distan) > 3600) {
                    this.circleList.push(circle);
                }
            } else {
                break;
            }
        }
    },
    //创建8个circle
    //随机颜色选择器
     selectColor() {
        let r = 100 + Math.round(Math.random() * 155);
        let g = 100 + Math.round(Math.random() * 155);
        let b = 100 + Math.round(Math.random() * 155);
        return `rgb(${r},${g},${b})`;
    },
    //构造关卡,不同关卡对应不同数量的小球,默认为六个小球。
     creatGame(num) {
        this.circleList = [];
        this.createCircle(num);
        for (let i = 0; i < this.circleList.length; i++) {
            this.circleList[i].className = "parm";
            this.circleList[i].text = i + 1;
            this.circleList[i].left = this.circleList[i].x + "px";
            this.circleList[i].top = this.circleList[i].y + "px";
            this.circleList[i].rgrbColor = this.selectColor();
        }
    },
    //触发重新开始
    restart(nowerPass) {
        this.isSuccess=null, //将通关失败和成功的弹窗进行关闭
        this.circleList = []
        this.pass = nowerPass;
        this.recodArr= []
        this.cricleClassName=''
        this.creatGame(nowerPass);
        clearInterval(this.timmer2);
        this.time = 0;
        this.timmer2 = setInterval(this.sumTime, 10);
    },
    //下一关
    nextPass() {
    //圆球数量设限,最多屏幕中出现十个小球。
        if (this.pass < 10) {
            this.pass++;
            this.restart(this.pass);
        }
    }
}

总结

这篇文章是我第一次写小游戏,在实现的过程中也遇到了很多问题,得力与同事们的帮助,才顺利实现这个小游戏,后面还需再继续学习,增加自己对FA的熟悉度,多写多练提升自己,每天进步一点点。

更多原创内容请关注:中软国际 HarmonyOS 技术团队

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-8-25 14:13:55修改
8
收藏 5
回复
举报
5条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

这个小游戏感觉对锻炼记忆力很有帮助

1
回复
2022-8-25 15:46:23
82王先生
82王先生

厉害厉害,甜美女果然强

1
回复
2022-8-25 17:33:37
lollipoptt
lollipoptt 回复了 82王先生
厉害厉害,甜美女果然强

比起82王先生还是逊色了

1
回复
2022-8-25 17:34:32
lollipoptt
lollipoptt 回复了 红叶亦知秋
这个小游戏感觉对锻炼记忆力很有帮助

哈哈 确实

1
回复
2022-8-25 17:35:22
0aaron
0aaron

5s数字消失的这个时长会不会太短了

回复
2022-8-26 15:11:41
回复
    相关推荐