当前位置:网站首页>大道至简 html + js 实现最朴实的小游戏俄罗斯方块
大道至简 html + js 实现最朴实的小游戏俄罗斯方块
2020-11-06 21:04:00 【kingapple】
前言
老实说这其实这是自己写的第二个俄罗斯方块。
本次的重写,除了复习一下以前自己写的代码的同时,也加有了一些新的思考。
其中最重要的一个目的就是渲染层与逻辑层在代码层面的分离(重新设计代码)。
——最终效果图如下。

正题
来看下一下俄罗斯方块的一些概念与逻辑
一、方块
最传统的俄罗斯方块,只有7个方块。
通常由T、I、Z、S、L、J、O这7个字母代替。
转换成代码如下。
shaps = {
'I': [
[1, 1, 1, 1],
],
'L': [
[1, 1, 1],
[1, 0, 0],
],
'J': [
[1, 1, 1],
[0, 0, 1],
],
'Z': [
[1, 1, 0],
[0, 1, 1],
],
'S': [
[0, 1, 1],
[1, 1, 0],
],
'T': [
[1, 1, 1],
[0, 1, 0],
],
'O': [
[1, 1],
[1, 1],
],
};
enumShaps = {
'I': [
[[0,0],[1,0],[2,0],[3,0]],
[[1,-1],[1,0],[1,1],[1,2]],
],
'L':[
[[0,0],[1,0],[2,0],[0,1]],
[[0,0],[1,0],[1,1],[1,2]],
[[2,0],[0,1],[1,1],[2,1]],
[[0,0],[0,1],[0,2],[1,2]],
],
'J':[
[[0,0],[1,0],[2,0],[2,1]],
[[1,0],[1,1],[1,2],[0,2]],
[[0,0],[0,1],[1,1],[2,1]],
[[0,0],[1,0],[0,1],[0,2]],
],
'Z':[
[[0,0],[1,0],[1,1],[2,1]],
[[1,0],[1,1],[0,1],[0,2]],
],
'S':[
[[1,0],[2,0],[0,1],[1,1]],
[[0,0],[0,1],[1,1],[1,2]],
],
'T':[
[[0,0],[1,0],[2,0],[1,1]],
[[1,-1],[1,0],[1,1],[0,0]],
[[0,0],[1,0],[2,0],[1,-1]],
[[1,-1],[1,0],[1,1],[2,0]],
],
'O':[
[[1,0],[2,0],[1,1],[2,1]],
],
};
上面代码有两组方块。(矩阵型,没举型)
两者没有直接联系,是旋转方块衍生的两种思路。
两者最大的区别在于,第一组矩阵型方块的旋转需要相关算法进行换算,相对复杂。
而第二组,已经将美中方块的旋转结果枚举出来,更佳便于理解。
第一种方块选装
let shapData = shaps['T']
// 用算法旋转矩阵
shapData = matirx2dRotation(shapData)
const shapRender = (vector) => {
// 与枚举型略有不同
}
第二种方块旋转
// 比如下面代码接可以直接去除T方块的其中一个旋转数据
// 这个数据中的各个矢量再加上方块的场景中的方块偏移量就是方块的渲染数据了
const shapData = enumShaps['T'][1]
// vector 偏移量(就是方块在场景中的位置信息)
const shapRender = (vector) => {
return shapData.map(([x, y]) => [x + X, y + Y]);
}
以上完整代码在底部仓库地址中
二、碰撞与逻辑
标准的情况,场景中只有唯一一个方块收到玩家操作。
玩家操作的方块在游戏开始后便生成并交与玩家控制权。
玩家控制的方块,每当玩家操作反馈后进行碰撞逻辑的检测。
这里的操作反馈主要是方块左、右、下移动与旋转。
- 方块是否溢出场景(场景左右与底部边界碰撞)
- 方块是否碰撞场景中静止的方块
每次游戏心跳间隔,还需要将当前玩家控制的方块下降一格。
其中不论是玩家主动方块下降或是游戏心跳间隔中自动将方块下降。都需要检测是否与场景底部或其它静止方块发生碰撞与否。
如果碰撞成立,则将当前方块加入静止方块序列。
这时候就可以执行小方块的逻辑。
消玩方块后需要将空缺出来的位置补上。
最后生成一个新的方块加入到场景中。
新的方块进入场景的同时,需要立即检测与静止方块的碰撞。如果为真则游戏是否game over。
// 方块静止逻辑
const isShapDead = vector => {
// ...如果为真便加入到静止方块的序列
}
// 是否溢出场景
// 不需要检测顶部
const isOverFlow = vectors => {
const [width, height] = screenSize;
return vectors.some(([x, y]) => {
return x < 0 || x >= width || y >= height;
});
}
// 是否发生碰撞
const isShapHit = vectors => {
// ...
}
// 游戏是否失败
const isGameOver = data => {
// 方块初始位置矢量
const [, y] = vector;
if (y <= 0 && isShapHit(data)) {
return true;
}
return false;
}
以上完整代码在底部仓库地址中
三、渲染层与逻辑层分离
每一次游戏心跳,与每一次用户操作反馈会触发渲染
或许是做前后端分离有些时日了,多少受了虚拟dom的一点影响。
重新设计的代码,将游戏的整个过程虚拟化。
只在每一个心跳(类似游戏中帧的概念)或者用户每次主动操作后才会推送游戏虚拟数据到渲染层,由渲染层实现渲染逻辑。
// TetrisJS 整个游戏的逻辑代码
const TJS = new TetrisJS({
screenSize,
intervals: 1000,
});
// update 的回调函中接受渲染请求的推送
TJS.update(() => {
// TJS.map就是游戏的虚拟数据
renderGame(TJS.map)
});
const renderGame = data => {
// render 渲染逻辑
}
最后上仓库代码(以上代码基于此)https://github.com/applelee/tetris-js.git
老代码(慎点)https://github.com/applelee/tetris-js-old.git
版权声明
本文为[kingapple]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/1243524/blog/4540920
边栏推荐
- Simple summary of front end modularization
- ES6学习笔记(五):轻松了解ES6的内置扩展对象
- 一篇文章带你了解HTML表格及其主要属性介绍
- 5.4 static resource mapping
- Face to face Manual Chapter 16: explanation and implementation of fair lock of code peasant association lock and reentrantlock
- 前端基础牢记的一些操作-Github仓库管理
- How to use parameters in ES6
- Just now, I popularized two unique skills of login to Xuemei
- Vuejs development specification
- Process analysis of Python authentication mechanism based on JWT
猜你喜欢

一篇文章教会你使用Python网络爬虫下载酷狗音乐

Tool class under JUC package, its name is locksupport! Did you make it?

一篇文章带你了解CSS3圆角知识

The difference between gbdt and XGB, and the mathematical derivation of gradient descent method and Newton method

仅用六种字符来完成Hello World,你能做到吗?

有了这个神器,快速告别垃圾短信邮件

2019年的一个小目标,成为csdn的博客专家,纪念一下

Elasticsearch数据库 | Elasticsearch-7.5.0应用搭建实战

Filecoin主网上线以来Filecoin矿机扇区密封到底是什么意思

Interface pressure test: installation, use and instruction of siege pressure test
随机推荐
Face to face Manual Chapter 16: explanation and implementation of fair lock of code peasant association lock and reentrantlock
华为云“四个可靠”的方法论
Solve the problem of database insert data garbled in PL / SQL developer
I'm afraid that the spread sequence calculation of arbitrage strategy is not as simple as you think
Natural language processing - wrong word recognition (based on Python) kenlm, pycorrector
比特币一度突破14000美元,即将面临美国大选考验
IPFS/Filecoin合法性:保护个人隐私不被泄露
[C / C + + 1] clion configuration and running C language
ES6 essence:
How to use parameters in ES6
合约交易系统开发|智能合约交易平台搭建
Introduction to quantitative investment and Trading (Python introduction to financial analysis)
Vite + TS quickly build vue3 project and introduce related features
Free patent download tutorial (HowNet, Espacenet)
Jmeter——ForEach Controller&Loop Controller
一篇文章教会你使用Python网络爬虫下载酷狗音乐
Network security engineer Demo: the original * * is to get your computer administrator rights! 【***】
In order to save money, I learned PHP in one day!
Did you blog today?
前端基础牢记的一些操作-Github仓库管理