likes
comments
collection
share

【HTML】【消失的花木兰】花木兰:三兔蹦迪走,安能辨我是兔子?

作者站长头像
站长
· 阅读数 24

我正在参加「兔了个兔」创意投稿大赛,详情请看:「兔了个兔」创意投稿大赛

前言

(改编)  某日,参军后的花木兰刚回到家乡,却不料遇上抓拿自己的官兵... 因此,花木兰变成兔子躲了起来,你能否找到躲起来的花木兰呢?一起来拭目以待...

一、游戏名称与游戏规则(玩法)

游戏名称

花木兰:安能辨我是兔子

游戏规则(玩法)

游戏的规则非常简单,游戏开始后,花木兰会变成兔子,会与另外两只一模一样的兔子进行交换位置。找到最后的花木兰所变的兔子的位置即可获胜!   玩法如图所示(会有背景声音,也可进行关闭声音。):

【HTML】【消失的花木兰】花木兰:三兔蹦迪走,安能辨我是兔子?

二、大体设计与代码讲解

大体设计

  1. 首先,找素材(图片和音频)。弄个背景图,这里选择青青草地。(让兔子在进行跳跃起来的时候,能达到合理)
  2. 我们曾经玩过躲包包的游戏,学习了互换位置的思路。我们在这个基础上实现平行移动互换位置,并且完成小幅度的跳跃即可。(代码中有注释)

代码讲解

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

<!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">
    <meta name="description" content="花木兰:安能辨我是兔子, 南方者">
    <meta name="keywords" content="花木兰:安能辨我是兔子, 南方者">
    <title>花木兰:安能辨我是兔子</title>
    <link rel="shortcut icon" href="./img/rabbit.png" size="32x32">
</head>

<body>
    <div class="head">
        <h1>花木兰:安能辨我是兔子</h1>
        <h1 style="color: red; cursor: pointer;" onclick="gameStart()">开始游戏</h1>
        <h3 onclick="changeBGM()">声音状态:<span id="bgmStatus">开启</span>(点击这里可关闭)</h3>
        <div style="font-size: medium; color: #919191;">(注意:背景声音会有些大。)</div>
    </div>
    <div class="game">
        <div class="rabbit" onclick="gameOver(0)">
            <div style="display: none;" class="v-talk">
                <img src="./img/talk.png" alt="">
            </div>
            <img class="i-rabbit" src="./img/rabbit.png" alt="" style="opacity: 1;">
        </div>
        <div class="rabbit" onclick="gameOver(1)">
            <div style="display: none;" class="v-talk">
                <img src="./img/talk.png" alt="">
            </div>
            <img class="i-rabbit" src="./img/rabbit.png" alt="" style="opacity: 1;">
        </div>
        <div class="rabbit" onclick="gameOver(2)">
            <div style="display: none;" class="v-talk">
                <img src="./img/talk.png" alt="">
            </div>
            <!-- <img src="./img/Mulan.png" alt="" id="mulan" style="opacity: 1;"> -->
            <!-- <img src="./img/rabbit.png" alt=""> -->
            <img class="i-rabbit" src="./img/rabbit.png" alt="" style="opacity: 1;">
        </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>

</html>
<script>
    var isPlayBgm = true;
    var talkList = document.getElementsByClassName("v-talk");
    // var mulan = document.getElementById("mulan");
    var imgList = document.getElementsByClassName('i-rabbit');
    var isStart = false;
    var isMove = false;
    var answer = getRan(); // 随机生成木兰的位置,0,1,2

    function getRan() {
        return Math.floor(Math.random() * 3);
    }
    imgList[answer].src = "./img/Mulan.png"; // 设置为木兰
    // console.log("init answer:", answer)
    // gameStart();
    function gameStart() {
        // console.log(mulan)
        // console.log("answer:", answer)
        if (isStart || isMove) {
            return;
        }
        var mulan = imgList[answer];
        isStart = true;
        isMove = true;
        var count = 1;
        talkList[answer].style.display = "";
        talkList[answer].style.opacity = 0.8;
        mulan.style.opacity = 1;
        playBGM('./mp3/change.mp3');
        // 播放木兰变身动画
        var interval = setInterval(() => {
            var opacity = mulan.style.opacity;
            // console.log(opacity);
            if (opacity <= 0) {
                window.clearInterval(interval)
                // 播放变身成兔子(“碰”的一声)
                changeBody();
                return;
            }
            opacity -= count * 0.28;
            // console.log(opacity, count);
            if (0.8 > opacity)
                talkList[answer].style.opacity = opacity;
            mulan.style.opacity = opacity;
            count++;
        }, 400);
    }

    function changeBody() {
        var mulan = imgList[answer];
        // console.log(mulan)
        setTimeout(() => {
            talkList[answer].style.display = "none";
        }, 200)
        setTimeout(() => {
            mulan.src = "./img/smoke.png";
            playBGM('./mp3/peng.mp3');
            mulan.style.opacity = 0.8;
        }, 300)
        setTimeout(() => {
            mulan.style.opacity = 1;
            mulan.src = "./img/rabbit.png";
            setTimeout(() => {
                move(5); // 移动5次
            }, 200);
        }, 800)
        changePointer(true);
    }

    // window.onload = function () { move(2); }

    function move(sum) {
        // 小兔跳动(移动)

        // moveOne(imgList[0], imgList[1]);
        var num = getRan();
        while (answer == num) {
            num = getRan();
        }
        moveOne(answer, num, sum);
    }

    function moveOne(p1, p2, sum) {
        var node1 = imgList[p1], node2 = imgList[p2];
        // console.log("p1:", p1, "p2:", p2, "answer:", answer)
        playBGM("./mp3/jump.mp3");
        var t1 = node1.offsetTop;
        var l1 = node1.offsetLeft;
        var t2 = node2.offsetTop;
        var l2 = node2.offsetLeft;
        // console.log(node1, node1.offsetLeft, node2, node2.offsetLeft)
        // console.log("l1:" + l1, "t1:" + t1, " --- ", "l2:" + l2, "t2:" + t2);
        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");
        // console.log(translate2, translate1)
        node1.style.cssText = translate2 + String(-100) + "px);"; // y轴进行范围性移动
        node2.style.cssText = translate1 + String(-100) + "px);";

        setTimeout(function () {
            node1.style.cssText = translate2 + String(0) + "px);";
            node2.style.cssText = translate1 + String(0) + "px);";
            sum--;
            setTimeout(function () {
                // 这里瞬间变回原来的位置,实际上是并没有变化的。
                // 主要是为了形成视觉上的切换,因此只需要记录最终位置即可。(即 anster 的最终值)
                node1.classList.remove("game-trans");
                node2.classList.remove("game-trans");
                node1.style.cssText = "translate(0px,0px)";
                node2.style.cssText = "translate(0px,0px)";
            }, 800);
            if (p1 == answer) {
                answer = p2;
            } else if (p2 == answer) {
                answer = p1;
            }
            if (sum < 0) {
                isMove = false;
                return;
            }
            var num1 = getRan();
            var num2 = getRan();
            while (num2 == num1) {
                num2 = getRan();
            }
            setTimeout(() => {
                moveOne(num1, num2, sum);
            }, 1000)
        }, 300);
    }


    function changePointer(isPointer) {
        var imgList = document.getElementsByTagName('img');
        // 图片是否变鼠标滑入变小手
        var txt = "";
        if (isPointer) {
            txt = "pointer";
        }
        for (img of imgList) {
            // console.log(img)
            img.style.cursor = txt;
        }
    }

    function playBGM(url) {
        if (!isPlayBgm) {
            // 当前不开启
            return;
        }
        //浏览器适用       
        contextClass = window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;
        try {
            var context = new contextClass();
            var source = null;
            var audioBuffer = null;
            function stopSound() {
                if (source) {
                    source.stop(0); //立即停止
                }
            }
            function playSound() {
                source = context.createBufferSource();
                source.buffer = audioBuffer;
                source.loop = false;
                source.connect(context.destination);
                source.start(0); //立即播放    
            }
            function initSound(arrayBuffer) {
                context.decodeAudioData(arrayBuffer, function (buffer) { //解码成功时的回调函数
                    audioBuffer = buffer;
                    playSound();
                }, function (e) { //解码出错时的回调函数
                    console.log('404', e);
                });
            }
            function loadAudioFile(url) {
                var xhr = new XMLHttpRequest(); //通过XHR下载音频文件
                xhr.open('GET', url, true);
                xhr.responseType = 'arraybuffer';
                xhr.onload = function (e) { //下载完成
                    initSound(this.response);
                };
                xhr.send();
            }
            //这里用来存储背景音乐的路径
            loadAudioFile(url);
        } catch (e) {
            console.log('无法找到音乐!');
        }
    }

    function changeBGM() {
        var bgmStatus = document.getElementById("bgmStatus");
        // console.log(bgmStatus);
        var txt = "";
        if (isPlayBgm) {
            isPlayBgm = false;
            txt += "关闭";
        } else {
            isPlayBgm = true;
            txt += "开启";
        }
        // console.log(txt)
        bgmStatus.innerHTML = txt;
    }

    // 展开答案并且判断是否正确
    function gameOver(id) {
        if (!isStart || isMove) { // 游戏未开始 或 正在跳动
            return;
        }
        var titleValue, contentValue;
        // console.log("end answer:", answer, id)
        if (answer == id) {
            playBGM("./mp3/victory.mp3")
            titleValue = "胜利!";
            contentValue = "恭喜你成功找到了变身的兔子!<br>成功拿下花木兰!";
        } else {
            playBGM("./mp3/defeat.mp3")
            titleValue = "失败!";
            var text = "";
            switch (answer) {
                case 0:
                    text = "第一个";
                    break;
                case 1: text = "中间";
                    break;
                case 2: text = "最后一个";
                    break;
            }
            contentValue = "很抱歉,你找的并不是花木兰。<br>花木兰太狡猾了,她躲在了" + text + "!";
        }
        showModalMsg(titleValue, contentValue);
        imgList[answer].src = "./img/Mulan.png";
        changePointer(false);
        isStart = false;
    }

    // 显示弹窗框
    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 = "";
    }


</script>
<style>
    .head {
        position: fixed;
        width: 100%;
        text-align: center;
    }

    .head h1 {
        font-size: -webkit-xx-large;
    }

    body {
        /* 背景图设置 */
        background: url("./img/bg.png") no-repeat center center;
        background-size: cover;
        background-attachment: fixed;
        margin: 0px;
    }

    body,
    html,
    .game {
        height: 100%;
        width: 100%;
        /* margin: 50px; */
    }

    .game {
        display: flex;
        justify-content: space-around;
    }

    .rabbit {
        display: flex;
        /* 垂直居中 */
        align-items: center;
        /* 水平居中 */
        justify-content: center;
        /* 文字居中 */
        text-align: center;
        height: 100%;
        width: 25%;
        /* background: #000; */
    }


    img {
        max-width: 100%;
        max-height: 100%;
    }

    .game-trans {
        transition: transform 0.5s linear 0s;
    }

    .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;
    }

    .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;
    }

    .btn-close {
        cursor: pointer;
        color: #aaa;
        font-size: 30px;
        text-decoration: none;
        position: absolute;
        right: 5px;
        top: 0;
    }

    .btn-close:hover {
        color: #919191;
    }

    .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;
    }

    .v-talk {
        position: fixed;
        z-index: 10;
        opacity: 0.8;
    }
</style>

仓库地址与体验地址

【HTML】【消失的花木兰】花木兰:三兔蹦迪走,安能辨我是兔子?

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

以前的小游戏

文章小尾巴

文章写作、模板、文章小尾巴可参考:《写作“小心思”》   感谢你看到最后,最后再说两点~  ①如果你持有不同的看法,欢迎你在文章下方进行留言、评论。  ②如果对你有帮助,或者你认可的话,欢迎给个小点赞,支持一下~   我是南方者,一个热爱计算机更热爱祖国的南方人。  (文章内容仅供学习参考,如有侵权,非常抱歉,请立即联系作者删除。)

转载自:https://juejin.cn/post/7188153510922289207
评论
请登录