在正文的第一句加入“我正在参加「码上掘金挑战赛」详情请看:码上掘金挑战赛来了!”
前言
《躲包包》:是一款 pc 端单机 html 捉迷藏小游戏,休闲娱乐游戏;无需键盘操作,同时需要耐心和眼力,琢磨变化多端的靓仔们;锻炼眼力的时刻到了,出发吧,找到躲起来的靓仔!
找到,靓仔躲藏失败,胜利
未找到,靓仔躲藏成功,失败
一、游戏介绍与规则
游戏介绍
本期出站的靓仔们名单:
(注:当前未获得靓仔们许可,属于光明正大把各位拉入靓仔名单的!)
靓仔 | 南方者语录 |
---|---|
战场小包 | 单身仔 传送门 |
德育处主任 | 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 端都可放心食用 ~ )点击右上角可直达码上掘金!查看更完整的代码!
大家可以直接来笔者的网站来体验
在线体验(pc端):体验传送门
仓库地址:暂无(想要的可以直接去扒笔者的网站传送门 )
文章小尾巴
文章写作、模板、文章小尾巴可参考:《写作“小心思”》
感谢你看到最后,最后再说两点~
①如果你持有不同的看法,欢迎你在文章下方进行留言、评论。
②如果对你有帮助,或者你认可的话,欢迎给个小点赞,支持一下~
我是南方者,一个热爱计算机更热爱祖国的南方人。
(文章内容仅供学习参考,如有侵权,非常抱歉,请立即联系作者删除。)