写在前面得话:
这篇文章主要记录了我是怎么一步一步写出俄罗斯方块,整个代码用的函数编程,主要是为了让一些不熟悉es6, 面向对象写法得 新手能更容易看明白,全部得代码中都是一些js的基础知识,很容易理解。要说有点麻烦的,那就是游戏过程中的各种检测。但是只要你多思考,你就能理解代码为什么要那样写,你也可以实现这个游戏。(当然也许你有更好的实现方法)。
预览地址:http://blog.cwlserver.top/demo/Tetris.html
1,先理清游戏逻辑
- 游戏场景:场景大小为 10*18,
- 下落时间:初始方块每隔1秒,会下落一格。随着游戏进行时间得增加,方块下落时间间隔会缩短。
- 操作方法:方向键得 上下左右 分别控制方块得, 变形,加速下落,左移,右移。
- 方块类型:一共7种类型得方块。每次随机出现一种, 每种方块由数个 1*1大小得小方块组成
- 方块下落:当方块落到底, 或者下一格已经被占,方块停止下落,然后会有一个新的方块出现
- 方块左右移动:方块左右移动时,如果左,右是墙或者是已经被占,方块将不能移动。
- 方块变形:方块逆时针旋转90°,变形时需要判断方块是否可以变形。
- 游戏会有下一个方块得提示
- 消行:当一行被填满时,这一行将被消除
- 计分规则: 消1行得2分,2行4分,3行8分,4行16分
- 游戏结束: 当方块下落到底,并且方块超出游戏场景时,判定游戏结束
2,分步实现游戏中得功能
html结构
<div id="box">
<canvas id="canvas" width="300" height="540"></canvas>
<div class="scorebox">
<p>游戏已进行: <span id="game-time">00:00:00</span></p><br>
<p>当前得分: <span id="score">0</span></p><br>
<p>下一个方块:</p><br>
<canvas id="next" width="120" height="120"></canvas><br>
<p class="btns"><button id="pause">暂停</button><button id="restart">重新开始</button></p>
</div>
</div>
构建场景
因为场景大小是10x18,所以我决定用一个 10x18得二维数组来模拟场景,这样方便和方块做碰撞检测。
//定义列数
var ROW = 10;
//定义行数
var COL = 18;
//游戏得分
var SCORE = 0;
//游戏场景
var area = new Array(COL);
for(var i=0; i<area.length; i++){
area[i] = new Array(ROW).fill(0);
}
/*
最终得到得area是这样得
area = [
[0,0,0,0....]
[0,0,0,0....]
[0,0,0,0....]
...
]
*/
构建小方块
小方块我同样使用二维数组来构建
//定义各种方块得数组, 一共7种不同得方块,数组中的1,2,3,4..这些数字主要是为了每个方块设置不同的颜色
var data = {
'o':[
[1, 1],
[1, 1]
],
's':[
[2, 0, 0],
[2, 2, 0],
[0, 2, 0]
],
'5':[
[0, 0, 3],
[0, 3, 3],
[0, 3, 0]
],
'l':[
[4, 0, 0],
[4, 0, 0],
[4, 4, 0]
],
't':[
[5, 5, 5],
[0, 5, 0],
[0, 0, 0]
],
'j':[
[0, 0, 6],
[0, 0, 6],
[0, 6, 6]
],
'|':[
[0, 7, 0, 0],
[0, 7, 0, 0],
[0, 7, 0, 0],
[0, 7, 0, 0]
]
};
//定义方块得颜色,每个数字对应一种颜色
var aColor = ['', '#fff', '#0000FF', '#00FF00', '#CC00FF', '#CCFFFF','#FFFF33','#99FFFF'];
//将data中得key放到一个字符串中 方便随机调用
var sKey = 'os5ltj|';
//定义当前方块, 当前方块默认null;
var cur = null;
//因为游戏中会有下一个方块得提示, 所以这里要提前声明一下
var next = null;
//定义一个生成方块得函数
function createBox(){
//首先创建提示方块
if(!next){
//从skey中随机取出一个键名
var rnd = Math.floor(Math.random