游戏地址:

俄罗斯方块 | Tetris​zhangxiaoleiwk.gitee.io

看着眼熟?没错,UI 模仿了tetr.js,但代码是自己写的。

只支持电脑端,不知道键位可以点击设置查看。

游戏用纯 JavaScript、HTML、CSS 实现,图形用 canvas。

支持 SRS、DAS、ARR。

有一个设置面板,可以修改键位以及相关参数。

有一个本地的排行榜,可以记录自己的最好的十次战绩。

farter 在游戏细节上给予许多指导,但受限于作者自身技术水平,以及对游戏的理解,许多地方做的并不好。

作者并非码农,代码以能实现功能为主,比较随意。

后记:

虽然游戏的功能简单,但是玩了有一段时间,感觉稳定性不错,在 Edge chromium 浏览器上表现很好。

分辨率

每次调整屏幕分辨率,所有图形都会进行重绘,游戏在全屏模式下体验最好,为此,我还专门做了一个全屏的按钮。

过度动画

游戏有个我特别喜欢的特性,就是下落动画,看起来很简单,实现起来还是费了一番功夫。能实现这个,是因为游戏本身采用了双 canvas 设计。就像 Ps 的图层一样,背景和移动方块、阴影是分开的,这样不用每次更新图形重绘整个区域。这个设计是借鉴 tetr.js 的,但是它是采用三个图层,我看它 dom 的名字,应该是把 背景、移动方块、阴影全部分离。我在设计的时候做了一些简化,只做两个图层,这为消行动画的实现打下了基础。

消行动画是采用上下图层遮挡实现的,大致原理是,每次消行的时候,把背景图层消除部分以上的图形区域一帧一帧的绘制到前面图层,每一帧都移动一个距离,这样就达到一个动画效果。我最满意的地方是,在应对隔行消除的时候,它会依次从下往上显示过度动画,这样就达到一个很自然下落的过程,这个算法的实现我很喜欢。虽然从玩的角度,这个功能是拖累体验的,但是我实在喜欢这个实现。

更离谱的是,因为图形刷新采用 requestanimationframe 这个 API,根据官方的介绍,我不太确定这个API执行和屏幕刷新之间的确切关系,比如 144 hz的屏幕,这个 API 会以 1000 / 144的毫秒的间隔刷新吗?之所以在乎这个,是因为我把图形动画的移动计算也放在这个 API 里了。如果刷新的速度不一致,则意味着图形动画的移动速度不一致,因为动画帧数帧数分配是移动距离除以帧率,虽然多数电脑似乎都是 60hz,但是如果有 144hz呢,这个API的频率是多少呢?所以我搞了一个特别奇葩的设计,就是玩家第一次点开游戏的第一秒种里,程序会计算玩家电脑这个 API 的刷新率,然后和键位设置游戏数据等保存在本地。说了这么多,这其实是个很简单的东西。

在 Edge chromium 下,动画看着不错,但在最新的 Firefox 下,表现明显不如前者流畅。

SRS 旋转系统

我在中文网上几乎没有看到有关 SRS 的详细介绍,这里我说一说我所实现的 SRS。

所谓 SRS,就是方块的旋转系统。最开始我不懂 SRS,所以一直搞不懂 farter 说的方块钻来钻去。后来过了一年多,无意中在 B 站看到的一个介绍 SRS 的视频,突然明白了,这也是我在一年后又去完善游戏的原因。

流程大致是这样:方块预旋转完成,检测是否发生碰撞,如果没有发生碰撞,则旋转完成;如果发生碰撞,则开始进行所谓踢墙。把预旋转的方块和数组里面的数据依次计算,就是加、减X, Y轴。比如 [-1, 0] 就是把方块向左移动一格,以次类推就可以理解。一个数组有四个数据,依次尝试,尝试成功则旋转成功,四个尝试全部失败,则把用来保存上一个状态的方块的数据替换掉现在的状态,这意味啥也没变。

所谓旋转方块是说,一般程序会用两个数组保存移动的方块。比如你要移动方块,可以先移动一个数组的数据(作为预旋转),如果移动成功,则把数据复制到另一个数组(后一个状态),如果失败(比如移动的墙里去了,判定冲突),则把后一个状态的数组复制过来,就是啥也没动。程序绘制图形的时候,只需要绘制后一个状态的数组。

每个数组前面的类似 '0R' 的数据,是表示这个数据是用在某一个状态的,所以程序自身应该记录方块的状态,以匹配应该使用哪个数据。具体的内容可以看图片里的网址,虽然是英文的,但教程里的图片解释的很清楚。


更新:2020-7-13

  1. 做了一个消除方块的过度动画,虽然没有什么用,但是觉得这样的实现非常有意思。尤其是在应对隔行消除方块的时候,可以模仿自然的下落过程,感觉很有趣。
  2. 每次移动或者旋转,都会重置延时锁定的计时。
  3. 锁定或得分时有音效效果。
  4. 视觉效果以及一些计算细节的改进。

更新:2020-5-11

  1. 方块绘制改为提前绘制,浏览器尺寸变化,方块会进行重绘,以适应屏幕分辨率。
  2. 图形用两层 canvas 实现,一层为死方块,一层为移动的方块和阴影。避免每一帧的绘制都需要重绘整个图形。
  3. 候选方块由一个增加到六个。
  4. 设置面板做了一些补充,修改 DAS ARR 时,把以前的直接输入时间改为 1 ~ 10 的等级调整,感觉毫秒这个时间单位不容易感知。

java程序里繁体字显示为方块_网页 俄罗斯方块相关推荐

  1. java结果分行显示_编写一个java程序。分行显示自己的姓名,地址,电话!用Test.java命名。_学小易找答案...

    [单选题]16.骨骼肌进行完全强直收缩时,相邻两次刺激的时间间隔应 [填空题]实习岗位名称 [单选题]神经调节的基本方式是: [单选题]Thank you for your nice gifts. - ...

  2. java中web错误返回码,关于在java程序里调用webservice报500返回码的有关问题

    关于在java程序里调用webservice报500返回码的问题 我现在写了个程序,是调用webservice的,执行后我打印返回码是500  错误信息是 java.io.IOException: S ...

  3. 编写java程序用用于显示人姓名和年龄

    /*编写java程序用用于显示人姓名和年龄. 定义一个人类Person该类中应该有两个私有属性姓名name和年龄age. 定义构造方法用来初始化数据成员.再定义显示display方法将姓名和年龄打印出 ...

  4. 编写Java程序,用于显示人的姓名和年龄

    编写Java程序,用于显示人的姓名和年龄 定义一个人类(Person),该类中应该有两个私有属性,姓名(name)和年龄(age).定义构造方法,用来初始化数据成员.再定义显示(display)方法, ...

  5. java程序员一般用什么笔记本_购买适合程序员编程开发用的笔记本电脑的几点建议...

    Hello,everybody!最近在论坛里看到很多人在问购买程序员编程用的笔记本电脑有什么建议,作为一名前Java程序员,我说说我工作几年后对笔记本电脑要求的几点建议,也希望看到这篇文章的朋友,内心 ...

  6. java程序编译错误属于异常吗_“Cannot find symbol”编译错误是什么意思?

    "Cannot find symbol"编译错误是什么意思? 1."Cannot find symbol"错误是什么意思? 首先,它是编译错误1.这意味着,无论 ...

  7. java vo转map_Jython:在 Java 程序里运行 Python 代码 4.5

    彭翌 彭翌,网易游戏资深运维开发工程师,从事大数据相关的基础架构平台研发工作,业余时间也关注分布式系统等相关领域. 前言 众所周知,JVM 在大数据基础架构领域可以说是独占鳌头,当我们需要开发大数据处 ...

  8. java程序源代码如何保存到桌面_如何编写JAVA小白第一个程序

    学习上一篇文章之后,确定好JDK和环境变量都成功之后,我们来编写我们第一个java程序命名为HelloWorld.java. 上一篇文章链接:JDK下载与环境变量的安装 桌面上右击,新建一个文本文档 ...

  9. java中GUI中显示当前时间_【java编程】返回当地时间Clock到GUI面板Panel上

    用java编程:返回当地时间到GUI面板上. ClockPanel.java /* * To change this template, choose Tools | Templates * and ...

最新文章

  1. 2021年大数据Flink(五):Standalone-HA高可用集群模式
  2. mysql基础之视图
  3. 基于组件的.NET软件开发(3)
  4. 【实战】烂泥:net use命令使用(一)
  5. java connection 可以有多个statement 吗,JDBC多线程多个statement共享同一个connection
  6. 执行 pip3 install selenium 时出现 fail to create process
  7. hdu 3879(最小割模型求解最大权闭合图)
  8. python前端代码_python前端HTML
  9. 2021中国到店消费新趋势洞察报告
  10. 作为程序员我是如何对事物进行分析的
  11. 什么是创新?如何创新?
  12. ZKWeb网页框架1.3正式发布
  13. Selenium2+python自动化18-加载Firefox配置
  14. SqlServer Alwayson 搭建报错:19405
  15. 【poj2373】Dividing the Path【单调队列优化dp】
  16. 三菱plc指令dediv_三菱PLC指令[]学习指导书.ppt
  17. Win7依靠“局域网共享软件.EXE”实现局域网资源共享简要操作流程
  18. java 502错误_nginx 502 超时错误解决(java版本)
  19. vue全局引入openlayers_vue+openlayers绘制省市边界线
  20. Linux基础(维护基本存储空间)

热门文章

  1. mysql目录下没有配置文件_MySQL没有my.cnf配置文件如何解决
  2. python合并列表重新排序_python实现的合并两个排序的列表
  3. 读tomcat源码,随笔类图
  4. pdo sqlite_ sqlite2 pdo_mysql_php使用pdo连接sqlite3的配置示例
  5. css3如何向上_html5 – 使用CSS3不断向上动画气泡?
  6. 2021年恩阳中学高考成绩查询,巴中市恩阳中学2021年排名
  7. 深度学习之基于Xception实现四种动物识别
  8. Parity Game CodeForces - 298C
  9. mysql第四章思考与练习答案_Mysql课后思考题
  10. php redis 集合返回多条,详解PHP多个进程配合redis的有序集合实现大文件去重