当前位置:网站首页>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]所创,转载请带上原文链接,感谢
边栏推荐
- 開源一套極簡的前後端分離專案腳手架
- mongo 用户权限 登录指令
- What are Devops
- Zero basis to build a web search engine of its own
- What are PLC Analog input and digital input
- 【ElasticSearch搜索引擎】
- What knowledge do Python automated testing learn?
- An article will take you to understand SVG gradient knowledge
- Some operations kept in mind by the front end foundation GitHub warehouse management
- 意外的元素..所需元素..
猜你喜欢

Using an example to understand the underlying processing mechanism of JS function

JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m

This project allows you to quickly learn about a programming language in a few minutes

行为型模式之备忘录模式

大会倒计时|2020 PostgreSQL亚洲大会-中文分论坛议程安排

Vue communication and cross component listening state Vue communication

window系统 本机查找端口号占用方法

2020年第四届中国 BIM (数字建造)经理高峰论坛即将在杭举办

ES6 learning notes (5): easy to understand ES6's built-in extension objects

Junit测试出现 empty test suite
随机推荐
What knowledge do Python automated testing learn?
C語言I部落格作業03
Asp.Net Core learning notes: Introduction
一路踩坑,被迫聊聊 C# 代码调试技巧和远程调试
What is the tensor in tensorflow?
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
统计项目代码行数
Top 5 Chinese cloud manufacturers in 2018: Alibaba cloud, Tencent cloud, AWS, telecom, Unicom
Building a new generation cloud native data lake with iceberg on kubernetes
事件监听问题
消息队列(MessageQueue)-分析
Behind the record breaking Q2 revenue of Alibaba cloud, the cloud opening mode is reshaping
解决 WPF 绑定集合后数据变动界面却不更新的问题
【自学unity2d传奇游戏开发】地图编辑器
What course of artificial intelligence? Will it replace human work?
Get twice the result with half the effort: automation without cabinet
Even liver three all night, jvm77 high frequency interview questions detailed analysis, this?
ORA-02292: 违反完整约束条件 (MIDBJDEV2.SYS_C0020757) - 已找到子记录
Try to build my mall from scratch (2): use JWT to protect our information security and perfect swagger configuration
Will blockchain be the antidote to the global epidemic accelerating the transformation of Internet enterprises?