微信小程序 实现蚂蚁森林效果

wxml:

<view class="view_energy">
	<!-- 能量球 -->
	<view class="energy_all">
		<view class="item_energy" wx:for="{{energyList}}" wx:key="index" style="{{item.styleObject}}" bindtap="pullEnergy" data-i="{{index}}">
			<text class="energy_title" style="{{item.childStyle}}">{{item.num}}</text>
			<view class="energy_tips">{{item.title}}</view>
		</view>
	</view>
	<!-- 收取能量 -->
	<view class="get_integral" bindtap="pullAllEnergy">
		<image src="https://s1.ax1x.com/2023/04/23/p9e4z9J.png" class="img_collect" mode="widthFix"></image>
	</view>
	<!-- 浇水 -->
	<view bind:tap="jiaoshui">
		<image src="https://s1.ax1x.com/2023/04/23/p9eI6df.png" mode="widthFix" class="img_jiaoshui" />
		<view class="font">浇水</view>
	</view>
	<!-- 浇水gif -->
	<view>
		<image class="shui" hidden="{{isShui}}" src="https://wimg.588ku.com/gif620/21/09/02/a26ae7c290bfb00d5044457c9d023159.gif" mode="" />
	</view>
	<!-- 施肥 -->
	<view>
		<image src="https://s1.ax1x.com/2023/04/23/p9eI7wV.png" mode="widthFix" class="img_shifei" />
		<view class="font_shifei">施肥</view>
	</view>
</view>

<view class="sum">能量总数:{{sum}}</view>

wxss:

page {
  width: 100vw;
  height: 100vh;
  background: linear-gradient(to bottom, rgb(34, 193, 195), rgba(236, 202, 129, 0.7));
  /* 标准语法 */
}

/* 能量 */
.view_energy {
  height: 500rpx;
  width: 100%;
  position: relative;
}

.view_energy_list {
  position: relative;
  height: 130rpx;
  width: 116rpx;
  text-align: center;
}

@keyframes heart {
  from {
    transform: translate(0, 0);
    opacity: 1;
  }

  to {
    transform: translate(0, 6px);
    opacity: 0.8;
  }
}

@keyframes lines {
  from {
    transform: translate(0px, 0);
  }

  to {
    transform: translate(3px, 0);
  }
}

.energy_title {
  font-size: 23rpx;
  line-height: 110rpx;
  letter-spacing: 2rpx;
  color: white;
  display: block;
  width: 110rpx;
  height: 110rpx;
  text-align: center;
  font-family: 'wangte';
  background-image: url('http://image.51what.cn/public/upload/20190830/7addf9a8844d06bbddbdf30a31ea2fc5.png');
  background-size: 100% 100%;
  /* margin: 0 15rpx; */
}

.energy_tips {
  margin-top: -10rpx;
  font-size: 20rpx;
  color: white;
}

.view_collect {
  text-align: center;
}

/* 能量球的样式 */
.energy_all {
  position: relative;
}

.item_energy {
  position: absolute;
  /* height: 130rpx; */
  width: 116rpx;
  text-align: center;
  z-index: 1;
  transition: all .6s ease;
}

.energy_title {
  margin: 0 auto;
  font-size: 28rpx;
  letter-spacing: 2rpx;
  color: #fff;
  display: block;
  border-radius: 50%;
  text-align: center;
  background-image: url('http://image.51what.cn/public/upload/20190830/7addf9a8844d06bbddbdf30a31ea2fc5.png');
  background-size: 100% 100%;
}

.energy_tips {
  font-size: 22rpx;
  color: #fff;
  text-align: center;
}

/* 收取按钮css */
.get_integral {
  position: absolute;
  bottom: 40px;
  left: 50%;
  top: 100%;
  transform: translateX(-50%);
  width: 600rpx;
  height: 113rpx;
  z-index: 999;
}

.img_collect {
  width: 100%;
  height: 100%;
  /* animation: mycollect 1.0s ease-in-out 0.7s infinite alternate; */
}

@keyframes mycollect {
  from {
    transform: translate(-6px, 0);
  }

  to {
    transform: translate(6px, 0);
  }
}


.img_jiaoshui {
  width: 100rpx;
  margin-top: 1000rpx;
  margin-left: 50rpx;
}

.font {
  font-size: 28rpx;
  letter-spacing: 2rpx;
  color: #fff;
  margin-left: 70rpx;
  font-weight: 600;
}

.img_shifei {
  width: 100rpx;
  position: absolute;
  right: 0;
  margin-top: -140rpx;
  margin-right: 50rpx;
}

.font_shifei {
  font-weight: 600;
  font-size: 28rpx;
  letter-spacing: 2rpx;
  color: #fff;
  position: absolute;
  right: 0;
  margin-top: -40rpx;
  margin-right: 70rpx;
}

.shui {
  position: absolute;
  width: 280rpx;
  top: 140%;
  left: 50%;
  z-index: 999;
}

.sum {
  text-align: center;
  font-size: 50rpx;
  font-weight: bold;
  color: #fff;
  margin-top: 600rpx;
}

js

Page({
    data: {
        length: 10,
        energyList: [], //能量球
        disablePosShow: {}, //按钮信息
        integralPos: {}, //最多出现的位置
        isClick: 0, //记录领取了几次
        sum: 0,
        addTimer: '',
        arred: [], //能量球的index
        isShui: true
    },
    onLoad() {
        this.energyInit()
    },

    //初始化能量球
    energyInit() {
        let t = this,
            arr = [];
        t.integralPos(() => {
            for (var j = 0; j < t.data.length; j++) {
                let obj = t.isCreate(arr)
                if (obj) {
                    arr.push(obj)
                } else {
                    j--
                }
            }
            this.setData({
                energyList: arr
            })
        })
    },

    //获取收取按钮的位置
    integralPos(callback) {
        let t = this
        wx.getSystemInfo({
            success(res) {
                wx.createSelectorQuery().select('.get_integral').boundingClientRect(function (rect) {
                    t.data.disablePosShow = rect
                    console.log(rect);
                    t.data.integralPos.maxWidth = res.windowWidth - 50
                    t.data.integralPos.maxHeight = rect.bottom
                    callback()
                }).exec();
            }
        })

    },

    //圆和圆之间不可以重叠 判断两个元之间的圆心距离
    getCircleDistance(p1, p2, distanceToBall) {
        let dx = Math.abs(p2.left - p1.left),
            dy = Math.abs(p2.top - p1.top),
            //两个圆之间的距离
            disToBall = parseInt(Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)));
        return disToBall > distanceToBall;
    },

    //58为每个能量球的宽度
    disablePos(left, top) {
        if (left > this.data.disablePosShow.left - 55 && left < this.data.disablePosShow.left + this.data.disablePosShow.width && top > this.data.disablePosShow.top - 55) {
            return false
        } else {
            return true
        }
    },


    trainFn(min, max) {
        let num = Math.floor(Math.random() * (max - min + 1) + min)
        return num
    },

    isCreate(overList) {
        let t = this,
            obj = {
                left: t.trainFn(0, t.data.integralPos.maxWidth),
                top: t.trainFn(0, t.data.integralPos.maxHeight - 25),
                // size: t.trainFn(70),
                size: 80,
                anm_time: (Math.random()).toFixed(1),
                num: t.trainFn(2, 20),
                title: `签到`,
                styleObject: '',
                childStyle: '',
                isShow: true,
            }
        // obj.top = t.trainFn(10, t.data.integralPos.maxHeight-obj.size)
        obj.styleObject = `left: ${obj.left}px; top: ${obj.top}px; animation: heart 1.3s ease-in-out ${obj.anm_time}s infinite alternate`
        obj.childStyle = `width: ${obj.size}rpx; height: ${obj.size}rpx; line-height: ${obj.size}rpx`
        if (obj.size < 50) {
            obj.childStyle = `width: ${obj.size}rpx; height: ${obj.size}rpx; line-height: ${obj.size}rpx; font-size: 22rpx;`
        }
        let isflag = true
        if (!t.disablePos(obj.left, obj.top)) {
            isflag = false
        }
        overList.forEach((item) => {
            if (!t.getCircleDistance(item, obj, 60)) {
                isflag = false
            }
        })
        if (isflag) {
            return obj
        }
    },

    //收取动画
    gatherAn(item, style) {
        this.setData({
            [style]: item.styleObject
        })
        let addTotal = this.data.sum + Number(item.num)
        this.data.addTimer = setInterval(() => {
            if (this.data.sum != addTotal) {
                this.setData({
                    sum: this.data.sum + 1
                })
            } else {
                clearInterval(this.data.addTimer)
            }
        }, 10)
    },

    //点击能量球领取积分
    pullEnergy(e) {
        this.data.isClick++
        clearInterval(this.data.addTimer)
        let index = e.currentTarget.dataset.i,
            item = this.data.energyList[index],
            style = `energyList[${index}].styleObject`;
        // 158 是按钮的top加上高度的一半再减能量去的宽
        // 154 是按钮的left加上宽度的一半再减能量去的宽
        item.styleObject = item.styleObject.replace(item.top, 260)
        item.styleObject = item.styleObject.replace(item.left, 154)
        if (this.data.isClick > 10) {
            this.setData({
                energyList: []
            })
            return
        }
        this.gatherAn(item, style)
    },

    arredFn() {
        let index = this.trainFn(0, this.data.energyList.length - 1);
        if (this.data.arred.indexOf(index) == -1) {
            this.data.arred.push(index)
            this.data.isClick++
            return index
        } else {
            return this.arredFn()
        }
    },
    //点击按钮收取能量 
    pullAllEnergy() {
        if (this.data.isClick >= 10) return
        clearInterval(this.data.addTimer)
        let index = this.arredFn(),
            item = this.data.energyList[index],
            style = `energyList[${index}].styleObject`;
        item.styleObject = item.styleObject.replace(item.top, 260)
        item.styleObject = item.styleObject.replace(item.left, 154)
        this.gatherAn(item, style)
    },

    /**
     * 浇水
     */
    jiaoshui() {
        var that = this
        wx.showModal({
            title: '',
            content: '是否确认浇水',
            success(res) {
                if (res.confirm) {
                    if (that.data.sum < 10) {
                        wx.showToast({
                            title: '能量小于10',
                            icon: 'error',
                            duration: 2000
                        })
                    } else {
                        that.setData({
                            isShui: false,
                            sum: that.data.sum - 10
                        })
                        setTimeout(() => {
                            that.setData({
                                isShui: true
                            })
                        }, 5000)
                    }
                } else if (res.cancel) {
                    console.log('用户点击取消')
                }
            }
        })



    }
})

 最终效果:

 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

⁡⁢⁡⁢⁠Ac

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值