前言

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

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

游戏名称

花木兰:安能辨我是兔子

游戏规则(玩法)

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

二、大体设计与代码讲解

大体设计

  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,2function 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>

仓库地址与体验地址

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

以前的小游戏