当前位置:网站首页>Road to simple HTML + JS to achieve the most simple game Tetris
Road to simple HTML + JS to achieve the most simple game Tetris
2020-11-06 21:04:00 【kingapple】
Preface
To be honest, this is actually the second Tetris I wrote .
This rewrite , Besides reviewing the code I wrote before , There are also some new ideas .
One of the most important purposes is to separate the rendering layer from the logic layer at the code level ( Redesign the code ).
—— The final effect is as follows .
On the subject
Take a look at some of the concepts and logic of Tetris
One 、 square
The most traditional Tetris , Only 7 Square block .
Usually by T、I、Z、S、L、J、O this 7 One letter instead of .
Convert to code as follows .
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]],
],
};
The code above has two sets of squares .( Matrix , No lift )
There is no direct connection between the two , They are two ideas derived from rotating squares .
The biggest difference between the two is , The rotation of the first group of matrix blocks needs to be converted by relevant algorithms , Relatively complex .
And the second group , We have enumerated the rotation results of U.S. and Chinese squares , Better to understand .
The first box option
let shapData = shaps['T']
// Rotate the matrix by algorithm
shapData = matirx2dRotation(shapData)
const shapRender = (vector) => {
// It's a little different from enumeration
}
The second kind of square rotation
// For example, the following code can be directly removed T One of the rotation data of the square
// Each vector in this data plus the square offset in the scene of the block is the rendering data of the block
const shapData = enumShaps['T'][1]
// vector Offset ( It's the location of the square in the scene )
const shapRender = (vector) => {
return shapData.map(([x, y]) => [x + X, y + Y]);
}
The above complete code is in the bottom warehouse address
Two 、 Collision and logic
The standard situation , Only one square in the scene receives player action .
The player's box is generated and handed over to the player after the game begins .
Player controlled squares , Every time the player operates feedback, the collision logic is detected .
The operation feedback here is mainly on the left side of the block 、 Right 、 Move down and rotate .
- Whether the square overflows the scene ( The left and right sides of the scene collide with the bottom boundary )
- Whether the square collides with the static square in the scene
Every game heartbeat interval , You also need to drop the block controlled by the current player by one space .
Whether it is the player's active block drop or the game heartbeat interval will automatically drop the box . We need to detect whether it collides with the bottom of the scene or other static squares .
If the collision holds up , Add the current block to the static block sequence .
At this point, you can execute the logic of the small block .
You need to fill the vacant position after playing the square .
Finally, a new box is generated and added to the scene .
As the new box enters the scene , You need to detect collisions with still squares immediately . If true, then the game is game over.
// Block static logic
const isShapDead = vector => {
// ... If true, it is added to the sequence of static squares
}
// Whether it overflows the scene
// No need to detect the top
const isOverFlow = vectors => {
const [width, height] = screenSize;
return vectors.some(([x, y]) => {
return x < 0 || x >= width || y >= height;
});
}
// Is there a collision
const isShapHit = vectors => {
// ...
}
// Whether the game fails
const isGameOver = data => {
// Square initial position vector
const [, y] = vector;
if (y <= 0 && isShapHit(data)) {
return true;
}
return false;
}
The above complete code is in the bottom warehouse address
3、 ... and 、 The rendering layer is separated from the logic layer
Every time the game beats , With every user action feedback will trigger rendering
Maybe it's been separating the front and back for some time , A little bit virtual dom A little bit of an impact on .
Redesigned code , Virtualize the whole process of the game .
Only in every heartbeat ( Similar to the concept of frames in the game ) Or the user will push the game virtual data to the rendering layer after each active operation , The rendering logic is implemented by the render layer .
// TetrisJS The logic code of the whole game
const TJS = new TetrisJS({
screenSize,
intervals: 1000,
});
// update To accept the push of the rendering request in the callback letter of
TJS.update(() => {
// TJS.map It's the virtual data of the game
renderGame(TJS.map)
});
const renderGame = data => {
// render Rendering logic
}
Finally, code the warehouse ( The above code is based on this )https://github.com/applelee/tetris-js.git
Old code ( Be careful )https://github.com/applelee/tetris-js-old.git
版权声明
本文为[kingapple]所创,转载请带上原文链接,感谢
边栏推荐
- Asp.Net Core learning notes: Introduction
- To Lianyun analysis: why is IPFs / filecoin mining so difficult?
- ES中删除索引的mapping字段时应该考虑的点
- CCR coin frying robot: the boss of bitcoin digital currency, what you have to know
- An article will introduce you to CSS3 background knowledge
- What is the meaning of sector sealing of filecoin mining machine since the main network of filecoin was put online
- 代码重构之法——方法重构分析
- GitHub: the foundation of the front end
- ES6 learning notes (4): easy to understand the new grammar of ES6
- What knowledge do Python automated testing learn?
猜你喜欢
嘉宾专访|2020 PostgreSQL亚洲大会阿里云数据库专场:曾文旌
ORA-02292: 违反完整约束条件 (MIDBJDEV2.SYS_C0020757) - 已找到子记录
An article will introduce you to HTML tables and their main attributes
Get twice the result with half the effort: automation without cabinet
Use modelarts quickly, zero base white can also play AI!
游戏主题音乐对游戏的作用
面试官: ShardingSphere 学一下吧
Axios learning notes (2): easy to understand the use of XHR and how to package simple Axios
ES6 learning notes (3): teach you to use js object-oriented thinking to realize the function of adding, deleting, modifying and checking tab column
谷歌浏览器实现视频播放加速功能
随机推荐
Basic usage of GDB debugging
What course of artificial intelligence? Will it replace human work?
hdu3974 Assign the task線段樹 dfs序
ERD-ONLINE 免费在线数据库建模工具
Flink's datasource Trilogy: direct API
Helping financial technology innovation and development, atfx is at the forefront of the industry
CloudQuery V1.2.0 版本发布
【转发】查看lua中userdata的方法
What are PLC Analog input and digital input
美团内部讲座|周烜:华东师范大学的数据库系统研究
Some operations kept in mind by the front end foundation GitHub warehouse management
游戏开发中的新手引导与事件管理系统
代码重构之法——方法重构分析
What is the purchasing supplier system? Solution of purchasing supplier management platform
意派Epub360丨你想要的H5模板都在这里,电子书、大转盘、红包雨、问卷调查……
CCR coin frying robot: the boss of bitcoin digital currency, what you have to know
Outsourcing is really difficult. As an outsourcer, I can't help sighing.
開源一套極簡的前後端分離專案腳手架
An article taught you to download cool dog music using Python web crawler
The AI method put forward by China has more and more influence. Tianda et al. Mined the development law of AI from a large number of literatures