写在开头
上期代码主要实现瀑布流功能,本期就来实现读心术小游戏,开发久了很多功能都是通过框架组件库来完成,但是如果组件满足不了开发需求,还需要开发人员手动封装组件,专门出这样一期文章,通过原生js实现一些特定功能,功能也比较简单,也是想借助这样一个简单的功能,然后来帮助大家了解我们JavaScript,培养程序思维,本期到此结束。
实现功能
主要是读心术小游戏,看起来很神秘,其实都是有js语句控制的,代码中有备注,就不一一讲解了
创建页面
javascript
<!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>读心术2</title>
<link rel="stylesheet" href="../css/index.css">
</head>
<body>
<!-- 外层容器 -->
<div class="container">
<!-- 左侧部分 -->
<div class="board">
<!-- 左上的魔盘 -->
<div class="panel">
<!-- 魔盘圆心 -->
<img src="../images/round.png" alt="魔盘圆心" class="result" id="initImg">
<!-- 显示最终结果的图片 -->
<img src="../images/values/0.png" style="opacity: 0" alt="结果图片" class="result" id="resultImg">
</div>
<!-- 左下的游戏说明 -->
<div class="tip">
<p>在心中任意选择一个两位数</p>
<p>(或者说,从10~99之间任意选择一个数)</p>
<p>把这个数字分别减去其十位数和个位数</p>
<p>(例如你选择的是71,那就:71-7-1=63)</p>
<p>在右边图表中找出与最后得出的数所相应的图形,并把这个图形牢记心中。</p>
<p>然后点击上方的阵型。</p>
<p>你会发现,阵型所显示出来的图形就是你刚刚心里记下的那个图形。</p>
</div>
</div>
<!-- 右侧部分,这一个部分的内容由 js 动态生成 -->
<div class="dictionary"></div>
</div>
<script src="../js/index.js"></script>
</body>
</html>
样式创建
javascript
/* 容器整体样式 */
.container{
width: 1000px;
height: 700px;
margin: 0 auto;
display: flex;
}
/* 容器左边的样式 */
.container .board{
width: 350px;
height: 100%;
}
/* 魔盘样式 */
.board .panel{
width: 100%;
height: 300px;
position: relative;
background: url('../images/bg.gif') no-repeat;
background-position: center;
}
/* 魔盘中心样式 */
.board .panel .result{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
/* 下方游戏说明样式 */
.board .tip p{
font-weight: 100;
text-align: center;
}
/* 右侧字典表样式 */
.container .dictionary{
width: 650px;
display: grid;
grid-template: repeat(20, 35px)/repeat(5, 130px);
grid-auto-flow: column;
font-weight: 100;
}
.container .dictionary .number{
display: inline-block;
width: 40px;
text-align: right;
margin-right: 10px;
}
.container .dictionary img{
height: 30px;
vertical-align: -5px;
}
逻辑实现
javascript
var maxImgIndex = 15; // 最大的索引值
var curTargetIndex = null; // 当前的索引
var isGameOver = false; // 游戏是否结束
// 封装两个 DOM 查询方法
function $(selector) {
return document.querySelector(selector);
}
function $$(selector) {
return document.querySelectorAll(selector);
}
// 获取 DOM 节点
var panel = $('.panel'); // 获取整个魔盘
var initImg = $('#initImg'); // 获取魔盘的圆心
var resultImg = $('#resultImg'); // 获取结果图片
var dictionary = $('.dictionary'); // 获取右侧的字典表
// Math.floor(Math.random() * 可能性数 + 第一个可能值)
// 1-10之间
// Math.floor(Math.random() * 10 + 1)
// 返回从 min 到 max 的随机数
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
// 初始化右侧的字典表
function init() {
// 需要随机选择一张 9 的倍数显示什么图片
curTargetIndex = getRandom(0, maxImgIndex); // 得到一个从 0 到 15 的随机数
// 首先清空上一次的字典表结果
dictionary.innerHTML = '';
// 生成这一次的字典表
// 一共是 100 张图片,如果是 9 的倍数,那么图片的索引应该为 curTargetIndex
// 否则的话就从 0~15 之间随便选择一张
for(var i=0; i<100; i++){
var imgIndex = null; // 用于存储图片的索引值
if(i % 9 === 0){
// 说明是 9 的倍数
imgIndex = curTargetIndex;
} else {
// 说明不是 9 的倍数,随便摇一张即可
imgIndex = getRandom(0, maxImgIndex);
}
dictionary.innerHTML += `
<div class="item">
<span class="number">${i}</span>
<span class="value">
<img src="../images/values/${imgIndex}.png"/>
</span>
</div>
`;
}
}
init();
// 接下来,我们需要绑定点击事件
panel.onclick = function(e){
if(isGameOver){
// 说明游戏结束,需要询问玩家是否再玩一遍,如果要,我就做一些初始化的工作
if(window.confirm('是否再玩一次?')){
init(); // 重新初始化魔盘
initImg.style.opacity = 1; // 显示魔盘圆心
resultImg.style.opacity = 0; // 隐藏结果图片
isGameOver = false;
// 接下来一步很关键,去除 transition 和 transform 都去除
// 并且还要删除 transitionend 事件,否则下一次游戏会直接触发 transitionend 事件
e.currentTarget.setAttribute('style', '');
panel.removeEventListener('transitionend', transitionendHandle)
}
} else {
// 如果进入到 else,我们就需要将结果给玩家显示出来
// 显示结果其实很简单,就是将魔盘圆心隐藏,将结果图片显示出来
// 但是我们需要旋转 1800 deg,有一点仪式感
e.currentTarget.style.transition = 'all 2s'
e.currentTarget.style.transform = 'rotate(1800deg)';
// 旋转完成后,我们就需要将魔盘圆心隐藏,将结果图片显示出来
// 通过 transitionend 事件,我们就可以知道旋转完了没有
panel.addEventListener('transitionend', transitionendHandle);
}
}
// 旋转完成后,要做的事情
function transitionendHandle(){
initImg.style.opacity = 0; // 将魔盘圆心修改为透明
resultImg.src = `../images/values/${curTargetIndex}.png`; // 设置结果图片
resultImg.style.opacity = 1; // 将结果图片显示出来
isGameOver = true;
}