6

HarmonyOS - 基于ArkUI(JS)实现打地鼠游戏-51CTO.COM

 2 years ago
source link: https://os.51cto.com/article/713962.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

HarmonyOS - 基于ArkUI(JS)实现打地鼠游戏-51CTO.COM

HarmonyOS - 基于ArkUI(JS)实现打地鼠游戏
作者:尹宝荣 2022-07-13 16:24:12
对于FA目前还在摸索的路上,这个游戏写的比较简单,思考的不够全面,还有很多不足之处。
d91e58a72275a2cb1ff555582888aec6ccc2d8.png

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

初学 HarmonyOS ArkUI(JS) ,对于FA的开发还是不太熟悉,单纯看文档,不使用起来的话,始终掌握不了,代码还是要多敲多思考才能进步。所以周末突发奇想利用HarmonyOS 写了一个简单的打地鼠游戏。

#夏日挑战赛# HarmonyOS - 基于ArkUI(JS)实现打地鼠游戏-开源基础软件社区

点击开始按钮之后,顶部剩余时间会从60秒开始倒计时,命中数和得分数清0,同时格子中会随机出现地鼠,点击格子出现锤子敲击地鼠,打中地鼠之后命中数+1,分数根据难度相应增加。难度分为四个星级,玩家可以根据自己的手速选择相应难度,难度越高击中得分越高,地鼠消失的间隔时间越短。60秒倒计时结束之后,地鼠不再出现,弹框提示游戏结束,并显示最终得分。

主要用到知识:animation,倒计时,HarmonyOS 基础组件。

图片来源: iconfont-阿里巴巴矢量图标库。

  1. 绘制4x4的格子,每个格子中有一张地鼠的图片和一张锤子的图片,都默认隐藏。锤子的图片定位在地鼠头上。
  2. 点击开始按钮的时候。
  • 开始60秒倒计时。
  • 每隔一段时间随机显示一张地鼠图片,根据难度显示几秒后隐藏。
  1. 点击“地鼠”时。
  • 锤子出现并有一个向下打击的animation动画效果。
  • 根据当前格子中地鼠的图片和锤子的图片是否显示,判断是否打中地鼠。
  1. 如果打中地鼠,命中次数+1,得分相应增加。
  2. 难度切换后,命中单个地鼠的得分改变,地鼠消失的时间间隔改变。
  3. 60秒倒计时结束后,游戏结束,地鼠不再出现,倒计时停止,弹框提示得分。

1、hml部分

(1)最上面是一些计数信息数据,用到了 input 组件。

<div class="container">
<!-- 头部计数信息模块-->
    <div class="game-title">
        <text class="title-text">打地鼠游戏</text>
    </div>
    <div class="header-info">
    <!--   剩余   -->
        <div class="input-box">
            <text class="input-title">剩余:</text>
            <input class="input" type="text" value="{{ timeInt }}"></input>
            <text class="input-unit">秒</text>
        </div>
    <!--  命中    -->
        <div class="input-box">
            <text class="input-title">命中:</text>
            <input class="input" type="text" value="{{ countInt }}"></input>
            <text class="input-unit">个</text>
        </div>
    <!--   共计   -->
        <div class="input-box">
            <text class="input-title">共计:</text>
            <input class="input" type="text" value="{{ scoreInt }}"></input>
            <text class="input-unit">分</text>
        </div>

(2)难度星级设定,用到了 rating 组件。

<!--   难度选择-->
        <div class="hard-container">
            <text class="input-title">难度设定:</text>
            <rating numstars="4" rating="{{ hardRating }}" stepsize="1" @change="changeRating" id="rating">
            </rating>
        </div>
    <!--    过关分数说明    -->
        <div class="pass-score">
            <text class="pass-text">当前难度: {{hardRating}} 星   命中单个得分:{{ passScore }} 分</text>
        </div>
    </div>

附表:rating组件的属性和事件。

#夏日挑战赛# HarmonyOS - 基于ArkUI(JS)实现打地鼠游戏-开源基础软件社区
#夏日挑战赛# HarmonyOS - 基于ArkUI(JS)实现打地鼠游戏-开源基础软件社区

(3)打地鼠的格子区域 ,是用数据for循环出来的,写的时候没有考虑周全,代码有一些冗余,感兴趣的伙伴可以把这块代码重构一下,看起来会更简洁。

<!--  打地鼠区域  -->
    <div class="game-area">
    <!-- 第1行-->
        <div class="game-tr1">
            <div class="game-td" for="item in trOne[0]" on:click="showHammer({{ item }})">
                <image class="hammer-pic cover" id="{{ item.idValue }}" src="common/images/hammer.png"
                       show="{{ item.showHammer }}">
                </image>
                <image class="game-pic cover" src="common/images/dishu.png" show="{{ item.showMose }}">
                </image>
            </div>
        </div>
    <!--    第2行   -->
        <div class="game-tr1">
            <div class="game-td" for="item in trOne[1]" on:click="showHammer({{ item }})">
                <image class="hammer-pic cover" id="{{ item.idValue }}" src="common/images/hammer.png"
                       show="{{ item.showHammer }}">
                </image>
                <image class="game-pic cover" src="common/images/dishu.png" show="{{ item.showMose }}">
                </image>
            </div>
        </div>
    <!--    第3行    -->
        <div class="game-tr1">
            <div class="game-td" for="item in trOne[2]" on:click="showHammer({{ item }})">
                <image class="hammer-pic cover" id="{{ item.idValue }}" src="common/images/hammer.png"
                       show="{{ item.showHammer }}">
                </image>
                <image class="game-pic cover" src="common/images/dishu.png" show="{{ item.showMose }}">
                </image>
            </div>
        </div>
    <!--     第4行    -->
        <div class="game-tr1 last-tr">
            <div class="game-td" for="item in trOne[3]" on:click="showHammer({{ item }})">
                <image class="hammer-pic cover" id="{{ item.idValue }}" src="common/images/hammer.png"
                       show="{{ item.showHammer }}">
                </image>
                <image class="game-pic cover" src="common/images/dishu.png" show="{{ item.showMose }}">
                </image>
            </div>
        </div>
    </div>

(4)开始按钮和弹框,用到了 button 组件和 dialog 组件。

<!--  开始按钮  -->
    <div class="btn-area">
        <button class="btn-start" value="开始" on:click="startGame">
        </button>
    </div>
<!--  提示框  -->
    <dialog id="hintDialog" style="margin-bottom : 50%;">
        <div class="dialog-div">
            <div class="inner-txt">
                <text class="txt">GAME OVER</text>
            </div>
            <text class="text">游戏得分:{{ scoreInt }}</text>
            <div class="inner-btn">
                <button type="text" value="确定" onclick="closeDialog" class="btn-txt">                   </button>
            </div>
        </div>
    </dialog>
</div>

2、css部分

.container {
    padding-top: 20px;
    flex-direction: column;
}
/*头部信息样式*/
.game-title {
    display: flex;
    justify-content: center;
    color: chocolate;
    margin-bottom: 20px;
}
.header-info {
    flex-direction: column;
}
.input-title {
    font-size: 18px;
}
.input {
    width: 100px;
    height: 30px;
}
.input-unit {
    font-size: 18px;
    margin-left: 8px;
}
.input-box {
    margin-bottom: 14px;
    margin-left: 20px;
}
/*难度系数选择样式*/
.hard-container{
    margin-left: 20px;
    margin-bottom: 15px;
}
rating {
    width: 160px;
    height: 40px;
}
.pass-score{
    margin-left: 20px;
}
.pass-text{
    font-size: 16px;
    color: mediumblue;
}
/*游戏区域样式*/
.game-area {
    border: 1px solid black;
    flex-direction: column;
    margin: 20px;
    background-color: lightgreen;
}
.game-tr1 {
    height: 80px;
    border-bottom: 1px solid black;

}
.last-tr {
    border-bottom: none;
    flex: 1;
}
.game-td {
    position: relative;
    width: 80px;
    height: 80px;
    border-right: 1px solid black;
    display: flex;
    justify-content: center;
    align-items: center;
}
.game-pic {
    width: 85%;
    height: 85%;
}
.hammer-pic {
    position: absolute;
    top: 0px;
    left: 20px;
    width: 60px;
    height: 60px;
    z-index: 99;
}
/*按钮样式*/
.btn-area {
    display: flex;
    justify-content: center;
    margin-top: 10px;
}
.btn-start {
    width: 100px;
    height: 30px;
}
/*弹框样式*/
.dialog-div {
    flex-direction: column;
    align-items: center;
}
.area {
    width: 88%;
    border-radius: 5px;
}
.inner-txt {
    width: 80%;
    height: 100px;
    align-items: center;
    flex-direction: column;
    justify-content: space-around;
}
.txt {
    font-size: 18px;
    color: #000000;
    font-weight: bold;
}
.text {
    font-size: 16px;
}
.inner-btn {
    width: 80%;
    height: 100px;
    align-items: center;
    justify-content: space-around;
}

3、js部分

export default {
    data: {
        timeInt: 60, //剩余时间
        countInt: 0, //命中个数
        scoreInt: 0, //得分
        animation: '', //敲击动画
        //地鼠数据
        trOne: [
            [{
                 tr: 1,
                 id: 1,
                 idValue: 'A1',
                 showHammer: false,
                 showMose: false
             },
             {
                 tr: 1,
                 id: 2,
                 idValue: 'A2',
                 showHammer: false,
                 showMose: false
             },
             {
                 tr: 1,
                 id: 3,
                 idValue: 'A3',
                 showHammer: false,
                 showMose: false
             },
             {
                 tr: 1,
                 id: 4,
                 idValue: 'A4',
                 showHammer: false,
                 showMose: false
             },],

            [{
                 tr: 2,
                 id: 1,
                 idValue: 'A5',
                 showHammer: false,
                 showMose: false
             },
             {
                 tr: 2,
                 id: 2,
                 idValue: 'A6',
                 showHammer: false,
                 showMose: false
             },
             {
                 tr: 2,
                 id: 3,
                 idValue: 'A7',
                 showHammer: false,
                 showMose: false
             },
             {
                 tr: 2,
                 id: 4,
                 idValue: 'A8',
                 showHammer: false,
                 showMose: false
             },],
            [{
                 tr: 3,
                 id: 1,
                 idValue: 'A9',
                 showHammer: false,
                 showMose: false
             },
             {
                 tr: 3,
                 id: 2,
                 idValue: 'A10',
                 showHammer: false,
                 showMose: false
             },
             {
                 tr: 3,
                 id: 3,
                 idValue: 'A11',
                 showHammer: false,
                 showMose: false
             },
             {
                 tr: 3,
                 id: 4,
                 idValue: 'A12',
                 showHammer: false,
                 showMose: false
             },],
            [{
                 tr: 4,
                 id: 1,
                 idValue: 'A13',
                 showHammer: false,
                 showMose: false
             },
             {
                 tr: 4,
                 id: 2,
                 idValue: 'A14',
                 showHammer: false,
                 showMose: false
             },
             {
                 tr: 4,
                 id: 3,
                 idValue: 'A15',
                 showHammer: false,
                 showMose: false
             },
             {
                 tr: 4,
                 id: 4,
                 idValue: 'A16',
                 showHammer: false,
                 showMose: false
             },]
        ], 
        hardRating: 1, //难度等级(默认为1)
        passScore: 1, //命中单个得分
        disAppearTime: 2500, //消失时间
        hardList: [
            {
                hardId: 1,
                add: 1,
                disappear: 2500,
            },
            {
                hardId: 2,
                add: 2,
                disappear: 2000,
            },
            {
                hardId: 3,
                add: 3,
                disappear: 1500,
            },
            {
                hardId: 4,
                add: 5,
                disappear: 500,
            }
        ],
    },
    onInit() {

    },
    onShow() {
        this.hardRating = 1
    },
    //打开弹框
    showDialog(e) {
        this.$element('hintDialog').show()
    },
    //关闭弹框
    closeDialog(e) {
        this.$element('hintDialog').close()
    },
    //开始按钮 数据清零
    startGame() {
        this.timeInt = 60;
        this.countInt = 0;
        this.scoreInt = 0;
        //生成地鼠
        let moseTimer = setInterval(this.showMose, 100)
        //游戏时间倒计时
        let countDown = setInterval(() => {
            this.timeInt--;
            //倒计时结束清除定时器
            if (this.timeInt === 0) {
                clearInterval(countDown);
                clearInterval(moseTimer);
                //弹出游戏结束弹框
                this.showDialog();
            }
        }, 1000)

    },
    //随机生成地鼠
    showMose() {
        let i = Math.round(Math.random() * 3);
        let j = Math.round(Math.random() * 3);
        this.trOne[j][i].showMose = true;
        //根据难度决定隔多少毫秒地鼠消失
        setTimeout(() => {
            this.trOne[j][i].showMose = false;
        }, this.disAppearTime)
    },
    //敲击地鼠动画效果
    showHammer(item) {
        this.trOne[item.tr-1][item.id-1].showHammer = true;
        var options = {
            duration: 50,
            easing: 'friction',
            delay: 0,
            fill: 'forwards',
            iterations: 2,
            direction: 'normal',
        };
        var frames = [
            {
                transform: {
                    rotate: '0deg'
                }, opacity: 0.1, offset: 0.0
            },
            {
                transform: {
                    rotate: '-30deg'
                }, opacity: 1.0, offset: 1.0
            }
        ];
        this.animation = this.$element(item.idValue).animate(frames, options);
        this.animation.play();

        //命中数及分数变化
        this.countHander()

        //锤子消失
        setTimeout(() => {
            this.trOne[item.tr-1][item.id-1].showHammer = false;
        }, 300)

    },
    //命中数及分数变化
    countHander() {
        this.trOne.forEach((item, index) => {
            item.forEach((_item, _i) => {
                if (_item.showHammer == true && _item.showMose == true) {
                    this.countInt++;
                    //根据难度计算得分
                    this.scoreInt += this.passScore
                }
            })
        })
    },
    //难度改变
    changeRating(e) {
        this.hardRating = e.rating;
        //命中得分改变
        this.passScore = this.hardList[this.hardRating-1].add;
        //地鼠消失时间改变
        this.disAppearTime = this.hardList[this.hardRating-1].disappear
    }
}

对于FA目前还在摸索的路上,这个游戏写的比较简单,思考的不够全面,还有很多不足之处。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。


Recommend

  • 8
    • os.51cto.com 3 years ago
    • Cache

    HarmonyOS-ArkUI实现宫格抽奖器

    HarmonyOS-ArkUI实现宫格抽奖器-51CTO.COM HarmonyOS-ArkUI实现宫格抽奖器 作者:李进 2022-03-03 18:49:56 巧妙的结合setInterval的机制实现了九宫格抽奖功能,点击抽奖时每次执行都是滚轮转动...

  • 5

    HarmonyOS - ArkUI(JS)实现电池充电动画-51CTO.COM HarmonyOS - ArkUI(JS)实现电池充电动画 作者:陈忠蔚 2022-07-20 15:24:47 结合系统的Animator可以实现各种各样炫酷的动画效果,...

  • 6

    基于ArkUI (JS) 实现图片旋转验证-51CTO.COM HarmonyOS - 基于ArkUI (JS) 实现图片旋转验证 作者:王少丽 2022-08-05 19:27:22 本文主要结合HarmonyOS官网上的相关组件以及通用API,...

  • 6

    HarmonyOS - 基于ArkUI(JS)实现黑白翻棋小游戏 作者:苏亚雯 2022-08-22 17:28:34 本文详细讲述了黑白翻棋的编写思路,内含详细解释,有兴趣的小伙伴可以自己动手来制作一个属于自己的黑白翻棋小游戏。

  • 4

    HarmonyOS - ArkUI(JS)实现数字记忆小游戏 作者:陈甜甜 2022-08-25 21:41:43 进入游戏页面,启动计时功能,并且随机生成小球,默认数量为六个。时间到达5s后小球内部的数字内容会消失,凭借用户的记忆按照数字...

  • 0

    HarmonyOS- 基于ArkUI(eTs)实现猫头鹰动画 作者:范颖 2022-09-05 15:22:27 我决定用Ets来画一只猫头鹰,看看Ets跟我之前掌握的知识有何不同,在什么地方需要值得注意。

  • 4

    HarmonyOS - 基于ArkUI(JS)实现自定义Circle进度条 作者:张前霞 2022-09-09 14:47:50 Circle进度条组件在开发中经常用到,形式多种多样,参考canvas文档做了简单的一种,支持各种属性调整。有需要可以参考看看...

  • 4

    HarmonyOS - 基于ArkUI(JS)实现彩带飘动特效 作者:曾昭卓 2022-09-14 15:17:26 彩带飘动特效,主要是使用canvas来实现的,设置三角形的两个初始的点,在随机生成第三个点,并绘制三角形,生成随机颜色,填充三...

  • 5

    HarmonyOS - 基于ArkUI(JS)实现信件弹出效果 作者:罗晓纯 2022-09-21 14:51:21 可别觉得书信是一个过时的东西,它可是80后的情怀,90后的回忆,00后的新宠,是经典的代名词。今天就想实现把这些古老的元素融入...

  • 9

    HarmonyOS - 基于ArkUI(ETS) 实现心电图组件 作者:杨尚晓 2022-10-24 14:49:54 绘制这个心电图没有用到重绘机制,动画效果是每次绘制的时候覆盖在原有的波形线上的,但是这样会比重绘整个画布性能更好一些。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK