【HTML】【休闲益智】躲包包小游戏( 找靓仔的捉迷藏小游戏

1,244 阅读3分钟

在正文的第一句加入“我正在参加「码上掘金挑战赛」详情请看:码上掘金挑战赛来了!

前言

《躲包包》:是一款 pc 端单机 html 捉迷藏小游戏,休闲娱乐游戏;无需键盘操作,同时需要耐心和眼力,琢磨变化多端的靓仔们;锻炼眼力的时刻到了,出发吧,找到躲起来的靓仔!
找到,靓仔躲藏失败,胜利 成功.gif
未找到,靓仔躲藏成功,失败
失败.gif

一、游戏介绍与规则

游戏介绍

本期出站的靓仔们名单:

(注:当前未获得靓仔们许可,属于光明正大把各位拉入靓仔名单的!)

靓仔南方者语录
战场小包单身仔 传送门
德育处主任gif动图之王 传送门
Captaincc能与掘友 “打” 成一片 传送门
摸鱼的春哥故事之王 传送门
掘金酱掘金最神秘的阿酱 传送门
努力的IT小胖子一直在 java 后端奋斗 传送门
翊君猫、诗歌与拍照 传送门
猪痞恶霸曾开发一款务农微信小程序 传送门
掘金Troy小厨神、DIV小能人 传送门

技术介绍

css + jq

游戏名称

《躲包包》

游戏规则

① 不限时间.(默认毫无难度)
② 分为四个等级:毫无难度、牛刀小试、熟能生巧、眼花缭乱
③ 仔细观察选择要找的靓仔,找到躲藏的位置 (小技巧课堂:仔细观察板块之间的变化,是一个很好的帮助!)

二、大体设计与代码讲解

大体设计

首先,提前把靓仔和数据准备好,做一个视觉上的九宫格(实际是一个一维数组);
图片自身旋转(花里胡哨)+图片位置移动的视觉效果(躲藏功能)
当前视觉上是,靓仔开始第一次躲藏后,实际上立马会回到原来的位置,只不过在视觉上形成了这种躲藏移动;因此,我们只需要进行记录最终被躲藏的位置即可。

代码讲解

由于代码也比较简单,而且也有注释;就直接上完整的代码啦~

<!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>
    <link rel="shortcut icon" href="./img/baobao.png">
    <script src="https://javadoc.nanfangzhe.cn/jquery.min.js"></script>

</head>

<body>
    <div class="v-title">
        <h1>躲包包</h1>
        <h3>当前模式:<span id="l-model" style="color: rgb(226, 184, 184);">毫无难度</span></h3>
        <div class="v-detail">
            <span style="color: white;">躲包包,类似于躲猫猫,找到正确躲藏的地方!赶紧出发吧!</span><br>
            <span>(ps:点击图片可跳转到对应靓仔的掘金首页)</span>
        </div>
    </div>
    <div class="v-body">
        <div class="v-game">
            <div class="v-img">
                <img src="https://game.nanfangzhe.cn/game/hide-bao-bao/./img/laonan.png" alt="掘金" onclick="openNanUrl(this)" data-id="0">
            </div>
            <div class="v-img">
                <img src="https://game.nanfangzhe.cn/game/hide-bao-bao/./img/laonan.png" alt="掘金" onclick="openNanUrl(this)" data-id="1">
            </div>
            <div class="v-img">
                <img src="https://game.nanfangzhe.cn/game/hide-bao-bao/./img/laonan.png" alt="掘金" onclick="openNanUrl(this)" data-id="2">
            </div>
            <div class="v-img">
                <img src="https://game.nanfangzhe.cn/game/hide-bao-bao/./img/laonan.png" alt="掘金" onclick="openNanUrl(this)" data-id="3">
            </div>
            <div class="v-img">
                <img src="https://game.nanfangzhe.cn/game/hide-bao-bao/./img/baobao.png" alt="战场小包" onclick="openNanUrl(this)" data-id="4">
            </div>
            <div class="v-img">
                <img src="https://game.nanfangzhe.cn/game/hide-bao-bao/./img/laonan.png" alt="掘金" onclick="openNanUrl(this)" data-id="5">
            </div>
            <div class="v-img">
                <img src="https://game.nanfangzhe.cn/game/hide-bao-bao/./img/laonan.png" alt="掘金" onclick="openNanUrl(this)" data-id="6">
            </div>
            <div class="v-img">
                <img src="https://game.nanfangzhe.cn/game/hide-bao-bao/./img/laonan.png" alt="掘金" onclick="openNanUrl(this)" data-id="7">
            </div>
            <div class="v-img">
                <img src="https://game.nanfangzhe.cn/game/hide-bao-bao/./img/laonan.png" alt="掘金" onclick="openNanUrl(this)" data-id="8">
            </div>
        </div>
        <div class="v-btn">
            <div onclick="gameStart()">
                开始游戏
            </div>
            <div onclick="changeBoy()">
                切换靓仔
            </div>
            <div onclick="changeLevel()">
                切换模式
            </div>
            <div onclick="openNanUrl(this)">
                看看作者
            </div>
        </div>
        <div class="alert"></div>
    </div>
    <!-- 信息弹窗框 (该初始模板来源地址:http://www.webkaka.com/tutorial/html/2021/1015185/)-->
    <div class="modal-dialog" id="modal-dialog">
        <div class="modal-header">
            <h2 id="modal-title">提示框标题</h2>
            <span class="btn-close" onclick="closeModal()">×</span>
        </div>
        <div class="modal-body">
            <p id="modal-content">内容</p>
        </div>
        <div class="modal-footer">
            <span class="btn" onclick="closeModal()">确定</span>
        </div>
    </div>
</body>
<style>
    .v-detail {
        font-size: small;
        color: #aaa;
    }
    /* 初始样式代码模板来源地址:http://www.webkaka.com/tutorial/html/2021/1015185  */
    
    .btn {
        cursor: pointer;
        background: #428bca;
        border: #357ebd solid 1px;
        border-radius: 3px;
        color: #fff;
        display: inline-block;
        font-size: 14px;
        padding: 8px 15px;
        text-decoration: none;
        text-align: center;
        min-width: 60px;
        position: relative;
        transition: color 0.1s ease;
    }
    
    .btn:hover {
        background: #357ebd;
    }
    
    .btn-close {
        cursor: pointer;
        color: #aaa;
        font-size: 30px;
        text-decoration: none;
        position: absolute;
        right: 5px;
        top: 0;
    }
    
    .btn-close:hover {
        color: #919191;
    }
    
    .modal-dialog {
        display: none;
        background: #fefefe;
        border: #333 solid 1px;
        border-radius: 5px;
        margin-left: -180px;
        margin-top: -50px;
        position: fixed;
        left: 50%;
        top: 30%;
        z-index: 11;
        width: 360px;
    }
    
    .alert {
        display: none;
        background: #9da2e3;
        color: #d6e74c;
        border: #323232 solid 1px;
        border-radius: 5px;
        margin-left: -75px;
        margin-top: -50px;
        position: fixed;
        left: 50%;
        width: 150px;
        font-weight: bold;
        font-size: large;
        height: 50px;
        line-height: 50px;
        align-items: center;
        top: 30%;
        z-index: 11;
    }
    
    .modal-body {
        padding: 20px;
    }
    
    .modal-header,
    .modal-footer {
        padding: 10px 20px;
    }
    
    .modal-header {
        border-bottom: #eee solid 1px;
    }
    
    .modal-header h2 {
        font-size: 20px;
    }
    
    .modal-footer {
        border-top: #eee solid 1px;
        text-align: right;
    }
    
    .dropdown-content {
        display: none;
        position: absolute;
        background-color: #f9f9f9;
        min-width: 200px;
        box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
        /* padding: 12px 16px; */
    }
    
    .dropdown:hover .dropdown-content {
        display: block;
    }
    
    .v-btn {
        margin: 16px;
        text-align: center;
        width: 200px;
        padding-left: 20px;
        display: initial;
    }
    
    .v-btn div:hover {
        background: #385f9e;
    }
    
    .v-btn div {
        /* padding: 10px; */
        margin-top: 20px;
        /* border: 1px solid rgb(29, 190, 37); */
        /* cursor: pointer; */
        cursor: pointer;
        text-decoration: none;
        background: #2f435e;
        color: #f2f2f2;
        padding: 10px 30px 10px 30px;
        font-size: 16px;
        font-family: 微软雅黑, 宋体, Arial, Helvetica, Verdana, sans-serif;
        font-weight: bold;
        border-radius: 3px;
        /* -webkit-transition: all linear 0.30s; */
        -moz-transition: all linear 0.30s;
        transition: all linear 0.30s;
    }
    
    .v-game {
        margin: 0 auto;
        /* left: 30%; */
        width: 500px;
    }
    
    .v-img {
        margin: 5px;
    }
    
    .v-img img {
        border: 1px solid #ccc;
        height: 145px;
        margin: 5px;
        width: 30%;
        float: left;
        box-sizing: border-box;
        padding: 10px;
        /* animation-name: trans-card;
        animation-duration: 2s; */
    }
    
    .game-trans {
        transition: transform 0.5s linear 0s;
    }
    
    .trans {
        animation: trans-card 2s linear infinite;
    }
    
    @keyframes trans-card {
        from {
            transform: rotatey(0deg);
        }
        to {
            transform: rotatey(360deg);
        }
    }
    
    .v-body {
        display: inline-block;
    }
    
    body {
        align-items: center;
        text-align: center;
        justify-content: center;
        min-height: 100vh;
        background: linear-gradient(-135deg, #c850c0, #4158d0);
    }
</style>
<script>
    var author = "2840793779295133";
    var commonPath = "https://game.nanfangzhe.cn/game/hide-bao-bao/";
    // var commonPath = "";
    var authorImg = commonPath + "./img/laonan.png";
    var imgPathList = [
        "./img/zhuren.png",
        "./img/captain.png",
        "./img/chunge.png",
        "./img/jiang.png",
        "./img/baobao.png",
        "./img/pang.png",
        "./img/yijun.png",
        "./img/zhu.png",
        "./img/troy.png",
    ];
    var juejinImg = commonPath + "./img/juejin.png";
    var showUrlPathList = [
        "2673620576140030", // zhuren
        "3052665287739005", // captain
        "1714893870865303", // chunge
        "1556564194374926", // jiang
        "4424090519078430", // laobao
        "3482892898169437", // pang
        "2964698339501816", // yijun
        "431430802343479", // zhu
        "1742053927312702", // troy
    ]
    var isStart = false;
    var baoPosition = 4;
    var imgPosition = 4;
    var tarnsSum = 5; // 切换多少次
    var isTrans = false; // 是否正在进行转中
    var level = 0; // 等级
    var levelMsgList = ["毫无难度", "牛刀小试", "熟能生巧", "眼花缭乱"];

    // 切换模式
    function changeLevel() {
        if (isStart || isTrans) { // 游戏已经开始,不可以再切换模式了
            return;
        }
        if (level == levelMsgList.length - 1) {
            level = 0;
        } else {
            level++;
        }
        // console.log(level)
        $("#l-model").html(levelMsgList[level]);
        // $('.alert').html(levelMsgList[level]).addClass('alert-success').show().delay(500).fadeOut();
        // $('<div>').appendTo('body').addClass('alert alert-success').html('操作成功').show().delay(1500).fadeOut();
    }


    // 切换靓仔
    function changeBoy() {
        if (isStart || isTrans) { // 游戏已经开始,不可以再切换靓仔了
            return;
        }
        var nodeList = document.getElementsByClassName("v-img");
        var ran = Math.floor(Math.random() * (9));
        while (ran == imgPosition) {
            ran = Math.floor(Math.random() * (9));
        }
        imgPosition = ran;
        nodeList[baoPosition].childNodes[1].src = commonPath + imgPathList[ran];
    }

    // 游戏开始
    function gameStart() {
        if (isTrans) {
            // 已经转着,等转完了才可以再点击
            return;
        }
        var nodeList = document.getElementsByClassName("v-img");
        // console.log(nodeList)
        // 节点长度
        var len = nodeList.length;
        for (var i = 0; i < len; i++) {
            var node = nodeList[i].childNodes[1];
            node.classList.add("trans");
            // console.log(nodeList[i])
            // console.log(node)
        }
        if (!isStart) { // 游戏未开始
            setTimeout(function() {
                for (var i = 0; i < len; i++) {
                    var node = nodeList[i].childNodes[1];
                    node.classList.remove("trans");
                    // if (i == baoPosition) {
                    node.src = juejinImg
                        // }
                }
                var node = nodeList[baoPosition].childNodes[1];
                node.src = juejinImg
            }, 1800);
            isTrans = true;
            var sum = tarnsSum + level * 3; // 进行多少次
            setTimeout(function() {
                moveImg(nodeList, sum, len);
            }, 2000);
        } else { // 如果游戏已经开始
            setTimeout(function() {
                for (var i = 0; i < len; i++) {
                    var node = nodeList[i].childNodes[1];
                    node.classList.remove("trans");
                    // if (i == baoPosition) {
                    node.src = authorImg;
                    // }
                }
                var node = nodeList[baoPosition].childNodes[1];
                node.src = commonPath + imgPathList[imgPosition];
            }, 1000);
            isStart = false;
        }
    }

    // 移动图片(img1和img2的互换)
    function moveImg(nodeList, sum, len) {
        var ran = Math.floor(Math.random() * (len));
        while (ran == baoPosition) {
            // 保证新的和旧的不一样
            ran = Math.floor(Math.random() * (len));
        }
        var nowPosition = baoPosition;
        if (ran % 2 == 0) {
            // 增加随机性,偶数时与答案的位置切换
            // 记录最终值(即答案)
            baoPosition = ran;
        } else {
            // 增加随机性,奇数时不与答案的位置切换
            while (nowPosition == baoPosition || nowPosition == ran) {
                // 保证新的和旧的不一样
                nowPosition = Math.floor(Math.random() * (len));
            }
        }

        var node1 = nodeList[ran].childNodes[1];
        var node2 = nodeList[nowPosition].childNodes[1];

        // console.log(ran, nowPosition, baoPosition);

        var t1 = node1.offsetTop;
        var l1 = node1.offsetLeft;
        var t2 = node2.offsetTop;
        var l2 = node2.offsetLeft;
        var moveX = Math.abs(l1 - l2); // 取绝对值
        var moveY = Math.abs(t1 - t2);
        var translate1 = "-webkit-transform:";
        var translate2 = "-webkit-transform:";
        var translate1;
        var translate2;
        if (l1 > l2) {
            translate1 += " translate(" + String(moveX) + "px,";
            translate2 += " translate(" + String(-moveX) + "px,";
        } else {
            translate1 += " translate(" + String(-moveX) + "px,";
            translate2 += " translate(" + String(moveX) + "px,";
        }
        node1.classList.add("game-trans");
        node2.classList.add("game-trans");

        if (t1 > t2) {
            translate1 += String(moveY) + "px);";
            translate2 += String(-moveY) + "px);";
        } else {
            translate1 += String(-moveY) + "px);";
            translate2 += String(moveY) + "px);";
        }
        node1.style.cssText = translate2;
        node2.style.cssText = translate1;
        setTimeout(function() {
            // 这里瞬间变回原来的位置,实际上是并没有变化的。
            // 主要是为了形成视觉上的切换,因此只需要记录最终位置即可。(即 baoPosition 的最终值)
            node1.classList.remove("game-trans");
            node2.classList.remove("game-trans");
            node1.style.cssText = "translate(0px,0px)";
            node2.style.cssText = "translate(0px,0px)";
        }, 500);
        sum--;
        if (sum > 0) {
            setTimeout(function() {
                moveImg(nodeList, sum, len);
            }, 1000 - level * 280);
        } else {
            isStart = true;
            isTrans = false; // 转完了
        }
    }


    // 打开对应找的掘金首页
    function openNanUrl(e) {
        // console.log(e)
        var id = e.getAttribute("data-id");
        if (!isStart) {
            if (baoPosition == id) {
                window.open('https://juejin.cn/user/' + showUrlPathList[imgPosition])
            } else {
                window.open('https://juejin.cn/user/' + author)
            }
        } else {
            gameOver(id);
        }
    }


    // 展开答案并且判断是否正确
    function gameOver(id) {
        // console.log(id)
        // console.log(baoPosition)
        gameStart();
        var titleValue, contentValue;
        if (baoPosition == id) {
            titleValue = "胜利!";
            contentValue = "恭喜你成功找到了该靓仔!<br>成功拿下!";
        } else {
            titleValue = "失败!";
            contentValue = "很抱歉,你找的是不够靓的作者。<br>该靓仔太狡猾了,他躲在了" + (baoPosition + 1) + "号位!";
        }
        showModalMsg(titleValue, contentValue);
        isStart = false;
    }
    // 关闭弹窗框
    function closeModal() {
        var modal = document.getElementById("modal-dialog");
        modal.style.display = "";
    }
    // 显示弹窗框
    function showModalMsg(titleValue, contentValue) {
        var title = document.getElementById("modal-title");
        title.innerText = titleValue;
        var content = document.getElementById("modal-content");
        content.innerHTML = contentValue;
        var modal = document.getElementById("modal-dialog");
        modal.style.display = "block";
    }
</script>

</html>

三、仓库地址与体验地址

  这里代码片段展示(手机端、pc 端都可放心食用 ~ )点击右上角可直达码上掘金!查看更完整的代码!
image.png

  大家可以直接来笔者的网站来体验
  在线体验(pc端):体验传送门
  仓库地址:暂无(想要的可以直接去扒笔者的网站传送门

文章小尾巴

文章写作、模板、文章小尾巴可参考:《写作“小心思”》
  感谢你看到最后,最后再说两点~
  ①如果你持有不同的看法,欢迎你在文章下方进行留言、评论。
  ②如果对你有帮助,或者你认可的话,欢迎给个小点赞,支持一下~
  我是南方者,一个热爱计算机更热爱祖国的南方人。

  (文章内容仅供学习参考,如有侵权,非常抱歉,请立即联系作者删除。)