水果消消乐总结

简介: 项目介绍利用原生js实现,主要分为三个部分。导入图片 定义层级数 格式第一部分为格式的生成,定义层数,行数,列数,元素组数以及图片数组,动态生成div,把利用模板字符串图片插入到动态生成的div里,再利用随机数打乱排列。

文章目录


项目介绍

利用原生js实现,主要分为三个部分。


一,导入图片 定义层级数 格式

第一部分为格式的生成,定义层数,行数,列数,元素组数以及图片数组,动态生成div,把利用模板字符串图片插入到动态生成的div里,再利用随机数打乱排列。

  //导入图片 定义层级数 格式
    const imagesDate = [
        { img: './images/yingtao.png' },
        { img: './images/putao.png' },
        { img: './images/lizi.png' },
        { img: './images/菠萝.png' }]
    const size = 80//图片大小
    const rows = 6//行数
    const cols = 6//列数
    const delCount = 3//三个就消除
    const group = 4//一共有四组
    const cengCount = 5//层数有五层
    const cunArr = []//存储数据的数组
    const showDate = Array.from(new Array(delCount * group)).map(v => {
        return imagesDate.map(v => ({ ...v }))
    }).flat().sort(v => Math.random() - 0.5)// 算出图片总数然后用随机数打乱,flat把[[]]数组展开   随机0-0.5 缩小范围 sort() 方法对数组的项目进行排序。
    //1.利用多层for循环形成格式
    for (let cc = cengCount - 1; cc >= 0; cc--) {
        for (let i = 0; i < rows; i++) {
            for (let j = 0; j < cols; j++) {
                let pianyi = (cc + 1) % 2 === 0 ? size / 2 : 0 //设置层数偏移量,偶数层进行偏移
                //进行图片渲染
                let item = (Math.random() > 0.7 && showDate.pop()) //pop用完就删,当随机数大于0.7时,从renderData中取数组的最后一项,.pop的意思是取最后一项并从数组中移除该项
                item && cunArr.push(`<div class="item"   id="m${cc}-${i}-${j}"
                style="width:${size}px;height:${size}px;left:${size * j + pianyi}px;top:${size * i + pianyi}px;"><img src="${item.img}"/></div>`)
            }
        }
    }

二,计算遮罩部分

第二部分是给盖着的元素加阴影遮盖,利用for循环取出所有偶数层,判断此层的上一层是否有元素,如果有,就加遮盖,如果此层处于2,4,6 对比的处于1,3,5 判断四周是否有图片 如果有,就加遮盖 没有 就把遮盖移除

  //2.计算遮罩部分:在css定义一个class类,能标注暗色,判断是否需要添加class属性,利用classlist中的方法进行删除与添加class
    const checkDisabled = (items) => {
        (items || main.querySelectorAll('.item')).forEach((v, i) => {
            const arr = v.id.substring(1).split('-').map(v => Number(v))//把id取出来
            const isPy = (arr[0] + 1) % 2 === 0//还是偶数层偏移
            for (let i = arr[0] + 1; i <= cengCount - 1; i++) {//for循环,还是找
                const isPyB = (i + 1) % 2 === 0//所在的上一层处于第几层
                if (isPy === isPyB) {//身在不同层,但是坐标一样
                    const el = main.querySelector(`#m${i}-${arr[1]}-${arr[2]}`)//得到层数,后面依次为数组第二项,第三项
                    if (el) {//若是存在,则加遮盖
                        v.classList.add('disabled')
                        break;
                    }
                } else if (isPy && !isPyB) {//元素本身处于2,4,6  对比的处于1,3,5
                    if (![
                        `${i}-${arr[1]}-${arr[2]}`,
                        `${i}-${arr[1]}-${arr[2] + 1}`,
                        `${i}-${arr[1] + 1}-${arr[2]}`,
                        `${i}-${arr[1] + 1}-${arr[2] + 1}`//都为偏移量,就是周围的一圈图片
                    ].every(k => {//every一true全true 一false全false
                        return !main.querySelector('#m' + k) //k即为上述偏移量 (被遮住为false 加!)
                    })) {
                        v.classList.add('disabled')//如果为false 就加上disabled
                        break;
                    } else {
                        v.classList.remove('disabled')
                    }
                } else if (!isPy && isPyB) {//元素本身处于1,3,5  对比的处于2,4,6
                    if (![
                        `${i}-${arr[1]}-${arr[2]}`,
                        `${i}-${arr[1]}-${arr[2] - 1}`,
                        `${i}-${arr[1] - 1}-${arr[2]}`,
                        `${i}-${arr[1] - 1}-${arr[2] - 1}`
                    ].every(k => {
                        return !main.querySelector('#m' + k)
                    })) {
                        v.classList.add('disabled')
                        break;
                    } else {
                        v.classList.remove('disabled')
                    }
                }
            }
        })
    }

三,点击卡片进行消除计算

第三部分为元素的偏移与消除,当点击图片时,图片偏移到消除框里,同时要防止框内的元素重叠,当框内有三个相同的元素时,就消除,其他剩余的元素自动对齐

et move = (me) => {
        //下边框的右边距离 和上边距离
        let left = show.offsetLeft - main.offsetLeft
        let top = show.offsetTop - main.offsetTop
        if (!canMove || me.className.indexOf('disabled') >= 0) {
            return   //禁用的不能点击移动
        }
        canMove = false
        if (show.children.length > 0) {
            let el = show.lastElementChild
            left = el.offsetLeft + size   //防止框内的元素重叠
        }
        me.style.top = `${top + 4}px`
        me.style.left = `${left + 1}px`
        me.transitionNamesCount = 0  //计数,有俩个动画,执行两次
        me.ontransitionend = (e) => {
            me.transitionNamesCount++
            if (me.transitionNamesCount === 2) {
                moveEnd(me)
                canMove = true
            }
        }
    }
    for (let i = 0; i < cunArr.length; i++) {
        const me = main.children[i]
        me.addEventListener('click', () => {
            move(me)
        })
    }
    //转移节点
    const moveEnd = (me) => {
        me.ontransitionend = null
        me.setAttribute('onclick', '')
        me.style.top = 0
        show.appendChild(me)  //这就把上面的节点转移到下边
        const findResult = [...show.children].filter(v => v.innerHTML === me.innerHTML)//...先转为数组 filter(函数) 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
        if (findResult.length === 3) {
            findResult.forEach(v => {
                v.ontransitionend = () => {
                    show.removeChild(v); //动画完了以后 清除元素   但是  这样虽然清除了 元素  元素不能自动归位
                    [...show.children].forEach((v, i) => {//先转为数组再遍历
                        v.style.left = `${i * size + show.offsetLeft - main.offsetLeft}px`//归位 对齐
                    })
                }
                setTimeout(() =>  v.style.transform = 'scale(0)' )//动画消除
            })
        }
        setTimeout(() => {// setTimeout 多少秒后调用函数
            if (show.children.length > 6) {
                alert('小笨蛋,输了吧,重新开始吧')
                return location.reload()
            } else if (main.children.length === 0) {
                alert('恭喜你赢了')
                return location.reload()
            }
        }, 100)
        checkDisabled()
    }

遇到的问题以及解决方法

1,图片插入不成功

<img src="${item.img}"/>


在模板字符串最后边加个/


2,多个点击事件创建

先移除模板字符串中的点击事件,用addEventListener()方法进行创建点击事件

   for (let i = 0; i < cunArr.length; i++) {
        const me = main.children[i]
        me.addEventListener('click', () => {
            move(me)
        })
    }
 for (let i = 0; i < cunArr.length; i++) {
        const me1 = main.children[i]
        me1.addEventListener('click', mksound)
    }

3,函数无法调用

利用箭头函数进行调用

  for (let i = 0; i < cunArr.length; i++) {
        const me = main.children[i]
        me.addEventListener('click', () => {
            move(me)
        })
    }

4,元素点击时偏移出错

设置相对于元素所在框的位置


目录
相关文章
|
搜索推荐 测试技术 数据库
QPS、TPS、RT、并发数、吞吐量分别是什么意思
QPS、TPS、RT、并发数、吞吐量分别是什么意思
4094 0
|
存储 人工智能 数据处理
阿里云CTO周靖人:全面投入升级AI大基建
9月19日,在2024杭州云栖大会上,阿里云CTO周靖人表示,阿里云正在围绕AI时代,树立一个AI基础设施的新标准,全面升级从服务器到计算、存储、网络、数据处理、模型训练和推理平台的技术架构体系,让数据中心成为一台超级计算机,为每个AI和应用提供高性能、高效的算力服务。
23533 15
|
SQL JSON 安全
Spring Authorization Server OAuth2授权服务器配置详解
Spring Authorization Server OAuth2授权服务器配置详解
4023 0
|
10月前
|
存储 监控 安全
如何用二维码提升隐患排查治理效率
纸质记录方式已经难以适应企业对高效、安全管理的需求。通过微信+二维码的方式,可以实现高效、低成本的解决隐患排查管理的问题。无论是巡检人员还是工人都能扫码上报隐患信息,管理人员通过后台集中管理。这种方式不仅加快了隐患信息流转,还实现了从发现到解决的全过程无缝衔接,让隐患处理更快速。
如何用二维码提升隐患排查治理效率
|
10月前
|
机器学习/深度学习 文字识别 开发者
使用OCR库Pix2Text执行p2t.recognize()时出现list index out of range的错误信息(附有Pix2Text识别图片内容和laTex公式的代码)
有时候报错并不是你代码有问题,源码出错也是很常见的情况,比如之前使用mxgraph也出现了不知名bug,最后也是修改的源码解决的。有疑问欢迎交流~ 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
开发者 人工智能 自然语言处理
欢迎使用通义灵码
灵码使用指南!一键收藏。
145056 31
|
缓存 算法 架构师
京东面试:如何设计600Wqps高并发ID?如何解决时钟回拨问题?
资深架构师尼恩在其读者交流群中分享了关于分布式ID系统的设计与实现,特别是针对高并发场景下的解决方案。他强调了分布式ID系统在高并发核心组件中的重要性,并详细介绍了百度的UidGenerator,这是一个基于Snowflake算法改进的Java实现,旨在解决分布式系统中的唯一ID生成问题。UidGenerator通过自定义workerId位数和初始化策略,支持虚拟化环境下的实例自动重启和漂移,其单机QPS可达600万。此外尼恩的技术分享不仅有助于提升面试表现,还能帮助开发者在实际项目中应对高并发挑战。
京东面试:如何设计600Wqps高并发ID?如何解决时钟回拨问题?
|
数据可视化 算法 前端开发
基于python flask+pyecharts实现的中药数据可视化大屏,实现基于Apriori算法的药品功效关系的关联规则
本文介绍了一个基于Python Flask和Pyecharts实现的中药数据可视化大屏,该系统应用Apriori算法挖掘中药药材与功效之间的关联规则,为中医药学研究提供了数据支持和可视化分析工具。
554 2
|
数据可视化 算法 搜索推荐
再也不怕冒泡排序了,看完这篇Go语言详解就会了
再也不怕冒泡排序了,看完这篇Go语言详解就会了
4568 0
|
存储 关系型数据库 MySQL