JavaScript 练手小技巧:打字小游戏
放假闲来无事,一群小屁孩想玩我的电脑。
字都不会打,还玩电脑。
用 js 写一个打字游戏,打不到 100 分,就不要玩我的电脑~~~!!!
整体界面如下所示,一切从简~
HTML 结构
<div id="box" class="box"><div class="tips">击中数量:<span id="scoreSpan" style="margin-right: 20px;">0</span>失误:<span id="missSpan">0</span></div><div class="container" id="container"></div><!-- 游戏结束标签 --><div class="gameover"><h1>游戏结束</h1><div class="overBtn"><button type="button" id="btn">重新开始</button></div></div>
</div>
div.container 是字母出现的区域,相对定位。
字母是 JS 动态生成的 span 标签,全部绝对定位。
div.gameover 是游戏结束时的画面,默认是隐藏的。当游戏结束的时候,给 div.box 添加一个类 over,才让 div.gameover 显示出来。
具体样式见下 CSS 样式部分。
CSS 样式
*{margin: 0;padding: 0;
}
div.box{width: 100vw;height: 100vh;position: relative;background:center center url("../images/mm.jpg") no-repeat;background-size: cover;
}
.tips{position: absolute;left:20px;top:20px;font-size: 20px;line-height: 40px;z-index: 2;
}
.tips span{font-size: 30px;color: #ff6600;vertical-align: middle;
}
.container{width: 100%;height: 100vh;position: relative;overflow: hidden;background: rgba(255,255,255,0.5);
}
.container span.zm{font-size: 40px;display: inline-block;padding: 5px 10px;height: 80px;line-height: 80px;overflow: hidden;position: absolute;
}
span.zm.shoot{animation: shootAni 0.2s;
}
@keyframes shootAni {0%{opacity: 1;transform: scale(1);}100%{opacity: 0;transform: scale(1.5);}
}
.gameover{position: absolute;left: 0;top:0;background: rgba(0,0,0,0.5);bottom:0;right:0;text-align: center;display: none;
}
.over .gameover{display: block;
}
.over .gameover h1{padding-top: 40vh;margin-bottom: 40px;
}
.over .gameover button{cursor: pointer;width: 100px;height: 50px;
}</style>
JavaScript 部分
字母是 26 个字母随机出现,因此利用一个字符串存储字母。
let zmStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
字母是随机生成的 span,span的内容就是随机字母。但是,字母不能跟已有的字母重复,因此要做一个重复性的判断。
判断的方式:先把已有的字母收集起来,形成一个字符串。随机字母的时候,就判断是否已经存在。如果存在,就重新随机选取字母。如果不存在,ok,就把这个字母放入span 中。
// 随机生成字母
let zmInStr =""; // 已有的字母
for(let i=0; i<=container.children.length-1; i++){zmInStr += container.children[i].innerText ;
}
let zmNow = zmStr[ Math.floor( Math.random()*zmStr.length) ];
// 防止字母重复
while( zmInStr.indexOf(zmNow) >= 0){zmNow = zmStr[ Math.floor( Math.random()*zmStr.length) ]
}
span.innerText = zmNow;
每个生成的字母,也就是 span,它的位置,速度都是随机的。
span.style.fontSize = (Math.random()*50+30)+"px";
span.style.color = fontColorArr[Math.floor(fontColorArr.length*Math.random())];
// 字母出现的位置
span.style.left = (80+Math.random()*(container.offsetWidth-160)) + "px";
span.style.top = `${60}px` ;
// 每个字母设置下落速度
span.speed = spDi+Math.random()*spCtr;
// 每个字母的下落距离
span.dis = 0;
当字母被击中,会执行一个 animation 动画。动画结束后,该字母span标签要被删除。所以,字母的span标签需要监听 animationend 事件。
// 添加动画事件
span.addEventListener("animationend",function () {// 当 animation 动画结束后,移除该字母container.removeChild(span);});
下坠动画部分。
利用的是 requestAnimationFrame ,每次执行动画先遍历所有字母 span。
获取每个 span 的速度 speed 和 移动的距离 dis。在当前 dis 上添加 speed 值,实现位置变化。
// 获取每个span的速度和位置
let speed = Number(span.speed);
let dis = Number(span.dis);
span.style.top = `${dis+speed}px`;
span.dis = `${dis+speed}`;
还要判断字母是否移动到了屏幕之外,这个时候说明字母没有被击中。要添加失误分。
// 判断字母是否在外面。
if( Number(span.dis) > Number(container.offsetHeight)+10){container.removeChild(span);createSpan();missScore++;missSpan.innerText = missScore;
}
当失误分超过10分的时候,游戏结束。
// 判断游戏是否结束:失误超过10次if(missScore>=10){cancelAnimationFrame(req);box.classList.add("over");return ;}
当用户击打键盘的时候,要判断按下的键是否在已有的字母中。
因此,要遍历字母 span 标签,判断按键是否跟其中的一个一致。
有,则这个字母被击中,添加击中动画 shoot,速度归零,再创建一个新的字母补位。得分+1 。
// 添加事件document.addEventListener("keyup",function (e) {console.info( e.code );let spans = container.getElementsByTagName("span");// 判断按键for(let i=0; i<spans.length ; i++){// 击中了字母:按下了正确的字母键if( "Key"+spans[i].innerText == e.code ){spans[i].classList.add("shoot"); // 击中字母spans[i].speed = 0; // 被击中的字母不再移动createSpan(); // 再生成一个字母// 得分score++;scoreSpan.innerText = score ;break;}}});
完整 JavaScript 代码如下:
let box = document.getElementById("box");let container = document.getElementById("container");let missSpan = document.getElementById("missSpan");let scoreSpan = document.getElementById("scoreSpan");let btn = document.getElementById("btn");let numZM = 5;let score = 0 ; // 得分let missScore = 0; // 失误let zmStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";let spCtr = 1; // 速度控制变量let spDi = 0.5;let req ; // 动画idlet fontColorArr = ["#ba300c","#057a7d","#b724c7","#8cc111"];// 创造一个字母function createSpan(){let span = document.createElement("span");span.className = "zm";// 随机生成字母let zmInStr =""; // 已有的字母for(let i=0; i<=container.children.length-1; i++){zmInStr += container.children[i].innerText ;}let zmNow = zmStr[ Math.floor( Math.random()*zmStr.length) ];// 防止字母重复while( zmInStr.indexOf(zmNow) >= 0){zmNow = zmStr[ Math.floor( Math.random()*zmStr.length) ]}span.innerText = zmNow;container.appendChild(span);span.style.fontSize = (Math.random()*50+30)+"px";span.style.color = fontColorArr[Math.floor(fontColorArr.length*Math.random())];// 字母出现的位置span.style.left = (80+Math.random()*(container.offsetWidth-160)) + "px";span.style.top = `${60}px` ;// 每个字母设置下落速度span.speed = spDi+Math.random()*spCtr;// 每个字母的下落距离span.dis = 0;// 添加动画事件span.addEventListener("animationend",function () {// 当 animation 动画结束后,移除该字母container.removeChild(span);});}// 移动函数function move(){let spans = container.children;for(let i=0; i<spans.length; i++){let span = spans[i];// 获取每个span的速度和位置let speed = Number(span.speed);let dis = Number(span.dis);span.style.top = `${dis+speed}px`;span.dis = `${dis+speed}`;// 判断字母是否在外面。if( Number(span.dis) > Number(container.offsetHeight)+10){container.removeChild(span);createSpan();missScore++;missSpan.innerText = missScore;}}// 判断游戏是否结束:失误超过10次if(missScore>=10){cancelAnimationFrame(req);box.classList.add("over");return ;}// 动画循环req = requestAnimationFrame(move);}// 初始化function initGame(){container.innerHTML = "";score = 0;scoreSpan.innerText = score ;missScore = 0;missSpan.innerText = missScore;box.classList.remove("over");// 初始生成字母for(let i=0; i<numZM; i++){createSpan()}move();}// 添加事件document.addEventListener("keyup",function (e) {console.info( e.code );let spans = container.getElementsByTagName("span");// 判断按键for(let i=0; i<spans.length ; i++){// 击中了字母:按下了正确的字母键if( "Key"+spans[i].innerText == e.code ){spans[i].classList.add("shoot"); // 击中字母spans[i].speed = 0; // 被击中的字母不再移动createSpan(); // 再生成一个字母// 得分score++;scoreSpan.innerText = score ;break;}}});// 重新开始游戏:btn.addEventListener("click",function(){initGame()});// 启动游戏initGame();
JavaScript 练手小技巧:打字小游戏相关推荐
- 天刀 服务器状态,天刀实用技巧_天刀各种游戏小技巧_玩游戏网
一:御风神行无CD小技巧 这个小技巧,是玩家们游戏方便的一大助力,毕竟它方便了几乎所有天刀玩家,在游戏中给玩家们创造了极大便利.就是当玩家角色走到地图的边缘空气墙处,自动蹦出来地图,点击传送点,可以无 ...
- rust原地复活_rust腐蚀游戏新手入门必知小技巧 Rust腐蚀游戏中的12个实用小技巧...
rust腐蚀游戏新手入门必知小技巧,想必还有很多小伙伴还不太了解,下面小编给大家带来了Rust腐蚀游戏中的12个实用小技巧,一起来看看吧. rust腐蚀游戏新手入门必知小技巧 Rust腐蚀游戏中的12 ...
- 《铁甲雄兵》小技巧介绍 梅花游戏视频网
小技巧介绍 大型军团竞技策略网游<铁甲雄兵>自不删档内测以来,聚集了大批人气,也吸引了无数萌新玩家加入,今天就为诸位萌新玩家整理了一大波新手必看的注意事项,千万不要错过呦! 本文转载自ww ...
- 51单片机可以用来练手的60个小设计
60个51单片机可以用来练手的小设计 最近题主在温习关于51的一些知识,所以自己在网上搜集了一些小设计感觉还可以,大家可以试一试做练手 同样的设计也可以为其他单片机提供一定的设计思路 1 电子秤设计: ...
- pyqt5练手项目-抖音小姐姐短视频下载
pyqt5=Python+ qt,这块的资料现在慢慢多起来了,这里给大家送一个小的demo用来练手. 里面技术点: 1)控件 Pushbutton的使用: 2)pyqt5线程的用法; 3)界面和逻辑分 ...
- C语言zh字符串指针的大小,C语言的一些小技巧,小知识
1.用if(!strcmp(s1, s2)) 比较两个字符串等值,是否是个好风格? 这并不是个很好的风格, 虽然这是个流行的习惯用法.如果两个字符串相等, 这个测试返回为真, 但! ("非& ...
- Javascript 练手小实验:秒表计时游戏
文章目录 一.说明 二.效果展示 三.代码 3.1 HTML 3.2 CSS 3.3 Javascript 一.说明 本游戏页面设计分为左右两栏.左上为跑马灯,左下为计时器和"STAR ...
- JavaScript 练手小技巧:页面高亮操作提示和蒙板
在页面上,有时候会遇到操作提示,如下图所示. 可以很直观的告诉用户,关键的操作在哪里,有什么做作用. 需要说明的是,被高亮的部分,并不是目标的真实标签,而是用的其他标签模拟的. 真实的标签被 mask ...
- JavaScript 练手小技巧:#RRGGBB 和 rgb(255,255,255)颜色代码相互转换
看到有人在 CSDN 上写颜色的转换代码,突发奇想,用 JavaScript 也写一个. 一.相关知识点 (1)常用颜色代码方式,有两种 #RRGGBB 和 rgb(255,255,255) 用 #R ...
最新文章
- echarts ucharts 和_使用chart和echarts制作图表
- Java -- 基于JDK1.8的LinkedList源码分析
- Java Scanner类
- GIS基本知识学习PDF文档
- i.mx6ul 移植Openwrt
- Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight respo
- [上海站] 微软Azure AspNetCore微服务实战
- windows安装MySQL数据库【附安装文档和安装包】
- coredump_filter的设置
- 【Kubernetes】Error: Cask minikube is unavailable No Cask with this name exists
- 金三银四 | 吃透这套题,面试更有底气
- 给萌新的Flexbox简易入门教程
- 哎呀!可能有弹出式窗口拦截器生成Gmail无法打开该网页。如果您使用弹出式窗口拦截器,请将其关闭以便打开窗口。...
- xmemcached的time out
- 微信小程序 访问locolhost_微信小程序 数据访问实例详解
- java怎么用unicode写程序_简单的讲解Java是使用Unicode字符集
- rollup打包压缩和去除注释等无效代码
- 如何将文件或文件夹加入杀毒软件白名单步骤
- 三角形的几何公式大全_解析几何(椭圆)常见二级结论92条附详细证明
- 瑞星千万巨款贿赂官员 制造冤狱铲除竞争对手图片
热门文章
- 一步到位,让你在手机上学会思维导图软件
- centos 7 安装RabbitMQ 3.8.18
- QQ游戏: 四国军棋和中国象棋客户端失败
- pcie转sata3硬盘不启动_minipcie固态硬盘8g系统加装sata硬盘系统启动不了。求大神解惑。...
- 使用地图设置 Use Map Settings
- python format用法详解
- 全球与中国LCP纤维市场现状及未来发展趋势
- 程序员那些牛逼闪闪的禁术,看到第二条我就忍不住哈哈哈哈哈哈哈哈
- 三坐标测量基础知识之测量误差与采点方法
- eclipse 安装反编译工具