Web版俄罗斯方块,500行代码实现

Hello,I'm Shendi;


做了一个Web版的小游戏,也是我制作的第一个H5小游戏

 

更多实战内容请进入我的实战专栏https://blog.csdn.net/qq_41806966/category_9656338.html

 

目录

简介

效果视频

解析

游戏规则

页面的制作

绘制背景

画布的初始化

方块对象

游戏逻辑执行

按键监听

交互事件(*)

思路

结果判断,加分机制

暂停游戏

游戏结束

在线试玩

源码


 

简介

拥有俄罗斯方块的基本功能

方块颜色随机

掉落速度会随着时间增长而加速

直接落地

实现了暂停功能

实现了虚拟按键

下一个方块的显示

 

效果视频

首先上制作和效果视频---基本上看完视频就能了解到制作过程了

比较简单,麻烦的是方块的变换部分都需要自己一个个去实现(使用矩阵旋转效果不好)

H5俄罗斯方块

 


解析

整个项目只有两个文件一个 html 文件,一个 js 文件

 

主要的地方就是 canvas,如果对canvas不熟可以先看下这篇文章

https://blog.csdn.net/qq_41806966/article/details/103779839

 

游戏规则

  • 宽: 10
  • 高: 20
  • 一横排满则消除
  • 最后一个方块到了顶端则游戏结束
  • 七个方块

为了更好地体验,方块下降速度应该随着时间增长而加速

 

页面的制作

整体页面只有一个 canvas 和 两个 div

两个 div 分别为暂停界面和结算界面

代码片段如下

 

 

html页面的js片段

 

 

上面代码就是提供了显示暂停界面和结束界面的方法

以及对应界面的按钮点击后做的操作,也就是 ui 方面的 js 代码

 

主要的是 game.init 这一行,初始化整个画布

 

绘制背景

我将绘制背景的方法放到了 game 对象中

上面的代码,前三行是绘制背景,黑色

然后绘制场景的四条线

 

接下来的代码就是绘制按键了

 

 

画布的初始化

我将关于游戏处理的一些方法都放到了 game 对象中

html 页面会执行 game对象的init方法,传递canvas对象

 

 

此方法会先判断canvas是否为空,后面重新开始游戏不需要再次传递参数了

并且将画布的context获取

 

 

当获取到画布和画笔后,会先绘制背景,然后绘制开始游戏

接下来给画布添加点击事件,用于点击虚拟按键(位置是自己通过输出试出来的)

 

 

最后会初始化一些变量,包括了分数,速度,时间,场景

 

 

当点击开始游戏的时候会执行 game对象的 run 方法

 

 

主要的操作都在 start 方法中

 

方块对象

我创建了两个方块对象,一个是当前方块,一个是下一个方块

提供了 spawn 方法用来生成方块信息

当前方块代码如下

当前方块的信息都是从下一个方块的信息拷贝

当生成了当前方块,会生成新的下一个方块

 

下一个方块多了颜色集合

在生成方块的时候,会生成一个随机的方块,生成位置是预定义的

在生成方块中有一个init方法用于初始化一些方块信息

 

然后就是一些固定的位置设置

 

游戏逻辑执行

start() 方法主要用于界面的渲染

当游戏开始后,我们需要一直刷新整个canvas

在 game 对象中有一个二维数组代表场景

我们的方块一开始是不在场景内的,当方块完成放置的时才会加入场景

也就是说,场景内只有已放置的方块信息,具体值是颜色信息

具体操作

  • 绘制背景
  • 绘制当前方块
  • 绘制下一个方块
  • 绘制现有方块
  • 绘制时间,分数
  • 自动下降
  • 根据时间调整速度
  • 递归

代码如下

/** 开启游戏 */
	start: function() {
		// 游戏执行逻辑
		game.bg();
		// 分数, 游戏事件
		game.ctx.fillStyle = "white";
		game.ctx.fillText("分数:" + game.scope, 120, 60);
		game.ctx.fillText("坚持时间:" + Math.round(game.time), 250, 60);
		
		// 渲染方块
		game.ctx.fillStyle = cur.color;
		for (let i = 0; i < cur.num; i++) {
			game.ctx.fillRect(game.minX + game.size * cur.arrX[i], game.minY + game.size * cur.arrY[i], game.size, game.size);
		};
		// 渲染下一个方块
		game.ctx.fillStyle = nextCur.color;
		for (let i = 0; i < nextCur.num; i++) {
			game.ctx.fillRect(game.minX + 180 + game.size * nextCur.arrX[i], game.minY + game.size * nextCur.arrY[i], game.size, game.size);
		};
		// 渲染现有方块
		for (let i = 0; i < game.scene.length; i++) {
			for (let j = 0; j < game.scene[i].length; j++) {
				if (game.scene[i][j] != null) {
					game.ctx.fillStyle = game.scene[i][j];
					game.ctx.fillRect(game.minX + j * game.size, game.minY + i * game.size, game.size, game.size);
				}
			}
		}
		
		// 自动下降
		if (game.num++ == game.speed) {
			game.num = 0;
			gameEnv.down();
			
			// 调整速度, 最快为0.1s
			if (game.speed != 2) {
				game.speed = 10 - Math.round(game.time / 30);
			}
		}
		
		game.time += 0.05;
		
		// 游戏暂停则不继续
		if (!game.isPause) setTimeout("game.start()", 50);
	},

 

按键监听

 

交互事件(*)

封装成了一个对象 gameEnv

里面有 变换,加速,左,右,直接到底 的方法

思路

当我们触发左事件时,方块会向左移动,因为之前的设计是将当前方块作为一个单独的对象,所以我们只需要修改对象中的坐标位置就行

  • 向左 x-1,当到边界不能往左
  • 向右 x+1,与向左同
  • 向下 y+1,当碰到其他方块或者到底部则完成放置
  • 向上,变换 顺时针旋转90度,需要自己一个一个去实现(大部分都是这么做的),除去正方形,需要实现6*4=24个if块
  • 直接到底,往下的操作需要判断,正好我们封装了向下的操作,我们只需要在向下方法中返回一个值,让我们知道是否放置完成就可以轻松实现此需求

 

结果判断,加分机制

当我们完成放置时,需要判断先判断游戏是否结束,然后判断是否有可以消除的方块,是则需要加分

如果游戏结束条件不成立,则开始下一个物体,并判断是否有可以消除的方块

  • 加分机制
    • 一行100
    • 两行200
    • 三行400
    • 四行800

 

 

暂停游戏

在暂停方法中,会去调用一个名 pause 的方法

 

游戏结束


在线试玩

https://1711680493.github.io/Tetris/index.html

 

源码

在我的 github 中的 Tetris 中,可以点下方链接进入,查看里面的介绍获取

https://github.com/1711680493/Application

别忘了点 Star~

 

1、一个用于摆放小型正方形的平面虚拟场地,其标准大小:宽为10,列高为20,以每个小正方形为单位。 七喜安卓网2、一组由4个小型正方形组成的规则图形,英文称为Tetromino,中文通称为方块共有7种,分别以S、Z、L、J、I、O、T这7个字母的形状来命名。 I:一次最多消除四层 J(左右):最多消除三层,或消除二层 L:最多消除三层,或消除二层 O:消除一至二层 S(左右):最多二层,容易造成孔洞 Z (左右):最多二层,容易造成孔洞 T:最多二层 (1)部分游戏有单格方块,可以穿透固定的方块到达最下层空位。其他的改中出现更多特别的造型。 方块会从区域上方开始缓慢继续落下。 (2)玩家可以做的操作有:以90度为单位旋转方块,以格子为单位左右移动方块,让方块加速落下。 (3)方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的方块出现在区域上方开始落下。 (4)当区域中某一列横向格子全部由方块填满,则该列会消失并成为玩家的得分。同时删除的列数越多,得分指数上升。 (5)当固定的方块堆到区域最上方而无法消除层数时,则游戏结束。 (6)一般来说,游戏还会提示下一个要落下的方块,熟练的玩家会计算到下一个方块,评估要如何进。由于游戏能不断进下去对商业用游戏不太理想,所以一般还会随着游戏的进而加速提高难度。 3、通过设计者预先设置的随机发生器不断地输出单个方块到场地顶部,以一定的规则进移动、旋转、下落和摆放,锁定并填充到场地中。每次摆放如果将场地的一或多完全填满,则组成这些的所有小正方形将被消除,并且以此来换取一定的积分或者其他形式的奖励。而未被消除的方块会一直累积,并对后来的方块摆放造成各种影响。 4、如果未被消除的方块堆放的高度超过场地所规定的最大高度(并不一定是20或者玩家所能见到的高度),则游戏结束。 具体到每一款不同的游戏,其中的细节规则都可能有千差万别,但是以上的基本规则是相同的。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HackShendi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值