小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
前言
之前刚刚学Javascript的时候,写了一个简单的“别踩白块儿”游戏。刚刚整理代码的时候突然发现,刚好可以写个分析,就当是复习原生的Javascript。
一、方法
核心思路:定义一个元素作为块的容器,通过容器的偏移量变化来模拟块的移动。
- 初始化的时候,容器向上偏移一定的高度(一个块的高度),并不断移动。
- 向容器中添加块,每次添加一行,一行4个,其中一个随机变为黑色块。
- 当添加到一定行数(容器铺满),判断最前的一行是否通过,通过则移除并添加新行,不通过则游戏结束。
二、效果
- 别踩白块儿基本效果
- 实时积分
- 可控制速度
- 暂停和继续
- 随积分增长速度加快
三、实现的过程
1. HTML + CSS
这个就直接贴了,没什么好讲的。
<div class="wrap">
<div class="gamebox">
<div class="gamearea">
<div class="moveblocks" id="moveblocks"></div>
<!-- <div class="main" id="main"></div> -->
</div>
<button class="start" id="start">
GAME START!
</button>
</div>
<div class="controlbox">
<div class="score" id="score">
<p>Score</p>
<p>0</p>
</div>
<div class="speed" id="speed">
<p>speed</p>
<p>0</p>
</div>
<button class="speedUp" id="speedUp">
speed Up!
</button>
<button class="slowDown" id="slowDown">
slow Down!
</button>
<button class="pause" id="pause">
Pause
</button>
</div>
</div>
2. Javascript
- 首先获取对应的元素,初始化配置项
var moveblocks = document.getElementById("moveblocks");
var main = document.getElementById("main");
var start = document.getElementById("start");
var score = document.getElementById("score");
var speedbox = document.getElementById("speed");
var speedUp = document.getElementById("speedUp");
var slowDown = document.getElementById("slowDown");
var pause = document.getElementById("pause");
var goOn = document.getElementById("goOn");
// 计时器
var timer;
// 初始速度
var startspeed = 1;
// 速度
var speed = startspeed;
// 积分
var num = 0;
- 块填充函数
在容器中继续添加块。 主要通过这个函数来添加块,并通过设置样式和类名来标志是否是需要点击的块。
function createNewDiv(classname) {
var newrow = document.createElement("div");
newrow.className = classname;
for (var i = 0; i < 4; i++) {
var blocks = document.createElement("div");
newrow.appendChild(blocks);
}
// 如果游戏区域是空的,newrow应该放在后面;
// 如果游戏区域不是空的,newrow应该插入到第一个之前去
if (moveblocks.children.length == 0) {
moveblocks.appendChild(newrow);
}
else {
moveblocks.insertBefore(newrow, moveblocks.children[0]);
}
//给随机一个block加颜色
index = Math.floor(Math.random() * 4)
newrow.children[index].style.backgroundColor = "black";
newrow.children[index].className = "i";
}
- 容器移动和点击积分函数
容器初始化时位于 -115px 处并通过原来位置和速度更新新的位置
当位置超出时,回到初始位置。
当添加到一定行数(容器铺满),判断最前的一行是否通过。
function movebox(obj) {
// 初始化 速度 和 分数
// var startspeed = 1;
// var speed = startspeed;
// var num = 0;
timer = setInterval(
function () {
var y = parseInt(getComputedStyle(obj, null)['top']) + speed;
obj.style.top = y + "px";
if (parseInt(getComputedStyle(obj, null)['top']) >= 0) {
createNewDiv("newrow");
obj.style.top = -115 + "px";
}
// 进行判定
if (obj.children.length >= 6) {
for (var i = 0; i < 4; i++) {
if (obj.children[obj.children.length - 1].children[i].className == 'i') {
//游戏结束
obj.style.top = '-115px';
// score.innerHTML = '游戏结束,最高得分: ' + num;
//关闭定时器
// clearInterval(obj.timer);
clearInterval(timer);
//显示开始游戏
confirm("游戏结束,最高分:" + num);
start.innerHTML = "REPLAY";
}
}
obj.removeChild(obj.children[obj.children.length - 1]);
}
//点击和积分
obj.onclick = function (event) {
event = event || window.event;
if (((event.target ? event.target : event.srcElement).className == 'i')
||
((event.target ? event.target : event.srcElement).className == 'k')) {
if ((event.target ? event.target : event.srcElement).className == 'i') {
//点击后的盒子颜色
(event.target ? event.target : event.srcElement).style.backgroundColor = "#bbb";
//清除盒子标记
(event.target ? event.target : event.srcElement).className = 'k';
//计分
num++;
}
} else {
obj.style.top = 0;
// clearInterval(obj.timer);
clearInterval(timer);
start.innerHTML = "REPLAY";
confirm("游戏结束,最高分:" + num);
}
// 每积10分速度增加一次;
if (num != 0 && num % 10 == 0) {
speed++;
}
}
// 实时显示分数和速度
score.children[1].innerHTML = num;
speedbox.children[1].innerHTML = speed;
}, 20);
}
- 加速,减速,暂停/继续功能
// 加速
speedUp.onclick = function () {
speed++;
}
// 减速 不加判定还可以向上走,hhhhhhhhhhh
slowDown.onclick = function () {
// if (speed > 1) {
// speed--;
// }
speed--;
}
// 暂停和继续 设置statics属性保存状态
pause.statics = 0;
pause.onclick = function () {
if (speed != 0) {
prespeed = speed;
}
if (pause.statics == 0) {
pause.statics = 1;
speed = 0;
pause.innerHTML = "goOn";
} else {
pause.statics = 0;
speed = prespeed;
pause.innerHTML = "pause";
}
}
- 游戏启动函数
start.onclick = function () {
clearInterval(timer);
startspeed = 1;
speed = startspeed;
if (moveblocks.children.length != 0) {
// 游戏开始的时候清空moveblocks盒子
moveblocks.innerHTML = '';
}
//清空计分
start.innerHTML = "冲呀!";
score.children[1].innerHTML = 0;
speedbox.children[1].innerHTML = 0;
movebox(moveblocks);
}
完整的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
<script type="text/javascript" src=""></script>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
html,
body {
margin: 0;
padding: 0;
font-size: 16px;
}
.wrap {
width: 35%;
height: 650px;
margin: auto;
background-color: antiquewhite;
display: flex;
}
.gamebox {
width: 65%;
height: 650px;
background-color: white;
border-style: solid;
border-width: 0 1px 1px 1px;
}
.gamearea {
height: 575px;
}
#moveblocks {
width: 100%;
height: 575px;
position: relative;
top: -115px;
}
#main {
width: 100%;
height: 575px;
}
.start {
width: 100%;
height: 75px;
line-height: 72px;
font-size: 1.7rem;
font-weight: bold;
text-align: center;
background-color: antiquewhite;
cursor: pointer;
}
.controlbox {
width: 35%;
}
.score,
.speed {
width: 100%;
height: 100px;
margin: 25px 0;
box-sizing: border-box;
font-size: 1.7rem;
font-weight: bold;
text-align: center;
}
.score p,
.speed p {
height: 50px;
line-height: 50px;
}
.speedUp,
.slowDown,
.pause {
width: 100%;
height: 50px;
list-style: none;
text-decoration: none;
background-color: antiquewhite;
cursor: pointer;
font-size: 1.3rem;
font-weight: bold;
text-align: center;
}
.speedUp {
margin: 50px 0 25px 0;
}
.slowDown {
margin: 25px 0 25px 0;
}
.pause {
margin: 25 px 0 50px 0;
}
.newrow {
width: 100%;
height: 115px;
display: flex;
}
.newrow div {
width: 25%;
height: 115px;
border-style: solid;
border-width: 0 1px 1px 1px;
/* border-top-width: 0;
border-left-width: 0; */
cursor: pointer;
}
</style>
</head>
<body>
<div class="wrap">
<div class="gamebox">
<div class="gamearea">
<div class="moveblocks" id="moveblocks"></div>
<!-- <div class="main" id="main"></div> -->
</div>
<button class="start" id="start">
GAME START!
</button>
</div>
<div class="controlbox">
<div class="score" id="score">
<p>Score</p>
<p>0</p>
</div>
<div class="speed" id="speed">
<p>speed</p>
<p>0</p>
</div>
<button class="speedUp" id="speedUp">
speed Up!
</button>
<button class="slowDown" id="slowDown">
slow Down!
</button>
<button class="pause" id="pause">
Pause
</button>
</div>
</div>
<script type="text/javascript">
// 找对象
var moveblocks = document.getElementById("moveblocks");
var main = document.getElementById("main");
var start = document.getElementById("start");
var score = document.getElementById("score");
var speedbox = document.getElementById("speed");
var speedUp = document.getElementById("speedUp");
var slowDown = document.getElementById("slowDown");
var pause = document.getElementById("pause");
var goOn = document.getElementById("goOn");
// 计时器
var timer;
// 初始速度
var startspeed = 1;
// 速度
var speed = startspeed;
// 积分
var num = 0;
// 每行创建一个大div,再在里面创建4个小div,调用一次函数只创建一行div
function createNewDiv(classname) {
var newrow = document.createElement("div");
newrow.className = classname;
for (var i = 0; i < 4; i++) {
var blocks = document.createElement("div");
newrow.appendChild(blocks);
}
// 如果游戏区域是空的,newrow应该放在后面;
// 如果游戏区域不是空的,newrow应该插入到第一个之前去
if (moveblocks.children.length == 0) {
moveblocks.appendChild(newrow);
}
else {
moveblocks.insertBefore(newrow, moveblocks.children[0]);
}
//给随机一个block加颜色
index = Math.floor(Math.random() * 4)
newrow.children[index].style.backgroundColor = "black";
newrow.children[index].className = "i";
}
function movebox(obj) {
// 初始化 速度 和 分数
// var startspeed = 1;
// var speed = startspeed;
// var num = 0;
timer = setInterval(
function () {
var y = parseInt(getComputedStyle(obj, null)['top']) + speed;
obj.style.top = y + "px";
if (parseInt(getComputedStyle(obj, null)['top']) >= 0) {
createNewDiv("newrow");
obj.style.top = -115 + "px";
}
// 进行判定
if (obj.children.length >= 6) {
for (var i = 0; i < 4; i++) {
if (obj.children[obj.children.length - 1].children[i].className == 'i') {
//游戏结束
obj.style.top = '-115px';
// score.innerHTML = '游戏结束,最高得分: ' + num;
//关闭定时器
// clearInterval(obj.timer);
clearInterval(timer);
//显示开始游戏
confirm("游戏结束,最高分:" + num);
start.innerHTML = "REPLAY";
}
}
obj.removeChild(obj.children[obj.children.length - 1]);
}
//点击和积分
obj.onclick = function (event) {
event = event || window.event;
if (((event.target ? event.target : event.srcElement).className == 'i')
||
((event.target ? event.target : event.srcElement).className == 'k')) {
if ((event.target ? event.target : event.srcElement).className == 'i') {
//点击后的盒子颜色
(event.target ? event.target : event.srcElement).style.backgroundColor = "#bbb";
//清除盒子标记
(event.target ? event.target : event.srcElement).className = 'k';
//计分
num++;
}
} else {
obj.style.top = 0;
// clearInterval(obj.timer);
clearInterval(timer);
start.innerHTML = "REPLAY";
confirm("游戏结束,最高分:" + num);
}
// 每积10分速度增加一次;
if (num != 0 && num % 10 == 0) {
speed++;
}
}
// 实时显示分数和速度
score.children[1].innerHTML = num;
speedbox.children[1].innerHTML = speed;
}, 20);
}
// 加速
speedUp.onclick = function () {
speed++;
}
// 减速 不加判定还可以向上走,hhhhhhhhhhh
slowDown.onclick = function () {
// if (speed > 1) {
// speed--;
// }
speed--;
}
// 暂停和继续 设置statics属性保存状态
pause.statics = 0;
pause.onclick = function () {
if (speed != 0) {
prespeed = speed;
}
if (pause.statics == 0) {
pause.statics = 1;
speed = 0;
pause.innerHTML = "goOn";
} else {
pause.statics = 0;
speed = prespeed;
pause.innerHTML = "pause";
}
}
start.onclick = function () {
clearInterval(timer);
startspeed = 1;
speed = startspeed;
if (moveblocks.children.length != 0) {
// 游戏开始的时候清空moveblocks盒子
moveblocks.innerHTML = '';
}
//清空计分
start.innerHTML = "冲呀!";
score.children[1].innerHTML = 0;
speedbox.children[1].innerHTML = 0;
movebox(moveblocks);
}
</script>
</body>
</html>