Skip to content

Commit 8e29429

Browse files
authored
Merge pull request #742 from luv2027/Created_Tetris_Game
Created Tetris game using js
2 parents 3fa2eb5 + 9bbed93 commit 8e29429

File tree

11 files changed

+640
-0
lines changed

11 files changed

+640
-0
lines changed

TetrisGame/luv2027/Tetris Game.gif

1.04 MB
Loading

TetrisGame/luv2027/css/js/app.js

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
document.addEventListener('DOMContentLoaded', () => {
2+
const GRID_WIDTH = 10
3+
const GRID_HEIGHT = 20
4+
const GRID_SIZE = GRID_WIDTH * GRID_HEIGHT
5+
6+
7+
const grid = createGrid();
8+
let squares = Array.from(grid.querySelectorAll('div'))
9+
const startBtn = document.querySelector('.button')
10+
const hamburgerBtn = document.querySelector('.toggler')
11+
const menu = document.querySelector('.menu')
12+
const span = document.getElementsByClassName('close')[0]
13+
const scoreDisplay = document.querySelector('.score-display')
14+
const linesDisplay = document.querySelector('.lines-score')
15+
let currentIndex = 0
16+
let currentRotation = 0
17+
const width = 10
18+
let score = 0
19+
let lines = 0
20+
let timerId
21+
let nextRandom = 0
22+
const colors = [
23+
'url(images/blue_block.png)',
24+
'url(images/pink_block.png)',
25+
'url(images/purple_block.png)',
26+
'url(images/peach_block.png)',
27+
'url(images/yellow_block.png)'
28+
]
29+
30+
31+
function createGrid() {
32+
33+
let grid = document.querySelector(".grid")
34+
for (let i = 0; i < GRID_SIZE; i++) {
35+
let gridElement = document.createElement("div")
36+
grid.appendChild(gridElement)
37+
}
38+
39+
40+
for (let i = 0; i < GRID_WIDTH; i++) {
41+
let gridElement = document.createElement("div")
42+
gridElement.setAttribute("class", "block3")
43+
grid.appendChild(gridElement)
44+
}
45+
46+
let previousGrid = document.querySelector(".previous-grid")
47+
48+
for (let i = 0; i < 16; i++) {
49+
let gridElement = document.createElement("div")
50+
previousGrid.appendChild(gridElement);
51+
}
52+
return grid;
53+
}
54+
55+
56+
57+
function control(e) {
58+
if (e.keyCode === 39)
59+
moveright()
60+
else if (e.keyCode === 38)
61+
rotate()
62+
else if (e.keyCode === 37)
63+
moveleft()
64+
else if (e.keyCode === 40)
65+
moveDown()
66+
}
67+
68+
document.addEventListener('keydown', control)
69+
70+
71+
const lTetromino = [
72+
[1, GRID_WIDTH + 1, GRID_WIDTH * 2 + 1, 2],
73+
[GRID_WIDTH, GRID_WIDTH + 1, GRID_WIDTH + 2, GRID_WIDTH * 2 + 2],
74+
[1, GRID_WIDTH + 1, GRID_WIDTH * 2 + 1, GRID_WIDTH * 2],
75+
[GRID_WIDTH, GRID_WIDTH * 2, GRID_WIDTH * 2 + 1, GRID_WIDTH * 2 + 2]
76+
]
77+
78+
const zTetromino = [
79+
[0, GRID_WIDTH, GRID_WIDTH + 1, GRID_WIDTH * 2 + 1],
80+
[GRID_WIDTH + 1, GRID_WIDTH + 2, GRID_WIDTH * 2, GRID_WIDTH * 2 + 1],
81+
[0, GRID_WIDTH, GRID_WIDTH + 1, GRID_WIDTH * 2 + 1],
82+
[GRID_WIDTH + 1, GRID_WIDTH + 2, GRID_WIDTH * 2, GRID_WIDTH * 2 + 1]
83+
]
84+
85+
const tTetromino = [
86+
[1, GRID_WIDTH, GRID_WIDTH + 1, GRID_WIDTH + 2],
87+
[1, GRID_WIDTH + 1, GRID_WIDTH + 2, GRID_WIDTH * 2 + 1],
88+
[GRID_WIDTH, GRID_WIDTH + 1, GRID_WIDTH + 2, GRID_WIDTH * 2 + 1],
89+
[1, GRID_WIDTH, GRID_WIDTH + 1, GRID_WIDTH * 2 + 1]
90+
]
91+
92+
const oTetromino = [
93+
[0, 1, GRID_WIDTH, GRID_WIDTH + 1],
94+
[0, 1, GRID_WIDTH, GRID_WIDTH + 1],
95+
[0, 1, GRID_WIDTH, GRID_WIDTH + 1],
96+
[0, 1, GRID_WIDTH, GRID_WIDTH + 1]
97+
]
98+
99+
const iTetromino = [
100+
[1, GRID_WIDTH + 1, GRID_WIDTH * 2 + 1, GRID_WIDTH * 3 + 1],
101+
[GRID_WIDTH, GRID_WIDTH + 1, GRID_WIDTH + 2, GRID_WIDTH + 3],
102+
[1, GRID_WIDTH + 1, GRID_WIDTH * 2 + 1, GRID_WIDTH * 3 + 1],
103+
[GRID_WIDTH, GRID_WIDTH + 1, GRID_WIDTH + 2, GRID_WIDTH + 3]
104+
]
105+
106+
const theTetrominoes = [lTetromino, zTetromino, tTetromino, oTetromino, iTetromino]
107+
108+
109+
let random = Math.floor(Math.random() * theTetrominoes.length)
110+
let current = theTetrominoes[random][currentRotation]
111+
112+
113+
114+
let currentPosition = 4
115+
116+
function draw() {
117+
current.forEach(index => {
118+
squares[currentPosition + index].classList.add('block')
119+
squares[currentPosition + index].style.backgroundImage = colors[random]
120+
})
121+
}
122+
123+
function undraw() {
124+
current.forEach(index => {
125+
squares[currentPosition + index].classList.remove('block')
126+
squares[currentPosition + index].style.backgroundImage = 'none'
127+
})
128+
}
129+
130+
131+
function moveDown() {
132+
undraw()
133+
currentPosition = currentPosition += width
134+
draw()
135+
freeze()
136+
}
137+
138+
startBtn.addEventListener('click', () => {
139+
if (timerId) {
140+
clearInterval(timerId)
141+
timerId = null
142+
} else {
143+
draw()
144+
timerId = setInterval(moveDown, 1000)
145+
nextRandom = Math.floor(Math.random() * theTetrominoes.length)
146+
displayShape()
147+
}
148+
})
149+
150+
151+
function moveright() {
152+
undraw()
153+
const isAtRightEdge = current.some(index => (currentPosition + index) % width === width - 1)
154+
if (!isAtRightEdge) currentPosition += 1
155+
if (current.some(index => squares[currentPosition + index].classList.contains('block2'))) {
156+
currentPosition -= 1
157+
}
158+
draw()
159+
}
160+
161+
162+
function moveleft() {
163+
undraw()
164+
const isAtLeftEdge = current.some(index => (currentPosition + index) % width === 0)
165+
if (!isAtLeftEdge) currentPosition -= 1
166+
if (current.some(index => squares[currentPosition + index].classList.contains('block2'))) {
167+
currentPosition += 1
168+
}
169+
draw()
170+
}
171+
172+
173+
function freeze() {
174+
175+
if (current.some(index => squares[currentPosition + index + width].classList.contains('block3') || squares[currentPosition + index + width].classList.contains('block2'))) {
176+
177+
current.forEach(index => squares[index + currentPosition].classList.add('block2'))
178+
179+
random = nextRandom
180+
nextRandom = Math.floor(Math.random() * theTetrominoes.length)
181+
current = theTetrominoes[random][currentRotation]
182+
currentPosition = 4
183+
draw()
184+
displayShape()
185+
addScore()
186+
gameOver()
187+
}
188+
}
189+
freeze()
190+
191+
192+
function rotate() {
193+
undraw()
194+
currentRotation++
195+
if (currentRotation === current.length) {
196+
currentRotation = 0
197+
}
198+
current = theTetrominoes[random][currentRotation]
199+
draw()
200+
}
201+
202+
203+
function gameOver() {
204+
if (current.some(index => squares[currentPosition + index].classList.contains('block2'))) {
205+
scoreDisplay.innerHTML = 'end'
206+
clearInterval(timerId)
207+
}
208+
}
209+
210+
211+
const displayWidth = 4
212+
const displaySquares = document.querySelectorAll('.previous-grid div')
213+
let displayIndex = 0
214+
215+
const smallTetrominoes = [
216+
[1, displayWidth + 1, displayWidth * 2 + 1, 2], /* lTetromino */
217+
[0, displayWidth, displayWidth + 1, displayWidth * 2 + 1], /* zTetromino */
218+
[1, displayWidth, displayWidth + 1, displayWidth + 2], /* tTetromino */
219+
[0, 1, displayWidth, displayWidth + 1], /* oTetromino */
220+
[1, displayWidth + 1, displayWidth * 2 + 1, displayWidth * 3 + 1] /* iTetromino */
221+
]
222+
223+
function displayShape() {
224+
displaySquares.forEach(square => {
225+
square.classList.remove('block')
226+
square.style.backgroundImage = 'none'
227+
})
228+
smallTetrominoes[nextRandom].forEach(index => {
229+
displaySquares[displayIndex + index].classList.add('block')
230+
displaySquares[displayIndex + index].style.backgroundImage = colors[nextRandom]
231+
})
232+
}
233+
234+
235+
function addScore() {
236+
for (currentIndex = 0; currentIndex < GRID_SIZE; currentIndex += GRID_WIDTH) {
237+
const row = [currentIndex, currentIndex + 1, currentIndex + 2, currentIndex + 3, currentIndex + 4, currentIndex + 5, currentIndex + 6, currentIndex + 7, currentIndex + 8, currentIndex + 9]
238+
if (row.every(index => squares[index].classList.contains('block2'))) {
239+
score += 10
240+
lines += 1
241+
scoreDisplay.innerHTML = score
242+
linesDisplay.innerHTML = lines
243+
row.forEach(index => {
244+
squares[index].style.backgroundImage = 'none'
245+
squares[index].classList.remove('block2') || squares[index].classList.remove('block')
246+
247+
})
248+
249+
const squaresRemoved = squares.splice(currentIndex, width)
250+
squares = squaresRemoved.concat(squares)
251+
squares.forEach(cell => grid.appendChild(cell))
252+
}
253+
}
254+
}
255+
256+
257+
hamburgerBtn.addEventListener('click', () => {
258+
menu.style.display = 'flex'
259+
})
260+
span.addEventListener('click', () => {
261+
menu.style.display = 'none'
262+
})
263+
264+
})

0 commit comments

Comments
 (0)