js实现-别踩白块儿
简介
在js类的学习的时候,做的一款js小游戏。难度不高。具体实现看代码,写了注释
需求
游戏需求:游戏开始、游戏中、游戏结束
游戏开始:界面初始化、开始界面
游戏中:判断游戏状态、生成方块、分数显示与加分
游戏结束:结束界面、重新开始
实现
定义游戏容器类 Block 存放游戏内容
类属性:
container //游戏容器
timer //计时器
state //游戏状态
speed //移动速度
sum //游戏分数
top //容器顶部,控制容器
lastRowChilds //最后一行
方法:
// start()
游戏开始,创建游戏初始状态,开始监听全局
// createRow()
创建新行,先创建一行,然后将行添加到container的首子节点,随机生成黑块
// move()
container移动,通过top控制整个container,使用speed来改变top的值
// judge()
判断游戏状态,显示得分;当container到达底部时判断是否存在黑块,是则游戏结束,否则 删除末尾行
// flash()
显示得分,在页面中插入分数
// clickEvent()
点击监听,监听container容器的点击,在script中调用。
// gameOver()
游戏结束,清除定时器,更改游戏状态
// again()
重新开始,重置类,同时调用start()
代码
index.html
<!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">
<link rel="stylesheet" href="css/block.css">
<script src="js/block.js"></script>
<title>Piano_Tiles_es6</title>
</head>
<body>
<!-- 游戏区域 -->
<div class="wrapper">
<!-- 分数 -->
<p id="score">0</p>
<!-- 游戏区域 -->
<div id="main"></div>
<!-- 开始界面 -->
<div class="curtain_start" id="curtain_start">
<p>别踩白块儿</p>
<span id="start">开始</span>
</div>
<!-- 重新开始 -->
<div class="curtain_end" id="curtain_end" style="display: none">
<p>游戏结束!</p>
<h4 id="res">得分: 0</h4>
<span id="again">重新开始</span>
</div>
</div>
<script>
const curtain_start = document.getElementById('curtain_start');
const main = document.getElementById('main');
const start = document.getElementById('start');
const again = document.getElementById('again');
var gamer = new Block(main); //创建游戏实例
gamer.clickEvent(); //点击监听
start.onclick = function() {
console.log('点击了开始');
curtain_start.style.display = 'none';
// 游戏开始
gamer.start();
}
again.onclick = function() {
console.log('点击了重玩');
curtain_end.style.display = 'none';
// 游戏开始
gamer.again();
}
</script>
</body>
</html>
block.css
* {
margin: 0;
padding: 0;
}
.wrapper {
width: 400px;
height: 600px;
position: relative;
left: 0;
margin: auto;
border: 2px solid #000000;
}
#main {
width: 400px;
height: 900px;
top: -150px;
position: relative;
}
#score {
position: absolute;
top: 10px;
left: 15px;
font-size: 23px;
z-index: 1;
}
.curtain_start,.curtain_end {
width: 400px;
height: 600px;
background-color: rgb(0, 0, 0, .3);
position: absolute;
top: 0;
}
.curtain_start p,
.curtain_end p {
color: #fff;
line-height: 35px;
font-size: 35px;
position: absolute;
top: 200px;
left: 120px;
}
.curtain_start span,
.curtain_end span {
display: block;
width: 100px;
height: 50px;
font-size: 20px;
text-align: center;
line-height: 50px;
position: absolute;
top: 300px;
left: 150px;
background: #6cd966;
color: #fff;
border-radius: 6px;
cursor: pointer;
}
.curtain_end h4 {
color: #fff;
line-height: 35px;
font-size: 35px;
position: absolute;
top: 250px;
left: 140px;
}
.row {
width: 400px;
height: 150px;
}
.block {
width: 98px;
height: 148px;
background-color: #ffffff;
border: 1px solid #000000;
float: left;
}
.black {
width: 98px;
height: 148px;
border: 1px solid #000000;
float: left;
background-color: #000000;
cursor: pointer;
}
block.js
// 游戏容器类 Block
class Block {
constructor(container) {
this.container = container; //游戏容器
this.timer = null; //计时器
this.state = false; //游戏状态
this.speed = 2; //游戏速度
this.sum = 0; //游戏分数
this.top = -150; //容器顶部
this.lastRowChilds = null; //最后一行
}
//开始游戏
start() {
let _this = this;
this.state = true;
//创建行
for (let i = 0; i < 4; i++) {
this.createRow();
console.log('创建行');
}
//每单位时间处理事件
this.timer = setInterval(() => {
_this.move();
_this.judge();
}, 30);
}
//创建新行
createRow() {
// const contain = this.container;
//添加内容从首子节点开始添加
let firstChild = this.container.firstChild;
let rowDiv = document.createElement('div');
rowDiv.className = 'row';
// 行内方块,随机黑色
let blocks = ['block', 'block', 'block', 'block'];
let random = Math.floor(Math.random() * 4);
blocks[random] = 'black';
// 添加进入行
for (let i = 0; i < 4; i++) {
let block = document.createElement('div');
block.className = blocks[i];
rowDiv.appendChild(block);
}
if (firstChild == null) {
//没有行,添加
this.container.appendChild(rowDiv);
} else {
//有行,添加到一号子节点
this.container.insertBefore(rowDiv, firstChild);
}
}
//界面移动
move() {
this.top += this.speed; //随速度累加
this.container.style.top = this.top + 'px';
}
//判断游戏状态
judge() {
// 容器出框,创建行
//获取容器所有行
let rowChilds = document.getElementsByClassName('row');
this.lastRowChilds = rowChilds[rowChilds.length - 1];
if (this.top >= 0) {
// 到达底部自动生成块
this.createRow();
// 容器视图回到-150px
this.top = -150;
this.container.style.top = '-150px';
console.log('回到位置:', this.container.offsetTop);
// 在最后一行的所有块中遍历
for (let i = 0; i < this.lastRowChilds.childNodes.length; i++) {
// 游戏自动进行时游戏状态
if (this.lastRowChilds.childNodes[i].className == 'black') {
console.log('有黑的,游戏结束');
this.gameOver();
} else if(rowChilds.length == 6){ //除了游戏开始,让容器适中存在五行
this.container.removeChild(this.lastRowChilds);
}
}
}
this.flash();
}
//显示得分
flash() {
let score = document.getElementById('score');
score.innerHTML = this.sum;
let res = document.getElementById('res');
res.innerHTML = `得分: ${this.sum}`;
}
// 点击监听
clickEvent() {
console.log('执行了clickEvent');
let _this = this;
// 为容器添加点击监听
this.container.addEventListener('click', (e) => {
console.log(e.target);
let tag = e.target;
if (tag.className == 'black') {
_this.sum++; //点击黑块得分增加
_this.speed += 0.4; //速度增加
console.log('点到了黑块,速度增加为:', _this.speed);
tag.className = 'block';
} else {
console.log('点到了白块');
this.gameOver(); //游戏结束
}
})
}
// 游戏结束
gameOver() {
this.state = false; //游戏状态置为false
clearInterval(this.timer); //清空定时器
const curtain_end = document.getElementById('curtain_end'); //展示页面
curtain_end.style.display = 'block';
}
//重新开始
again() {
this.timer = null; //计时器
this.state = false; //游戏状态
this.speed = 2; //游戏速度
this.sum = 0; //游戏分数
this.top = -150; //容器顶部
this.lastRowChilds = null; //最后一行
this.container.innerHTML = ''; //将容器置空
this.start();
}
}
效果
开始
游戏
游戏结束: