【HTML】【休闲益智】真相?真香?只有一个!看看谁是大馋虫 or 贪吃鬼(找出真正吃了月饼的人

1,209 阅读3分钟

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

前言

  在上一篇《躲包包》的小游戏中,很多掘友就不满意啦,怎么有我这个靓仔,怎么没我这个靓仔,怎么没我这个靓妹!这次,每个人都可以当靓仔靓妹参与进来了呢!
  首先,所有数据是来源笔者掘金里的粉丝用户!怎么能亏待 “范斯(粉丝)” 呢!看看谁才是大馋虫!

一、游戏介绍与规则

游戏介绍

随机出现9只馋虫,月饼即将在他们之间游走,找到最终落入大馋虫手里的!
大馋虫-成功.gif
本期出演的馋虫:所有粉丝

技术介绍

css + jq

游戏名称

《找到大馋虫》

游戏规则

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

二、大体设计与代码讲解

大体设计

首先,提前把馋虫相关的数据准备好(2022年9月9日的),做一个视觉上的九宫格(实际是一个一维数组);
月饼位置移动的视觉效果(月饼游走功能)
也可自定义成为馋虫!

代码讲解

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

<!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="https://p3-passport.byteimg.com/img/user-avatar/db3b09f9ca107d8843cee3fe8f4f0cd4~100x100.awebp">
    <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-cake" id="moon-cake">
            <img src="./img/moon-cake1.png" width="60px" height="60px" alt="月饼" onclick="changeCake(this)" style="margin-top: 8px;">
        </div>
        <div id="v-game">
        </div>
        <div class="v-btn">
            <div onclick="gameStart()">
                开始游戏
            </div>
            <div onclick="changeBoy()">
                换波靓仔
            </div>
            <div onclick="changeBoss()">
                自定主角
            </div>
            <div onclick="changeLevel()">
                切换模式
            </div>
            <div onclick="window.open('https\://juejin.cn/user/2840793779295133')">
                看看作者
            </div>
        </div>
        <div class="alert"></div>
    </div>
    <!-- 表单提交 -->
    <div class="wrapper" id="edit-dialog">
        <div class="modal-header">
            <h2 id="edit-title">提示框标题</h2>
            <span class="btn-close" onclick="closeModal()">×</span>
        </div>
        <div class="input-data">
            <input id="edit-head" type="text" required="" />
            <div class="underline"></div>
            <label>请输入头像链接(如:nanfangzhe.cn/xxx.png)</label>
        </div>
        <div class="input-data">
            <input id="edit-url" type="text" required="" />
            <div class="underline"></div>
            <label>请输入跳转首页(如:nanfangzhe.cn)</label>
        </div>
        <div class="modal-footer">
            <span class="btn" onclick="reset()">清空</span>
            <span class="btn" onclick="sumbit()">确定</span>
        </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>
<link rel="stylesheet" href="./index.css">
<script>
    var isStart = false; // 是否已经开始
    var isMove = false; // 是否正在移动
    var level = 0; // 等级
    var levelMsgList = ["毫无难度", "牛刀小试", "熟能生巧", "眼花缭乱"];

    // 切换模式
    function changeLevel() {
        if (isStart || isMove) { // 游戏已经开始,不可以再切换模式了
            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();
    }

    var vGame = document.getElementById("v-game");
    // console.log(vGame1)
    // var vGame = vGame1[0]
    // console.log(vGame)
    // 传入需要创建的element,并添加需要初始化的相关内容
    function getInitElement(name) {
        var element = document.createElement(name);
        // 注:IE浏览器不支持一下添加多个class
        element.classList.add("v-img"); // 公共化
        element.ondragstart = function() {
            return false
        }; // 禁止图片拖拽移动在新窗口打开
        return element;
    }
    // div.innerText = "66666";
    // console.log(div)
    // console.log(vGame)
    // vGame.appendChild(div)
    // console.log(vGame)

    // 随机获取一组不重复数字的数组
    function getRandomNum(needSum, numSum) {
        let ranList = []; //生成的随机数组
        if (!numSum || !needSum) {
            // 需要两个参数,否则直接返回
            console.log("随机生成数,缺少参数!")
            return;
        }
        while (ranList.length < needSum) {
            let num = Math.floor(Math.random() * numSum);
            while (ranList.indexOf(num) == -1) {
                ranList.push(num)
            }
        }
        return ranList;
    }

    var author = {
        "name": "\n    南方者\n  ",
        "url": "https://juejin.cn/user/2840793779295133",
        "head": "https://p3-passport.byteimg.com/img/user-avatar/db3b09f9ca107d8843cee3fe8f4f0cd4~100x100.awebp",
        "detail": "\n              程序员南方者 @微信公众号\n            "
    }
    var fans;
    // 获取粉丝的数据(已提前保存相关内容)
    $.getJSON("https://game.nanfangzhe.cn/game/find-glutton/./nanfangzhe-fans-20220909.json", function(data) {
        // console.log(fans)
        fans = data;
        var ranList = getRandomNum(9, 88);
        for (var i in ranList) {
            // 遍历随机的粉丝靓仔靓妹
            var fan;
            if (i != 4) {
                fan = fans[ranList[i]];
            } else {
                fan = author;
            }
            // console.log(fan)
            saveFan(fan, vGame, i);
        }
    });

    // 切换靓仔(换一拨靓仔)
    function changeBoy() {
        if (isStart) { // 游戏开始不可换
            return;
        }
        // console.log(fans)
        var ranList = getRandomNum(9, 88);
        var nodeList = document.getElementsByClassName("v-img");
        // console.log(nodeList)
        for (var i in nodeList) {
            if (i == 4) { // 主要 c 位不可换
                continue;
            }
            var div = nodeList[i];
            var img = div.children;
            if (!div || !img) {
                continue;
            }
            // console.log(img)
            var fan = fans[ranList[i]];
            const url = String(fan.url);
            // console.log(url)
            if (!img[0]) {
                continue;
            }
            // console.log(img)
            img[0].src = fan.head;
            img[0].alt = fan.detail;
            img[0].title = fan.name;
            div.onclick = function() {
                openUrl(url, i);
            }
        }
    }



    // 保存粉丝到盒子里
    function saveFan(fan, vGame, id) {
        var div = getInitElement("div");
        var img = document.createElement("img");
        var url = fan.url;
        var msg = fan.detail;
        var name = fan.name;
        img.src = fan.head;
        img.classList.add("v-img-tarns");
        img.alt = msg;
        img.title = name;
        div.style.cursor = "pointer";  // 鼠标滑入能变小手
        // console.log(url)
        div.onclick = function() {
            openUrl(url, id);
        }
        div.appendChild(img);
        vGame.appendChild(div);
    }

    // 去除前后空格、回车
    function Trim(str) {
        return str.replace(/(^\s*)|(\s*$)/g, "");
    }

    // 自定主角
    function changeBoss() {
        if (isStart) {
            return;
        }
        // var childNodes = vGame.children;
        // console.log(childNodes[4])
        var titleValue = "自定义主角";
        var contentValue = "";
        editModalMsg(titleValue, contentValue);
    }

    // 编辑框
    function editModalMsg(titleValue, contentValue) {
        if (isStart) {
            return;
        }
        var title = document.getElementById("edit-title");
        title.innerText = titleValue;
        var modal = document.getElementById("edit-dialog");
        modal.style.display = "block";
    }


    // 自定义的链接
    var url = document.getElementById("edit-url");
    // 自定义的头像
    var head = document.getElementById("edit-head");

    // (确定)提交表单
    function sumbit() {
        if (isStart) {
            return;
        }
        var headValue = head.value;
        var urlValue = url.value;
        var children = vGame.children[4];
        if (headValue) {
            var img = children.children[0];
            img.src = headValue;
            img.alt = "自定义主角";
            img.title = "自定义主角";
        }
        if (urlValue) {
            children.onclick = function() {
                openUrl(url, 4);
            }
        }
        closeEditodal();
    }

    // 打开馋虫对应的掘金页面
    function openUrl(url, id) {
        if (!isStart) {
            window.open(url);
            return;
        }
        if (isMove) { // 还在移动中,不可结束
            return;
        }
        // 游戏已经开始
        // console.log(id, moonCakePosition)
        gameOver(id)

    }

    // 展开答案并且判断是否正确
    function gameOver(id) {
        var node = document.getElementsByClassName("v-img")[moonCakePosition];
        node.children[0].classList.remove("v-img-tarns");
        var titleValue, contentValue;

        // console.log(node)
        if (moonCakePosition == id) {
            titleValue = "胜利!";
            contentValue = "恭喜你成功找到了该大馋虫!<br>成功拿下!";
        } else {
            titleValue = "失败!";
            contentValue = "很抱歉,你找到不是大馋虫。<br>该大馋虫太狡猾了,他是" + (moonCakePosition + 1) + "号位!";
        }
        setTimeout(function() {
            showModalMsg(titleValue, contentValue);
            isStart = false;
        }, 300);
    }
    // 显示弹窗框
    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";
    }

    // 关闭弹窗框
    function closeModal() {
        var modal = document.getElementById("modal-dialog");
        modal.style.display = "";
    }
    // 关闭弹窗框
    function closeEditodal() {
        var modal = document.getElementById("edit-dialog");
        modal.style.display = "";
    }
    // 清空
    function reset() {
        url.value = "";
        head.value = "";
    }

    var cakeNum = 0;
    changeCake();
    // 切换月饼
    function changeCake(e) {
        if (isStart) {
            return;
        }
        e = e || document.getElementById("moon-cake").children[0]
        let num = Math.floor(Math.random() * 4) + 1;
        while (cakeNum == num) {
            num = Math.floor(Math.random() * 4) + 1;
        }
        cakeNum = num;
        var url = "https://game.nanfangzhe.cn/game/find-glutton/./img/moon-cake" + num + ".png";
        e.src = url;
        // console.log(url)
        // console.log(e)
    }

    // 月饼在的位置
    var moonCakePosition = 4;

    // 大馋虫吃月饼了
    function gameStart() {
        if (isStart || isMove) {
            return;
        }
        isStart = true;
        isMove = true;
        var moonCake = document.getElementById("moon-cake");
        var children = vGame.children[moonCakePosition].childNodes[0];
        children.classList.add("v-img-tarns");

        // console.log(children)
        // console.log(moonCake, children);
        moveMoonCake(moonCake, children);
        var sum = 5;
        setTimeout(function() {
            forLoop(moonCake, sum);
        }, 1000 + (500 - 50 * level));
    }

    function forLoop(moonCake, sum) {
        var ran = Math.floor(Math.random() * (9));
        while (ran == moonCakePosition) {
            // 保证新的和旧的不一样
            ran = Math.floor(Math.random() * (9));
        }
        moonCakePosition = ran;
        moveMoonCake(moonCake, vGame.children[ran].childNodes[0], sum);
    }



    // 移动月饼
    function moveMoonCake(moonCake, person, sum) {
        var t1 = person.offsetTop;
        var l1 = person.offsetLeft;
        var h1 = person.offsetHeight;
        var h2 = moonCake.offsetHeight;
        var w1 = person.offsetWidth;
        var w2 = moonCake.offsetWidth;
        var t2 = moonCake.offsetTop;
        var l2 = moonCake.offsetLeft;
        // console.log(t1, t2);
        // console.log(l1, l2);
        // console.log(h1, h2);
        var moveX = Math.abs(l1 - l2 - Math.abs(w2 - w1) / 2); // 取绝对值
        var moveY = Math.abs(t1 - t2 + Math.abs(h2 - h1) / 2);
        var translate1 = "-webkit-transform:";
        // var translate2 = "-webkit-transform:";
        if (l1 > l2) {
            translate1 += " translate(" + String(-moveX) + "px,";
            // translate2 += " translate(" + String(0) + "px,";
        } else {
            translate1 += " translate(" + String(-moveX) + "px,";
            // translate2 += " translate(" + String(0) + "px,";
        }
        // person.classList.add("game-trans");
        moonCake.classList.add("game-trans");

        if (t1 > t2) {
            translate1 += String(moveY) + "px);";
            // translate2 += String(0) + "px);";
        } else {
            translate1 += String(-moveY) + "px);";
            // translate2 += String(0) + "px);";
        }
        translate1 += " transition: transform " + (1 - 0.25 * level) + "s linear 0s;";
        moonCake.style.cssText = translate1;
        // person.style.cssText = translate2;
        if (sum == undefined) {
            return;
        }
        sum--;
        if (sum > 0) {
            var ran = Math.floor(Math.random() * (9));
            while (ran == moonCakePosition) {
                // 保证新的和旧的不一样
                ran = Math.floor(Math.random() * (9));
            }
            moonCakePosition = ran;
            setTimeout(function() {
                moveMoonCake(moonCake, vGame.children[ran].childNodes[0], sum);
            }, 1000 + (600 - 400 * level));
        } else {
            // 移动完成
            isMove = false;
            // console.log(moonCakePosition)
        }
    }
</script>

</html>

三、仓库地址与体验地址

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

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

文章小尾巴

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

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