前言

  • 课程实验要求,迫不得已看了一点javascript,实现这个类似“节奏大师”的小游戏,有计时,计分,对玩家成绩进行排序的小功能,感觉自己审美还是不行,还有感觉自己写的javascript好丑陋,没有数据结构的味道。

  • 遇到卡壳的问题:javascript选择伪元素::after,代码中我用::after表示QWER四个键,js无法选择到伪元素,通过设置如下css代码,然后var crack = document.getElementsByClassName(‘crack’)[0]; 之后crack就是伪元素.crack::after。

    .crack {pointer-events: none;
    }/*伪元素样式*/
    .crack::after {pointer-events: auto;
    }
    
  • 用到javascript知识:Dom,键盘事件,定时器等等=.=

效果

Code

html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Game</title><link rel="stylesheet" href="src/css/play.css">
</head><body><div id="game-box"><div class="game-name"><span>游戏名: <span style="color: red;">节奏大师简化版</span></span>&nbsp&nbsp&nbsp<span>游戏时间:<span class="time"></span></span>&nbsp&nbsp&nbsp<span>积分:<span class="sorce">0</span></span>&nbsp&nbsp&nbsp<button onclick="gameTime()">开始游戏</button></div><div class="crack-box"><!-- 四个轨道 --><div class="crack"></div><div class="crack"></div><div class="crack"></div><div class="crack"></div></div><div class="prefect">prefect~<br>OvO<br>积分+2</div><div class="good">good~<br>OvO<br>积分+1</div><div class="miss">miss~<br>OvO<br>积分+0</div></div><div id="rank-rule"><div class="rankbox"><div class="rank-list"><table class="rank-table"><caption>游戏积分表Top5</caption><tr><th>玩家名</th><th>游戏积分</th></tr></table></div></div><div class="rulebox"><div style="color: red;font-size: 30px;">游戏规则</div><div style="color: white;font-size: 20px;">玩家通过点击“开始游戏”按钮进行游戏,通过键盘的按键QWER进行操作.<br>当小方块滑落到轨道末尾,点击对应按键,根据按键时机获取不同的分数.<br>游戏时间20s,在这时间内随机出现小方块.<br>系统会对玩家成绩进行排序,筛选top5的进行展示~</div></div></div><script src="/src/js/play.js"></script>
</body></html>

css

* {margin: 0;padding: 0;
}body {background-image: url(../img/last.jpg);background-repeat: no-repeat;background-size: 100%;background-attachment: fixed;
}#game-box {position: absolute;left: 0;top: 0;width: 50%;height: 100vh;border: 2px solid black;overflow: hidden;/*因为设置为绝对定位,后面设置子元素的高度大小100%会溢出,使得子元素超出的部分隐藏*/
}#rank-rule {position: absolute;right: 0;top: 0;width: 50%;height: 100vh;
}.game-name {text-align: center;margin-top: 20px;color: aliceblue;font-size: larger;font-weight: 800;
}/* 四个轨道的区域 */
.crack-box {width: 100%;height: 100%;/* border: 1px solid white; */display: flex;margin: 0 auto;margin-top: 10px;margin-bottom: 10px;width: 80%;height: 90%;background-color: rgba(2, 8, 37, 0.3);position: relative;
}/* 轨道 */
.crack-box div {position: relative;width: 25%;height: 100%;border: 1px solid rgba(0, 0, 0, 0.347);cursor: pointer;
}/* 滑落的方块样式 */
.crack-box .crack div {position: absolute;/* 设置脱离文档流,这样生成的小方块不会互相干扰 */width: 100%;height: 10%;background-color: aliceblue;border-radius: 10%;}/* 作为轨道的按钮 */
.crack:nth-child(1)::after {content: "Q";
}.crack:nth-child(2)::after {content: "W";
}.crack:nth-child(3)::after {content: "E";
}.crack:nth-child(4)::after {content: "R";
}.crack {pointer-events: none;/* 这样才能使用js选择.crack::after */
}/*伪元素样式*/
.crack::after {pointer-events: auto;/* 这样才能使用js选择.crack::after */display: flex;justify-content: center;align-items: center;position: absolute;bottom: 0;width: 100%;height: 10%;box-shadow: -5px -5px 10px rgba(138, 177, 167, 0.496);background-color: rgba(187, 186, 186, 0.476);cursor: pointer;font-size: 30px;font-weight: 900;color: rgba(245, 11, 11, 0.625);
}/* 伪元素点击时的属性 */
.onclick::after {content: "";background-color: red;color: black;
}.prefect {position: absolute;margin: 0 auto;width: auto;height: auto;top: 50%;left: 50%;transform: translate(-50%, -50%);/*调节位置,使得居中*/text-align: center;font-size: 2rem;font-weight: 900;font-family: fantasy;color: rgba(247, 31, 31, 0.7);background-color: rgba(136, 233, 127, 0);z-index: 99;display: none;
}.good {position: absolute;margin: 0 auto;width: auto;height: auto;top: 50%;left: 50%;transform: translate(-50%, -50%);/*调节位置,使得居中*/text-align: center;font-size: 2rem;font-weight: 900;font-family: fantasy;color: rgba(38, 18, 212, 0.676);background-color: rgba(136, 233, 127, 0);z-index: 99;display: none;
}.miss {position: absolute;margin: 0 auto;width: auto;height: auto;top: 50%;left: 50%;transform: translate(-50%, -50%);/*调节位置,使得居中*/text-align: center;font-size: 2rem;font-weight: 900;font-family: fantasy;color: rgba(240, 225, 23, 0.598);background-color: rgba(136, 233, 127, 0);z-index: 99;display: none;
}/* //开始游戏按钮样式 */
button {border-radius: 10px;text-shadow: 0px 1px 0px #2f6627;box-shadow: 0px 0px 0px 2px #9fb4f2;font-family: Arial;color: #ffffff;/* font-size: 10px; */background: #44c76776;padding: 12px 30px 12px 30px;border: solid #18ab29 1px;text-decoration: none;
}
button:hover {color: #ffffff;background: #e92311af;text-decoration: none;
}.rank-list{color: white;font-size: 20px;height: 60%;width: 100%;/* border: 2px solid red; */position: absolute;top: 5px;right: 0;}/* rank表样式 */
.rank-list table caption{font-size: 40px;color: red;
}
.rank-list table{width: 100%;/* height: 200px; 如果指定了这个高度,td行就会根据这个高度进行分布,到时候删除行的时候就会很丑*/border-top: 1px solid rgba(255, 255, 255, 0.5);/* border-left: 1px solid rgba(255, 255, 255, 0.5); */text-align: center;vertical-align: center;table-layout: fixed;}
.rank-list table th{border-right: 1px solid rgba(255, 255, 255, 0.5);border-bottom: 1px solid rgba(255, 255, 255, 0.5);padding: 8px;
}.rank-list table td{padding: 8px;border-right: 1px solid rgba(255, 255, 255, 0.5);border-bottom: 1px solid rgba(255, 255, 255, 0.5);
}.rulebox{position: relative;right: 0;top: 70%;text-align: center;
}
/**问题:*设置高度宽度为百分号时,是根据第一个position不是static的父元素的大小进行设置的 *设置伪元素的伪类效果:p:hover::after,跟正常的思维相反。。*但是p:focus::after就不启作用,由于js不能选取到伪元素,所以设置如下属性,这样选取到.crack,其实是选中了.crack::after.crack{pointer-events: none;}.crack::after{pointer-events: auto;}
*/

javascript

var socre = 0; //分数
var num = 1; //玩家编号
var items = new Array(); //玩家积分数组// 随机在四个轨道内生成小方块
function CreateBlock() {var crackNumber = Math.floor(Math.random() * 4); //轨道编号var blockNum = Math.floor(Math.random() * 3 + 1); //轨道滑落方块数量,1~3块var fatherBox = document.getElementsByClassName("crack")[crackNumber]; //找到父级元素for (var i = 0; i < blockNum; i++) {var block = document.createElement('div');fatherBox.appendChild(block);block.timer = null;//获取轨道的长度var target = fatherBox.offsetHeightstartMove(block, target);}
}// 小方块向下滑落,然后消失
function startMove(obj, target) {clearInterval(obj.timer); //清除计时器var y = 1;var top = 0;obj.timer = setInterval(function () {if (top < target - obj.offsetHeight) {top += y; //每次滑落1pxobj.style.top = top + "px";} else {obj.remove();clearInterval(obj.timer); //清除计时器}}, 10);
}// QWER健按下事件
document.onkeydown = function (event) {if (event.keyCode == 81) {var crack = document.getElementsByClassName('crack')[0];crack.classList.add('onclick');addSorce(crack);showSorces();}if (event.keyCode == 87) {var crack = document.getElementsByClassName('crack')[1];crack.classList.add('onclick');addSorce(crack);showSorces();}if (event.keyCode == 69) {var crack = document.getElementsByClassName('crack')[2];crack.classList.add('onclick');addSorce(crack);showSorces();}if (event.keyCode == 82) {var crack = document.getElementsByClassName('crack')[3];crack.classList.add('onclick');addSorce(crack);showSorces();}
}
// QWER健按下事件
document.onkeyup = function (event) {if (event.keyCode == 81) {var crack = document.getElementsByClassName('crack')[0];crack.classList.remove('onclick');}if (event.keyCode == 87) {var crack = document.getElementsByClassName('crack')[1];crack.classList.remove('onclick');}if (event.keyCode == 69) {var crack = document.getElementsByClassName('crack')[2];crack.classList.remove('onclick');}if (event.keyCode == 82) {var crack = document.getElementsByClassName('crack')[3];crack.classList.remove('onclick');}
}
//判断按钮点击,小方块在什么位置,进而加多少分
function addSorce(crack) {var firstBlock = crack.firstChild; //获取该轨道的第一个小方块if (firstBlock) { //如果该轨道存在小方块var blockTop = firstBlock.offsetTop;var blockHeight = firstBlock.offsetHeight;var crackHeight = crack.offsetHeight;// console.log(blockTop,blockHeight,crackHeight);var prefect = document.getElementsByClassName("prefect")[0];var good = document.getElementsByClassName("good")[0];var miss = document.getElementsByClassName("miss")[0];// console.log(blockTop, blockHeight,crackHeight);if (blockTop <= crackHeight - blockHeight && blockTop >= crackHeight - blockHeight * 1.3) {socre += 2; //加2分prefect.style.display = "block";firstBlock.remove();} else if (blockTop >= crackHeight - blockHeight * 1.8 && blockTop < crackHeight - blockHeight * 1.3) {socre += 1;good.style.display = "block";} else {miss.style.display = "block";}}
}// 每隔一段时间去除miss,prefect.good的样式
function remove() {var prefect = document.getElementsByClassName("prefect")[0];var good = document.getElementsByClassName("good")[0];var miss = document.getElementsByClassName("miss")[0];prefect.style.display = "none";good.style.display = "none";miss.style.display = "none";
}//显示分数
function showSorces() {var elem = document.getElementsByClassName("sorce")[0];elem.innerHTML = socre;elem.style.color = 'red';
}//"开始游戏"按钮函数
function gameTime() {var time = 20;var eleTime = document.getElementsByClassName('time')[0];var timer = setInterval(function () {if (time >= 0) {CreateBlock();eleTime.innerHTML = time + "s";eleTime.style.color = "red"time--;} else {clearInterval(timer);//到时间,清空还在轨道上的方块var blocks = document.getElementsByClassName('crack');for (var i = 0; i < blocks.length; i++) {while (blocks[i].hasChildNodes()) {blocks[i].removeChild(blocks[i].firstChild);}}alert("time is run out")var player = {name: "玩家" + num,socre: socre};items.push(player);items.sort(function (a, b) { //默认是按照字符串大小排序,改成按数字return (b.socre - a.socre); //降序});num++; //玩家编号+1socre = 0; //重置showSorces(); //重置分数showRankList(); //展示分数top5}}, 1000)
}//展示积分表
function showRankList() {var table = document.getElementsByClassName("rank-table")[0];console.log(table.rows.length);if (table.rows.length > 0) { //先把所有的行删除for (var i = table.rows.length - 1; i > 0; i--) {table.deleteRow(i);}}//从数组中读取数组,写到积分表中var maxLength = 5; //top5if (items.length < 5) {maxLength = items.length; //最多读出5个}for (var i = 0; i < maxLength; i++) {var row = document.getElementsByClassName("rank-table")[0].insertRow(i + 1); //i+1是表示插入在th后面var name = row.insertCell(0);var socre = row.insertCell(1);name.innerHTML = items[i].name;socre.innerHTML = items[i].socre;}
}setInterval(remove, 800); //定时清理prefect,miss,good的标志

javascript-原生javascript实现类似节奏大师小游戏相关推荐

  1. html+javascript实现的网页版飞机大战小游戏源码

    html+javascript实现的网页版飞机大战小游戏源码 完整代码下载地址: html+javascript实现的网页版飞机大战小游戏源码 index.html <!DOCTYPE html ...

  2. php跳一跳小游戏,原生JS实现的跳一跳小游戏完整实例

    本文实例讲述了原生JS实现的跳一跳小游戏.分享给大家供大家参考,具体如下: 以下说的是闲暇编写的一个小游戏--跳一跳,类似于微信的跳一跳,大体实现功能有: 1.先随机生成地图: 2.按住按钮释放后完成 ...

  3. html实现跳跳棋游戏,原生JS实现的跳一跳小游戏完整实例

    本文实例讲述了原生JS实现的跳一跳小游戏.分享给大家供大家参考,具体如下: 以下说的是闲暇编写的一个小游戏--跳一跳,类似于微信的跳一跳,大体实现功能有: 1.先随机生成地图: 2.按住按钮释放后完成 ...

  4. 打砖块小游戏php程序,利用原生js实现html5打砖块小游戏(代码示例)

    本篇文章给大家通过代码示例介绍一下利用原生js实现html5打砖块小游戏的方法.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 前言 PS:本次项目中使用了大量 es6 语法,故对于 ...

  5. 如何用 JavaScript+Canvas 开发一款超级烧脑小游戏?

    作者 | huangjianke 责编 | 伍杏玲 出品 | CSDN(ID:CSDNnews) [CSDN 编者按]据微信最新数据,微信小游戏累计注册用户量已突破10亿.那么初学者如何开发一款好玩又 ...

  6. html5 打气球小游戏,在javascript+css3中如何实现打气球小游戏

    这是一个简单但是印象深刻的小游戏,打气球小游戏的实现代码,主要基于js和css3,基于css3画气球,具体实现代码大家参考下本文 效果知识点: css3画气球, 自定义属性运用,随机阵列, DOM元素 ...

  7. 单机类似节奏大师游戏源码项目

    "本源码不能成一个完整的游戏,还欠缺很多的东西,当初只是作为使用cocos2dx引擎时的练习. 源码也非常的简单,基本都是if else作为判断,相信有编程功底的辕门都能看懂. --< ...

  8. 大大维的游戏机计划2--一个自制的类似2048的小游戏

    承接上篇,这几日,笔者本来打算写一个2048的,但写着写着,突然有个想法,能不能搞一个将2048和消消乐结合起来的游戏,于是,笔者便写出了如下这个小游戏. 值得一提的是,整个游戏完全由笔者独自写成,并 ...

  9. cocos creator 安卓原生平台环境_竞技对抗小游戏单挑篮球开发历程 | Cocos技术派第12期...

    本文来自于"Cocos 荣耀讲师"征稿活动第1期,最先发表于 Cocos 中文社区,作者 ID:蟹老板,2017年加入社区,文章作品包括<猎头专家的开发历程>等. Co ...

  10. 前端每日实战:164# 视频演示如何用原生 JS 创作一个数独训练小游戏(内含 4 个视频)...

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/mQYobz 可交互视频 此视频是可 ...

最新文章

  1. C++ 多态实现机制
  2. NeurIPS 2021 | 华为诺亚Oral论文:基于频域的二值神经网络训练方法
  3. 打通NTFS权限 文件共享各取所需
  4. 拿到两封信,开心ING
  5. 能使曲线变平滑的一维滤波器_双边滤波器的原理及实现
  6. 【C语言】str类与men库函数的实现(如:strcpy,strcmp,strstr,strcat,memmove,memcpy)
  7. 东莞理工c语言作业,东莞理工学院 c语言复习题
  8. PHY芯片88EE1111 MDIO接口调试
  9. python读取第一行设为字典_将csv读入字典,第一行成为名称
  10. 5e的训练模式全是英文_四块GPU即可训练BigGAN:「官方版」PyTorch实现出炉
  11. ubuntu 串口调试工具_开源软件分享基于WPF的串口调试工具
  12. 微信小程序入门4-扫普通二维码进入小程序、打开短链接进入小程序
  13. 秒懂三层交换机的作用及使用
  14. 自定义进度条PictureProgressBar
  15. android连路由器 mtu,解决app无网络问题,将宽带路由器MTU从1500修改成1480
  16. 熔断器熔断时间标准_保险丝熔断时间标准 保险丝熔断标准
  17. 自定义json格式-解析为对象
  18. 图像特征提取之LoG特征
  19. CollageIt - [照片拼贴,照片整合]
  20. 简单句 - 主谓/主谓宾/主系表的分析

热门文章

  1. C++的O2、O3到底是个什么鬼
  2. 免费下载C++Prime!
  3. 5WHY分析法 学习笔记
  4. 可以这样理解 TIM_INIT(arr,psc)重装载值和分频值
  5. python 使用QPixmap显示图片扭曲、错位问题的解决
  6. android短信验证码登录,Android注册登录实时自动获取短信验证码
  7. 北京航空航天大学计算机考研难度,北京航空航天大学考研难吗?一般要什么水平才可以进入?...
  8. CSS峰会圆桌论道丨共享产业数字化升级中的安全探索
  9. ggggxc学习笔记---C语言代码I
  10. 无线键鼠接收器丢了怎么办