放假闲来无事,一群小屁孩想玩我的电脑。

字都不会打,还玩电脑。

用 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 练手小技巧:打字小游戏相关推荐

  1. 天刀 服务器状态,天刀实用技巧_天刀各种游戏小技巧_玩游戏网

    一:御风神行无CD小技巧 这个小技巧,是玩家们游戏方便的一大助力,毕竟它方便了几乎所有天刀玩家,在游戏中给玩家们创造了极大便利.就是当玩家角色走到地图的边缘空气墙处,自动蹦出来地图,点击传送点,可以无 ...

  2. rust原地复活_rust腐蚀游戏新手入门必知小技巧 Rust腐蚀游戏中的12个实用小技巧...

    rust腐蚀游戏新手入门必知小技巧,想必还有很多小伙伴还不太了解,下面小编给大家带来了Rust腐蚀游戏中的12个实用小技巧,一起来看看吧. rust腐蚀游戏新手入门必知小技巧 Rust腐蚀游戏中的12 ...

  3. 《铁甲雄兵》小技巧介绍 梅花游戏视频网

    小技巧介绍 大型军团竞技策略网游<铁甲雄兵>自不删档内测以来,聚集了大批人气,也吸引了无数萌新玩家加入,今天就为诸位萌新玩家整理了一大波新手必看的注意事项,千万不要错过呦! 本文转载自ww ...

  4. 51单片机可以用来练手的60个小设计

    60个51单片机可以用来练手的小设计 最近题主在温习关于51的一些知识,所以自己在网上搜集了一些小设计感觉还可以,大家可以试一试做练手 同样的设计也可以为其他单片机提供一定的设计思路 1 电子秤设计: ...

  5. pyqt5练手项目-抖音小姐姐短视频下载

    pyqt5=Python+ qt,这块的资料现在慢慢多起来了,这里给大家送一个小的demo用来练手. 里面技术点: 1)控件 Pushbutton的使用: 2)pyqt5线程的用法; 3)界面和逻辑分 ...

  6. C语言zh字符串指针的大小,C语言的一些小技巧,小知识

    1.用if(!strcmp(s1, s2)) 比较两个字符串等值,是否是个好风格? 这并不是个很好的风格, 虽然这是个流行的习惯用法.如果两个字符串相等, 这个测试返回为真, 但! ("非& ...

  7. Javascript 练手小实验:秒表计时游戏

    文章目录 一.说明 二.效果展示 三.代码 3.1 HTML 3.2 CSS 3.3 Javascript 一.说明    本游戏页面设计分为左右两栏.左上为跑马灯,左下为计时器和"STAR ...

  8. JavaScript 练手小技巧:页面高亮操作提示和蒙板

    在页面上,有时候会遇到操作提示,如下图所示. 可以很直观的告诉用户,关键的操作在哪里,有什么做作用. 需要说明的是,被高亮的部分,并不是目标的真实标签,而是用的其他标签模拟的. 真实的标签被 mask ...

  9. JavaScript 练手小技巧:#RRGGBB 和 rgb(255,255,255)颜色代码相互转换

    看到有人在 CSDN 上写颜色的转换代码,突发奇想,用 JavaScript 也写一个. 一.相关知识点 (1)常用颜色代码方式,有两种 #RRGGBB 和 rgb(255,255,255) 用 #R ...

最新文章

  1. echarts ucharts 和_使用chart和echarts制作图表
  2. Java -- 基于JDK1.8的LinkedList源码分析
  3. Java Scanner类
  4. GIS基本知识学习PDF文档
  5. i.mx6ul 移植Openwrt
  6. Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight respo
  7. [上海站] 微软Azure AspNetCore微服务实战
  8. windows安装MySQL数据库【附安装文档和安装包】
  9. coredump_filter的设置
  10. 【Kubernetes】Error: Cask minikube is unavailable No Cask with this name exists
  11. 金三银四 | 吃透这套题,面试更有底气
  12. 给萌新的Flexbox简易入门教程
  13. 哎呀!可能有弹出式窗口拦截器生成Gmail无法打开该网页。如果您使用弹出式窗口拦截器,请将其关闭以便打开窗口。...
  14. xmemcached的time out
  15. 微信小程序 访问locolhost_微信小程序 数据访问实例详解
  16. java怎么用unicode写程序_简单的讲解Java是使用Unicode字符集
  17. rollup打包压缩和去除注释等无效代码
  18. 如何将文件或文件夹加入杀毒软件白名单步骤
  19. 三角形的几何公式大全_解析几何(椭圆)常见二级结论92条附详细证明
  20. 瑞星千万巨款贿赂官员 制造冤狱铲除竞争对手图片

热门文章

  1. 一步到位,让你在手机上学会思维导图软件
  2. centos 7 安装RabbitMQ 3.8.18
  3. QQ游戏: 四国军棋和中国象棋客户端失败
  4. pcie转sata3硬盘不启动_minipcie固态硬盘8g系统加装sata硬盘系统启动不了。求大神解惑。...
  5. 使用地图设置 Use Map Settings
  6. python format用法详解
  7. 全球与中国LCP纤维市场现状及未来发展趋势
  8. 程序员那些牛逼闪闪的禁术,看到第二条我就忍不住哈哈哈哈哈哈哈哈
  9. 三坐标测量基础知识之测量误差与采点方法
  10. eclipse 安装反编译工具