Tetris in JS

引言

在这个项目里,我们会实现一个俄罗斯方块小游戏。

一般情况下,这样的游戏应该使用 canvas,或者更先进的 JavaScript 游戏引擎,如 Egretcocos2d-js

在这个项目中,为了让玩家学员,掌握熟练使用最最基础的 HTMLJavaScriptCSS,我们会让大家直接操作 DOM 来实现游戏。虽然很老土,但是还记得小时候火遍大江南北的 QQ 空间游戏么(还是说两三年已经一代沟了...)?那上面的游戏,实现方式是直接操作 DOM 的游戏比例是最高的。

顺带说一下,我们的团队里有使用 Canvas 的大神,大家感兴趣的话我们可以把他拉来~

代码结构

请先下载初始代码

将压缩包解压,你会得到以下三个文件:
- tetris-in-js.html
- tetris-in-js.css
- tetris-in-js.js
我们游戏的画面和控制按钮定义在 .html 文件中,画面和控制按钮的样式定义在 .css 文件中,游戏的逻辑定义在 .js 文件中。

HTML 文件

HTML 文件定义了我们的游戏框和按钮,并且将 JS 文件中的函数绑定到对应的地方(如按钮)。

CSS 文件

CSS 文件定义了我们在 HTML 文件中绘制的游戏框的样子。本项目提供的 CSS 文件定义了按钮和游戏框的长相。

JS 文件

JS 文件是所有逻辑和运算发生的地方,它控制着游戏的开始、结束,方块的移动和消除等等。

需要做什么?

本项目提供的这份不完全的俄罗斯方块代码,包含了一些需要填补的代码框架。其中标注 YOUR CODE STARTSYOUR CODE ENDS 中间的部分,是需要完善的部分。

在现实的开发场景中,合作几乎是不可避免。经常性地,你的合作者也会像这样给你一份代码框架,需要你去填补其中的逻辑。这可能也是成长最快的方法(不过,若是遇到不写注释或是思路清奇的工友,那当我没说)。

在这个项目中,我们需要做的,是实现以下游戏逻辑:
- 游戏开始 (Game Start)
- 方块自动下落
- 控制方块移动 (左、右) 和加速下落 (down)
- 方块坠底 (drop)
- 当一行被填满时消去
- 当方块在上方超出屏幕时游戏结束。

在完成了这些逻辑之后,大家可以尝试修改这个游戏的外观,或是增加新的逻辑。

关于外观,大家根据自己的审美,怎么漂亮怎么来。

同样,关于逻辑,怎么好玩儿怎么来。下面给大家举几个例子:
- 显示当前得分
- 调整游戏难度
- 闯关机制
- 新的方块
- 可以穿过方块,一直落到最底下的补缝小方块
- 落到底时可以消去一圈方块的炸弹方块
- 所有方块都能落到最下面,无需保持原来形状的雨滴方块

定义

在书写程序之前,我们要先搞清楚定义和用语,这样沟通成本会比较低,写起来也方便。

Piece 和 Block

程序中的 piece 指的是一种方块,而 block 指的是一个小单元。

在基础版本中,一个 piece 由四个 block 通过一定排列而成。
比如,一个长条的 piece 由四个 block 水平(或垂直)首尾相接而成。

DOM

一个 HTML 页面是由一堆节点(叫做 DOM,全称是 Document Object Model,或 文档对象模型)组成的,好比你的餐桌、餐桌上的盘子以及盘子里的水果拼盘(橙子、番茄和西瓜),每一个都可以被当作一个节点。当你把餐桌向北移动一米,它上面的所有东西都会向北移动一米,而相对位置不变;当你移动盘子,盘子里的水果品盘的形状不会被破坏,餐桌也不会移动,但水果的位置确实都改变了。在这里,餐桌是盘子的 母节点,盘子的 子节点 是盘子里的所有水果。类比到俄罗斯方块里,一个 piece 就是四个 block 的母节点,它们的位置是相对 piece 的位置确定的(就好比水果的位置是相对盘子确定的,而不是桌子)。这一点非常重要。

DOM 的属性

每个 DOM 都有一大堆的属性。假设对一个名字为 blockDOM 变量,以下是设置的示例:

block.className = 'myblock'; // 相当于给它打上了一个叫作 myblock 的标签。在 CSS 文件中,我们会声明,所有带 myblock 标签的 DOM 都会被染成某种颜色。
block.style.width = '10px'; // block 的宽度为 10 像素
block.style.height = '15px'; // block 的高度
block.style.top = '20px'; // block 的顶上要空出 20 像素的空间(相当把 block 从原来的位置往下移动 20 像素)
block.style.left = '20px'; // block 的左边要空出 20 像素的空间(相当把 block 从原来的位置往右移动 20 像素)

各种方块

基础版本的俄罗斯方块有七种不同的 piece:
请看图片。

从左到右,第一行的名字分别是:
- bar
- sevenShapeReversed
- sevenShape
- square
第二行的名字分别是:
- zShape
- hump
- zShapeReversed

occupationMatrix

这是一个二维数组,每个元素都是要么是 null(没有被 block 占据的时候),要么是一个 DOM 元素(被 block 占据的时候)。occupationMatrix[0] 对应的是画面的最上面那一行,occupationMatrix[0][0] 对应的是画面最上面一行的最左边那一个格子。occupationMatrix[19][9]就是画面的最右下角那一格。所以,往下和往右是加,往上和往左是减。

关键的像素大小

我们的游戏画面宽度是 200 像素,高度是 400 像素。我们定义了一个 block 是长宽都为 20 像素的方块。在设置的时候,需要把这个设置好。

指引

我们强烈建议学生自己通读代码和文档后,直接开始编写程序。
但如果觉得需要一些引导,可以按照以下流程来进行:

定义方块

在第一个 YOUR CODE HERE 的地方,仿照已经给的例子,完成全部七种 piece 的定义。
推荐拿纸和比稍微计算一下哦。
完成后,点击不停点击开始游戏按钮,应该可以看到所有不同方块随机生成。

生成方块

方块的移动

方块的旋转

方块的消除、游戏结束以及其它

补充剩余的逻辑,完善你的俄罗斯方块!

部署

完成你的俄罗斯方块之后,我们会教你怎样把它放到你的个人网站上,开放给大家玩。

所以,你可以试着多加一些功能,并且把它做得好看一点,也许大家会对你做的东西爱不释手!