俄罗斯方块游戏(JavaScript) - 开源

459 阅读9分钟

在这篇文章中,我将向你展示用纯JavaScript编程的俄罗斯方块游戏,完全免费且开放源代码。

这个方块游戏是用JavaScript编程的,使用canvas来绘制游戏。我还使用Bootstrap来布置按钮和整个页面,并使用了一点SweetAlert来进行提醒。

虽然看起来很简单,但 这是让我花费最多的工作之一,也是我最自豪的工作。要理解所有的碰撞、旋转、行删除、部件移动、限制等逻辑,(对我来说)是很复杂的。

在游戏的特点中,我们发现。

  • **声音:**背景音乐,当棋子不能旋转时的声音,当完成一排棋子时的声音,以及四维码触地时的声音
  • **颜色:**每个棋子都有一个在运行时选择的随机颜色
  • **旋转:**棋子可以旋转以适应它们,并积累积分
  • **移动兼容:**因为是网页游戏,所以我添加了一些按钮,以便在手机和平板电脑上玩,但也可以用键盘玩。
  • **开源:**你可以修改游戏、棋盘、长度、速度、棋子、旋转等。
  • **俄罗斯方块移植:**表现得像任何正常的俄罗斯方块游戏
  • **游戏暂停:**游戏可以在任何时候暂停或恢复

然后让我们看看这个用JS编程的游戏的细节。在整个文章中,我将向你展示这个游戏是如何编程的,我也会给你留下一个演示和完整的代码,这是自由软件。

**注意:**在这篇文章中,数字棋子俄罗斯方块都是同义的。

俄罗斯方块游戏的一般算法

这个算法很简单。我们有一个直角坐标平面,坐标XY 。我们有3样东西。

  1. 游戏板:所有东西都会被画出来或显示出来的棋盘
  2. 现有棋子:之前已经落下的点或棋子;也就是说,留在那里的数字
  3. 当前棋子:目前正在下降的棋子,玩家可以移动或旋转的棋子。

现在我们要做的是:先画出棋盘(空的),然后把现有的棋子重叠起来,最后放置当前的棋子(正在下降的那个)。

在每一次移动或试图旋转时,我们都要检查该棋子是否与墙或下面的另一个图形一起倒塌。当该部分被旋转时,我们做一个模拟,看看这些点在被旋转后,是否不会与另一个部分一起倒塌。

此外,当检测到棋子落地时,就会启动一个定时器,在一定的毫秒内放入下一个棋子(这样玩家就有时间移动棋子)。

在显示另一个形状之前,当前形状的点被移动到现有的部分。

剩下的是碰撞和与数组的工作。例如,为了检查一排是否已满,我们在Y的某一位置穿过数组的每个点,并检查它是否已被占用。

所有的游戏绘制都是在requestAnimationFrame ,我们用JavaScriptCanvas上绘制一个数组。

游戏音乐

该游戏有各种声音。所有的声音都被注入并隐藏在DOM中。它们是这样启动的。

查看Gist上的代码。

在这种情况下,背景声音是在一个循环中重现的,所以它无限地重复。然后,我们像这样复制它**(第1行**)。

查看Gist上的代码。

帮助类

一个点有两个东西。X和Y坐标。而一个Tetromino有几个点组成。

Gist上查看代码。

俄罗斯方块

就像我说的,一个俄罗斯方块图形是由几个点组成的。此外,它还有几种旋转方式。例如,Z只有2个,但J有4个。这些旋转也被定义为俄罗斯方块,旋转时它们会被交换。

为了跟踪图形所处的旋转,要保留一个索引。旋转只不过是一个有几个Tetromino的数组,它代表了所有可能的旋转。

Gist上查看代码。

你可以看到,颜色是在第6行选择的。在选择图形的那一刻,每一个旋转的点都被涂上了随机颜色。

有用的功能

在继续之前,让我们看一下有用的函数。在这些函数中,我们有加载声音的函数,有选择随机颜色的函数,也有选择随机数以知道选择哪个数字的函数。

Gist上查看代码。

例如,getRandomColor 函数从我们接下来要看到的Game 类的静态数组中选择一个随机颜色。而这个函数重用了名为getRandomNumberInRange 的函数,该函数在一定范围内返回一个数字。

游戏操作

JavaScript中的俄罗斯方块--欢迎来到游戏

让我们先来看看游戏的常量,比如棋盘的大小、颜色、当用户打出一排分数时给他的分数或可选择的随机颜色。

Gist上查看代码。

颜色阵列可以根据你的喜好进行修改,要么改变颜色,要么添加更多的颜色,以增加随机性。

我们还有一些有趣的参数,比如每个方块的大小,以像素为单位(这影响到棋盘的大小),或者用毫秒来表示棋子向下移动的速度、动画的持续时间或者棋子触地后玩家需要移动的时间。

游戏初始函数

这一切都从init函数开始,但我们定义几件事的构造函数也很重要。

Gist上查看代码。

游戏会收到要画的画布的ID。通过这种方式,我们可以用同样的代码制作两个俄罗斯方块游戏板。

我们还有各种标志,棋盘的定义,声音,等等。现在让我们看看这个开源俄罗斯方块游戏的启动和重启。

Gist上查看代码。

这里需要注意的一个重要的事情是syncExistingPiecesWithBoard 函数。这个函数所做的是清理棋盘并将现有的棋子放在上面(也就是修改数组的索引)。

在画布上绘制

在画布上绘制整个俄罗斯方块游戏的函数如下。它将每隔17毫秒被调用一次,使用requestAnimationFrame

Gist上查看代码。

如果你想在其他地方绘制游戏,你可以修改这个函数;例如,在表格中,用SVG,在控制台中,等等。

获取随机数字

我们有一个函数,在那里我们定义数字和它们的旋转。这个方法将在每次调用时返回一个随机的Tetromino

Gist上查看代码。

就在这里,我们正在使用Point 类和Tetromino 类。请记住,每个Tetromino将收到一个包含所有可能的旋转的数组。而每个旋转又是一个具有不同坐标的点的数组。

这些坐标不会在点的内部修改,而是从棋盘上的全局X和Y开始放置。

如果你想定义其他形状或修改旋转,这就是你必须进行修改的地方。

碰撞和运动

我知道有一些用于视频游戏开发的引擎,但在这种情况下,我想用手来做所有的事情。因此我创建了自己的函数来知道一个点是否出界,一个点是否有效,等等。

让我们先来看看检查现有棋盘和棋子的点碰撞函数。

Gist上查看代码。

我们使用的是X和Y的全局坐标,因为记住图中的每个点都是独立的。

现在让我们来看看移动或旋转图形的函数。

Gist上查看代码。

我们所做的是模拟移动并检查每个点是否仍然有效。如果数字不能旋转,我们也会播放一个声音。

删除完整的行

在这个用JavaScrtipt编写的积木游戏中删除整行的内容

这是我花了最多时间编程的一个函数。它的作用是检查并删除已填满的行。它看起来像这样。

Gist上查看代码。

我们必须获得所有已经被填充的行的Y坐标。对于每一行,我们检查是否可以将所有的点向下移动。如果可以,我们就降低它们,但我们降低的程度不会超过被删除的行数

同时,这个功能也会增加分数。刷新它的函数是。

Gist上查看代码。

分数的计算是根据被删除的点数乘以被删除的每一格的分数。

游戏循环

现在让我们来看看游戏循环。根据上面定义的间隔时间(毫秒),我们在可能的情况下降低四维码。如果棋子不能再移动,就会启动一个定时器,给玩家一个移动棋子的机会。

当计时器用完时,如果四维码仍然不能移动,我们就把当前的部分添加到现有的零件中,然后选择另一个形状。

Gist上查看代码。

也是在这个循环中,我们检查玩家是否输了。

俄罗斯方块游戏--玩家输了

我必须承认,这个功能需要改进,因为它目前检查的是第二行的棋子,但它应该更聪明。

Gist上查看代码。

用JavaScript玩积木的控件

我编写的JavaScript中的积木游戏或俄罗斯方块,可以用键盘或按钮来玩。现在是展示游戏的HTML代码的好时机,在这里我们可以看到画布和按钮。

Gist上查看代码。

每个按钮都有一个ID,然后我在游戏中使用querySelector 来获取这个ID。

查看Gist上的代码。

现在让我们来看看控件,包括键盘和按钮。每一个都调用了 "尝试向右移动 "的功能和所有其他位置。

Gist上查看代码。

在这里你可以看到我们使用了canPlay 标志,我们根据自己的方便停用或激活它。例如,在游戏暂停时或在播放移行动画时不能播放。

把它全部放在一起

用JavaScript编写的Parzibyte玩俄罗斯方块游戏(开放源代码软件)

我不能在这里放或解释所有的代码。请记住,我们唯一需要的是一个画布,在那里我们可以画出整组方块。其余的都在代码中,特别是在Game 类中。你可以自由地去探索它。

我真的花了很多时间和精力来做这个游戏;你可以通过提交看到它的所有演变。

我给你留了一个YouTube视频来演示(西班牙语)。

完整和开放的源代码在我的GitHub上:https://github.com/parzibyte/tetris-javascript

你可以在这里试试这个演示:https://parzibyte.github.io/tetris-javascript/

我也借此机会邀请你在我的博客上阅读更多关于JavaScript视频游戏的内容。

The postTetris game in JavaScript - Open sourceappeared first onParzibyte's blog.