【前端客栈】基于HTML、CSS、JavaScript的羊了个羊静态仿写页面小游戏

news2024/12/28 21:05:30

🏜哈喽,大家好,我是小浪。前段时间羊了个羊火遍了大江南北,大家是否都通过第二关了呢?哈哈,没关系,既然通不过,那咋们不如自己来做一个这样的羊了个羊的仿写页面,学会了赶紧拿去在同学面前展示展示;OK,接下来,我们开始仿写这种游戏规则模式,写一个我们自己做出来的游戏——🍅果了个果🍅;

💡声明:本游戏只涉及到一个html文件+几张图片即可完成,不要配置其他任何的东西,如果你在寻找简单好运行的代码,那么本文将是您的不二之选。

ed47cb6ef59648d1878ea99e91a67075.gif

🌄那么,学习制作这个游戏之前,你需要掌握前端三剑客的相关知识点:前端客栈。

🎑如果你之前掌握了相关前端的知识点,或者你大概只需要获取这个游戏的源码,知道如何给这个游戏换换背景,换换图片等,那么你可以直接翻到本篇博客最后获取源码即可,每个地方的细节博主都描述的很清楚哈!

📲目录

一、大概游戏思想

二、具体实现方法及代码

三、运行结果展示

四、完整代码


一、大概游戏思想

📠我们要制作的游戏规则很简单,就是仿照羊了个羊的规则,选取三个相同的图片就可以进行消除,用来放置图片的格子我这里给的是七个,如果填满了七个格子还没有进行消除的话那么游戏就失败了,进行一个"游戏失败"的弹窗提示。

🏟这里博主给的是20*20的方格,也就是可以放置四百个图片,那么图片太小的话我们不太看的清楚,这里我们可以设置成四个方格大小存放一张图片,那样就减少了存放图片的数量,同时游戏的界面也会更加好看,因为图片的尺寸要大一些,看起来也清楚许多。

二、具体实现方法及代码

首先我们需要创建一个坐标系:

        // 坐标系的创建
        let scene = document.querySelector(".scene");
        let obj = {};
        for (let i = 0; i < 20; i++) {
            for (let j = 0; j < 20; j++) {
                let block = document.createElement("div");
                block.className = "block";
                scene.appendChild(block);
                obj[j + "-" + i] = block;
            }
        }

设置背景:

可以根据自己的喜好来设置喜欢的背景颜色;

0630f01278534d6dab38642d785247b0.png

设置整体坐标系大小:

        .scene {
            width: 500px;
            height: 500px;
            margin: 0 auto;
        }

设置每个格子:

        .block {
            width: 25px;
            height: 25px;
            float: left;
            position: relative;
        }

设置7个格子用来存放选择的卡片:

a9e2112d259c432fa56cbb6a646336e6.png

        .choose {
            width: 357px;
            height: 51px;
            border-top: 1px solid red;
            border-left: 1px solid red;
            margin: 30px auto;

        }

注意这里用来存放卡片的格子我们首先构建的格子的上、左两条边的样式,还需要设置格子的右、下两条边的格式;

        .item {
            width: 50px;
            height: 50px;
            border-right: 1px solid red;
            border-bottom: 1px solid red;
            float: left;
            position: relative;

        }

设置卡片的样式:

        .card {
            width: 50px;
            height: 50px;
            background-color: rgb(23, 228, 43);
            position: absolute;
            left: 0;
            top: 0;
            border-bottom: 3px solid #1cd241;
            box-shadow: 0 0 3px #000;
            background-size: 70%;
            background-position: center;
            background-repeat: no-repeat;
            cursor: pointer;
        }

卡片的背景和底色我们都是可以调的,直接修改background-color:rgb()即可。

5ac3660701774a7c883534e086687b31.png

创建卡片的代码:

       // 创建卡片
        let cardarr = []; //放置所有卡片的数组
        function draw(level = 1) {
            let posarr = [];
            for (let i = 0; i < 20; i++) {
                posarr.push([]);
                for (let j = 0; j < 20; j++) {
                    posarr[i][j] = 0;
                }
            }

            for (let i = level; i < 19 - level; i++) {
                for (let j = 1; j < 10; j++) {
                    if (Math.random() < 0.2 && check(i, j, posarr)) {
                        posarr[i][j] = 1;
                        posarr[i][18 - j] = 1;
                    }
                }

            }
            for (let i = 0; i < 20; i++) {
                for (let j = 0; j < 20; j++) {
                    if (posarr[i][j] === 1) {
                        let card = document.createElement("div");
                        card.className = "card";
                        card.style.zIndex = 10 - level;
                        obj[j + "-" + i].appendChild(card);
                        cardarr.push(card);
                        // if (level > 1) {
                        //     let mask = document.createElement("div");
                        //     mask.className = "mask";
                        //     mask.style.zIndex = 10 - level;
                        //     obj[j + "-" + i].appendChild(mask);
                        // }
                    }

                }

            }
        }

我们这里设置的七个格子,也就是图片的叠加层数是七层,既然有叠加,所以我们需要渲染叠加的遮罩;

       // 渲染遮罩
        function renderMask() {
            let masks = document.querySelectorAll(".mask");
            for (let i = 0; i < masks.length; i++)
                masks[i].parentNode.removeChild(masks[i]);
            for (let i = 0; i < cardarr.length; i++) {
                let item = cardarr[i];
                let rect = item.getBoundingClientRect();
                let { x, y } = rect;
                let one = document.elementFromPoint(x, y);
                let two = document.elementFromPoint(x + 49, y);
                let three = document.elementFromPoint(x, y + 49);
                let four = document.elementFromPoint(x + 49, y + 49);
                if (!(item.isSameNode(one) && item.isSameNode(two) && item.isSameNode(three) && item.isSameNode(four))) {
                    let mask = document.createElement("div");
                    mask.className = "mask";
                    mask.style.zIndex = getComputedStyle(cardarr[i]).zIndex;
                    cardarr[i].parentNode.appendChild(mask);
                }
                cardarr[i].index = i;
            }
        }

style中代码:

        .mask {
            width: 50px;
            height: 50px;
            background-color: #000000ae;
            position: absolute;
            left: 0;
            top: 0;
        }

图片渲染:

        // 图片渲染
        let imgarr = [];
        for (let i = 0; i < cardarr.length / 3; i++) {
            let n = Math.floor(Math.random() * 10);
            imgarr.push(n);
        }
        let allimg = [...imgarr, ...imgarr, ...imgarr];
        allimg.sort(function () {
            if (Math.random() > 0.5) {
                return 1;
            }
            else {
                return -1;
            }
        });
        for (let i = 0; i < cardarr.length; i++) {
            cardarr[i].style.backgroundImage = "url(" + allimg[i] + ".png)";
            cardarr[i].n=allimg[i];
        }

触发点击事件:

       // 点击事件
        let choosedarr = [];
        let items = document.querySelectorAll(".item");
        scene.onclick = function (e) {
            if (e.target.className === "card") {
                let item = e.target;
                // 删除页面的卡片
                item.parentNode.removeChild(item);
                // 从cardarr当中也去进行删除
                cardarr.splice(item.index, 1);
                if(cardarr.length===0){
                    alert("游戏成功");
                    location.reload();
                }
                // 重新绘制所有的遮罩
                renderMask();
                // 将当前被删除的卡片对象添加到choosedarr中
                if(choosedarr.length===7){
                    alert("游戏失败");
                    location.reload();
                }
                choosedarr.push(item);
                choosedarr.sort((a,b)=>a.n-b.n);
                let count={};
                for(let i=0;i<choosedarr.length;i++){
                    if(!count[choosedarr[i].n]){
                        count[choosedarr[i].n]=1;
                    }else{
                        count[choosedarr[i].n]+=1;
                    }
                }
                for(let i in count){
                    if(count[i]===3){
                        let length=choosedarr.length;
                        for(let j=0;j<choosedarr.length;j++){
                            if(choosedarr[j].n==i){
                                choosedarr.splice(j,1);
                                j--;
                            }
                        }
                    }
                }
                // 向item中添加卡片标签
                for(let i=0;i<items.length;i++){
                    items[i].innerHTML="";
                }
                for (let i = 0; i < choosedarr.length; i++) {
                    items[i].appendChild(choosedarr[i]);
                }
            }
        }

三、运行结果展示

整体样式:

2c0af9018fd64b83b495924378f739ec.png

 消除展示:

f33c9c6524d94fdbb03438473dcba0e4.png

失败演示:

3a853980c9dc47deaff1e4fe86b2df14.png

四、完整代码

1、文件设置格式

把ylgy.html文件和10张图片都放到一个文件夹下面,注意图片的格式修改为数字.png;这样才能保证正常运行;

07e5231c2a614ee790d5c4cf36a50f88.png

如果你想修改图片的话,可以自行下载后放在该文件夹下面即可。

源码以及图片素材获取地址github:羊了个羊仿写页面;

源代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>羊了个羊</title>
    <style>
        body {
            background-color: rgb(31, 146, 199);
        }

        .scene {
            width: 500px;
            height: 500px;
            margin: 0 auto;
        }

        .block {
            width: 25px;
            height: 25px;
            float: left;
            position: relative;
        }

        .choose {
            width: 357px;
            height: 51px;
            border-top: 1px solid red;
            border-left: 1px solid red;
            margin: 30px auto;

        }

        .item {
            width: 50px;
            height: 50px;
            border-right: 1px solid red;
            border-bottom: 1px solid red;
            float: left;
            position: relative;

        }

        .card {
            width: 50px;
            height: 50px;
            background-color: rgb(23, 228, 43);
            position: absolute;
            left: 0;
            top: 0;
            border-bottom: 3px solid #1cd241;
            box-shadow: 0 0 3px #000;
            background-size: 70%;
            background-position: center;
            background-repeat: no-repeat;
            cursor: pointer;
        }

        .mask {
            width: 50px;
            height: 50px;
            background-color: #000000ae;
            position: absolute;
            left: 0;
            top: 0;
        }
    </style>
</head>

<body>
    <div class="scene">
    </div>
    <div class="choose">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
    <script>
        // 坐标系的创建
        let scene = document.querySelector(".scene");
        let obj = {};
        for (let i = 0; i < 20; i++) {
            for (let j = 0; j < 20; j++) {
                let block = document.createElement("div");
                block.className = "block";
                scene.appendChild(block);
                obj[j + "-" + i] = block;
            }
        }
        // 创建卡片
        let cardarr = []; //放置所有卡片的数组
        function draw(level = 1) {
            let posarr = [];
            for (let i = 0; i < 20; i++) {
                posarr.push([]);
                for (let j = 0; j < 20; j++) {
                    posarr[i][j] = 0;
                }
            }

            for (let i = level; i < 19 - level; i++) {
                for (let j = 1; j < 10; j++) {
                    if (Math.random() < 0.2 && check(i, j, posarr)) {
                        posarr[i][j] = 1;
                        posarr[i][18 - j] = 1;
                    }
                }

            }
            for (let i = 0; i < 20; i++) {
                for (let j = 0; j < 20; j++) {
                    if (posarr[i][j] === 1) {
                        let card = document.createElement("div");
                        card.className = "card";
                        card.style.zIndex = 10 - level;
                        obj[j + "-" + i].appendChild(card);
                        cardarr.push(card);
                        // if (level > 1) {
                        //     let mask = document.createElement("div");
                        //     mask.className = "mask";
                        //     mask.style.zIndex = 10 - level;
                        //     obj[j + "-" + i].appendChild(mask);
                        // }
                    }

                }

            }
        }
        for (let i = 7; i > 0; i--) {
            draw(i);
        }
        // 把多余的卡片删除
        let length = cardarr.length;
        for (let i = 0; i < length % 3; i++) {
            let card = cardarr.pop();
            card.parentNode.removeChild(card);
        }
        function check(i, j, posarr) {
            if (posarr[i][j - 1] || posarr[i - 1][j - 1] || posarr[i - 1][j] || posarr[i - 1][j + 1]) {
                return false;
            }
            else {
                return true;
            }
        }
        // scene.getboundingClientRect;
        // scene.isSameElement;
        // 渲染遮罩
        function renderMask() {
            let masks = document.querySelectorAll(".mask");
            for (let i = 0; i < masks.length; i++)
                masks[i].parentNode.removeChild(masks[i]);
            for (let i = 0; i < cardarr.length; i++) {
                let item = cardarr[i];
                let rect = item.getBoundingClientRect();
                let { x, y } = rect;
                let one = document.elementFromPoint(x, y);
                let two = document.elementFromPoint(x + 49, y);
                let three = document.elementFromPoint(x, y + 49);
                let four = document.elementFromPoint(x + 49, y + 49);
                if (!(item.isSameNode(one) && item.isSameNode(two) && item.isSameNode(three) && item.isSameNode(four))) {
                    let mask = document.createElement("div");
                    mask.className = "mask";
                    mask.style.zIndex = getComputedStyle(cardarr[i]).zIndex;
                    cardarr[i].parentNode.appendChild(mask);
                }
                cardarr[i].index = i;
            }
        }
        renderMask()
        // 图片渲染
        let imgarr = [];
        for (let i = 0; i < cardarr.length / 3; i++) {
            let n = Math.floor(Math.random() * 10);
            imgarr.push(n);
        }
        let allimg = [...imgarr, ...imgarr, ...imgarr];
        allimg.sort(function () {
            if (Math.random() > 0.5) {
                return 1;
            }
            else {
                return -1;
            }
        });
        for (let i = 0; i < cardarr.length; i++) {
            cardarr[i].style.backgroundImage = "url(" + allimg[i] + ".png)";
            cardarr[i].n=allimg[i];
        }
        // 点击事件
        let choosedarr = [];
        let items = document.querySelectorAll(".item");
        scene.onclick = function (e) {
            if (e.target.className === "card") {
                let item = e.target;
                // 删除页面的卡片
                item.parentNode.removeChild(item);
                // 从cardarr当中也去进行删除
                cardarr.splice(item.index, 1);
                if(cardarr.length===0){
                    alert("游戏成功");
                    location.reload();
                }
                // 重新绘制所有的遮罩
                renderMask();
                // 将当前被删除的卡片对象添加到choosedarr中
                if(choosedarr.length===7){
                    alert("游戏失败");
                    location.reload();
                }
                choosedarr.push(item);
                choosedarr.sort((a,b)=>a.n-b.n);
                let count={};
                for(let i=0;i<choosedarr.length;i++){
                    if(!count[choosedarr[i].n]){
                        count[choosedarr[i].n]=1;
                    }else{
                        count[choosedarr[i].n]+=1;
                    }
                }
                for(let i in count){
                    if(count[i]===3){
                        let length=choosedarr.length;
                        for(let j=0;j<choosedarr.length;j++){
                            if(choosedarr[j].n==i){
                                choosedarr.splice(j,1);
                                j--;
                            }
                        }
                    }
                }
                // 向item中添加卡片标签
                for(let i=0;i<items.length;i++){
                    items[i].innerHTML="";
                }
                for (let i = 0; i < choosedarr.length; i++) {
                    items[i].appendChild(choosedarr[i]);
                }
            }
        }


    </script>
</body>

</html>

🏖🏖OK,那么今天的前端知识分享就到这里啦,原来前端这么有意思,后续会持续更新,感谢关注;最近也是在做测开+Java方向的面试真题+投递链接,感兴趣的小伙伴可参考->

📑本专栏:大厂直通车!有任何问题可以下方VX联系到博主喔!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/480926.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文本中的关键词提取方法

目录 1. TF-IDF&#xff08;Term Frequency-Inverse Document Frequency&#xff09;算法&#xff1a; 2. TextRank算法&#xff1a; 3. LDA&#xff08;Latent Dirichlet Allocation&#xff09;算法&#xff1a; 4. RAKE&#xff08;Rapid Automatic Keyword Extraction&…

基于SLM调制器,MIT研发高效率全息显示方案

此前&#xff0c;青亭网曾报道过NVIDIA、三星、剑桥大学等对空间光调制器&#xff08;SLM&#xff09;全息方案的探索。空间光调制器可调节光波的空间分布&#xff0c;在电驱动信号控制下&#xff0c;可改变光在空间中传播的振幅、强度、相位、偏振态等特性&#xff0c;从而形成…

MySQL性能优化之(explain)工具

慢SQL的定位 在MySQL当中&#xff0c;我们有时候写的SQL执行效率太慢此时我们需要将其优化。但是SQL可能非常的多&#xff0c;难道我们一条一条的进行查看吗&#xff1f;在MySQL当当中我们可以查看慢查询日志&#xff0c;看看那些SQL这么慢。但是这个默认情况下这个慢查询日志…

sqoop使用

sqoop使用 1. 导入数据2. 从mysql向hive导入数据2.1 导入用户信息表 2.导入订单表2.2 导入订单表2.3 导入商品信息表2.4 导入国家信息表2.5 导入省份信息表2.6 导入城市信息表2.7 创建hive临时表文件 在使用sqoop之前&#xff0c;需要提前启动hadoop, yarn和对应的数据库mysql …

当音乐遇上Python:用Pydub自动分割音频

&#x1f3b5; &#x1f3b5; &#x1f3b5; 当音乐遇上Python&#xff1a;用Pydub自动分割音频 随着短视频应用的普及&#xff0c;越来越多人开始了解并尝试制作自己的短视频作品。而在制作短视频时&#xff0c;背景音乐的选择和使用也是非常重要的一步。很多人喜欢选择一首长…

倒立摆控制器的设计(分别用极点配置,LQR方法,Robust H-无穷方法)

G01倒立摆控制器设计 Author&#xff1a;DargonNote date&#xff1a;2020/12/13课程用书&#xff1a;LMIs in Control Systems Analysis,Design and Applications 1,倒立摆控制系统简介 倒立摆系统是一个复杂的控制系统&#xff0c;具有非线性、强耦合、多变量、不稳定等特…

干货 | 正念,寻求属于你的存在之道

Hello,大家好&#xff01; 这里是壹脑云科研圈&#xff0c;我是喵君姐姐~ 你是否也曾感到内心无法平静&#xff1f;如果是&#xff0c;不妨了解一下正念&#xff0c;它或许能为你带来改变。 正念作为一种古老的修行方式&#xff0c;如今已经在世界范围内广为流传&#xff0c;…

《Netty》从零开始学netty源码(四十九)之PoolArena

目录 PoolArenaallocate()创建newByteBuf()分配具体的内存空间allocate() PoolArena Netty中分配内存是委托给PoolArena来管理的&#xff0c;它主要有两个实现类&#xff1a; 默认情况下使用的DirectArena&#xff0c;它的数据结构如下&#xff1a; 从属性中我们看到PoolA…

人生若只如初见,你不来看看Django吗

前言 本文介绍python三大主流web框架之一的Django框架的基本使用&#xff0c;如何创建django项目&#xff0c;如何运行django项目以及django项目的目录结构&#xff0c;另外django又是如何返回不同的数据和页面&#xff1f; python三大主流web框架 Python有三大主流的web框架…

JS手写实现Promise.all

Promise.all() 方法接收一个 Promise 对象数组作为参数&#xff0c;返回一个新的 Promise 对象。该 Promise 对象在所有的 Promise 对象都成功时才会成功&#xff0c;其中一个 Promise 对象失败时&#xff0c;则该 Promise 对象立即失败。 本篇博客将手写实现 Promise.all() 方…

用于scATAC-seq有监督分类的Cellcano

细胞类型识别是单细胞数据分析的基本步骤。由于高质量参考数据集的可用性&#xff0c;有监督细胞分类方法在scRNA-seq数据中很受欢迎。染色质可及性分析&#xff08;scATAC-seq&#xff09;的最新技术进步为理解表观遗传异质性带来了新的见解。随着scATAC-seq数据集的不断积累&…

第二节课 Linux和shell命令之文件管理与常用命令

命令执行&#xff0c;没有图形页面 文件权限是重点 1.目录树 windous分盘 CDEF 在Linux系统中并不存在C/D/E/F等盘符&#xff0c;Linux系统中的一切文件都是 从“根&#xff08;/&#xff09;”目录开始的&#xff0c;并按照文件系统层次化标准&#xff08;Filesystem Hie…

C++:计算机操作系统:多线程:高并发中的线程

高并发中的线程 一切要从CPU说起PC 程序计数器从CPU到操作系统从进程到线程 从这篇开始&#xff0c;我将会开启高性能&#xff0c;高并发系列&#xff0c;本篇是给系列的开篇&#xff0c;主要关注 多线程以及线程池。 一切要从CPU说起 你可能会有疑问&#xff0c;讲多线程为何…

西门子AmeSim车辆仿真软件在新能源汽车开发中的应用-软件AmeSim2021版分享

利用Simcenter Amesim提高系统仿真产品设计效率&#xff0c;Simcenter Amesim是一个全球领先的集成、可扩展的机、电、液系统仿真平台。它允许设计工程师虚拟评估和优化系统性能。 提高系统仿真效率 Simcenter Amesim是一个领先的集成、可扩展的系统仿真平台&#xff0c;允许…

汇编语言学习笔记一

常用寄存器类型 通用寄存器 AX&#xff0c;BX&#xff0c;CX&#xff0c;DX&#xff0c;这四个寄存器都是16位的 他们也可以拆分为2个8位的寄存器&#xff0c;如AX可以拆分为AH和AL两个8位的寄存器&#xff0c;其它三个也可以如此。 通用寄存器的使用比较简单&#xff0c;如 …

【HTML5笔记】HTML5语义化标签、音视频标签、表单标签属性

目录 一、HTML5学习 1.1、HTML5语法 1.2、语义化标签 1.3、音视频标签 &#xff08;1&#xff09;音频标签 &#xff08;2&#xff09;视频标签 1.4、input标签type属性 1.5、datalist数据列表 1.6、表单属性 一、HTML5学习 1.1、HTML5语法 HTML5增加了很多的新标签…

【SpringBoot】自定义策略的静态资源访问

文章目录 新建static文件夹&#xff0c;存储图片等资源方式一 Java编码定义方式二 配置中定义 新建static文件夹&#xff0c;存储图片等资源 项目版本信息&#xff1a;SpringBoot版本为2.3.3.RELEASE&#xff0c;JDK1.8 方式一 Java编码定义 配置类实现WebMvcConfigurer接口&…

【五一创作】spring boot starter 编写自己的starter

spring boot starter 编写自己的starter 陈钊 2023-5-1 源码地址&#xff1a; https://gitcode.net/qq_39339588/my-spring-boot-starter.git 封装my-spring-boot-starter 新建springboot工程&#xff0c;来封装为自己的spring-boot-starter 包名&#xff0c;随便写&#xff0…