Нужно реализовать увеличение скорости падения фигуры с каждым убранным уровнем. Кажется уже всё перепробовал, уже глаза замылились. Кто поможет, тому буду безмерно благодарен.
"use strict";
(function() {
const canvas = document.getElementById("tetris");
const context = canvas.getContext("2d");
context.scale(20, 20);
let makeMatrix = function(w, h) {
const matrix = [];
while (h--) {
matrix.push(new Array(w).fill(0));
}
return matrix;
};
let makePiece = function(type) {
if (type === "i") {
return [
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0]
];
} else if (type === "j") {
return [
[0, 2, 0],
[0, 2, 0],
[2, 2, 0]
];
} else if (type === "l") {
return [
[0, 3, 0],
[0, 3, 0],
[0, 3, 3]
];
} else if (type === "o") {
return [
[4, 4],
[4, 4]
];
} else if (type === "s") {
return [
[0, 5, 5],
[5, 5, 0],
[0, 0, 0]
];
} else if (type === "t") {
return [
[0, 6, 0],
[6, 6, 6],
[0, 0, 0]
];
} else if (type === "z") {
return [
[7, 7, 0],
[0, 7, 7],
[0, 0, 0]
];
}
};
let points = function() {
let rowCount = 1;
outer: for (let y = area.length - 1; y > 0; --y) {
for (let x = 0; x < area[y].length; ++x) {
if (area[y][x] === 0) {
continue outer;
}
}
const row = area.splice(y, 1)[0].fill(0);
area.unshift(row);
++y;
player.score += rowCount;
}
}
let collide = function(area, player) {
const [m, o] = [player.matrix, player.pos];
for (let y = 0; y < m.length; ++y) {
for (let x = 0; x < m[y].length; ++x) {
if (m[y][x] !== 0 && (area[y + o.y] && area[y + o.y][x + o.x]) !== 0) {
return true;
}
}
}
return false;
};
let drawMatrix = function(matrix, offset) {
matrix.forEach((row, y) => {
row.forEach((value, x) => {
if (value !== 0) {
let imgTag = document.createElement("IMG");
imgTag.src = colors[value];
context.drawImage(imgTag, x + offset.x, y + offset.y, 1, 1);
}
});
});
};
let merge = function(area, player) {
player.matrix.forEach((row, y) => {
row.forEach((value, x) => {
if (value !== 0) {
area[y + player.pos.y][x + player.pos.x] = value;
}
});
});
};
let rotate = function(matrix, dir) {
for (let y = 0; y < matrix.length; ++y) {
for (let x = 0; x < y; ++x) {
[
matrix[x][y],
matrix[y][x]
] = [
matrix[y][x],
matrix[x][y],
]
}
}
if (dir > 0) {
matrix.forEach(row => row.reverse());
} else {
matrix.reverse();
}
};
let playerReset = function() {
const pieces = "ijlostz";
player.matrix = makePiece(pieces[Math.floor(Math.random() * pieces.length)]);
player.pos.y = 0;
player.pos.x = (Math.floor(area[0].length / 2)) - (Math.floor(player.matrix[0].length / 2));
if (collide(area, player)) {
area.forEach(row => row.fill(0));
player.score = 0;
gameRun = false;
}
};
let playerDrop = function() {
player.pos.y++;
if (collide(area, player)) {
player.pos.y--;
merge(area, player);
points();
playerReset();
}
};
let playerMove = function(dir) {
player.pos.x += dir;
if (collide(area, player)) {
player.pos.x -= dir;
}
};
let playerRotate = function(dir) {
const pos = player.pos.x;
let offset = 1;
rotate(player.matrix, dir);
while (collide(area, player)) {
player.pos.x += offset;
offset = -(offset + (offset > 0 ? 1 : -1));
if (offset > player.matrix[0].length) {
rotate(player.matrix, -dir);
player.pos.x = pos;
return;
}
}
};
let draw = function() {
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "#000000";
context.fillRect(0, 0, canvas.width, canvas.height);
updateScore();
drawMatrix(area, {
x: 0,
y: 0
});
drawMatrix(player.matrix, player.pos);
};
let dropInter = 100;
let time = 0;
let update = function() {
time++;
if (time >= dropInter) {
playerDrop();
time = 0;
}
draw();
};
let updateScore = function() {
context.font = "bold 1px Arial";
context.fillStyle = "#ffffff";
context.textAlign = "left";
context.textBaseline = "top";
context.fillText("Lines:" + player.score, 0.1, 0.1);
};
// let addSpeed = function() {
// if (updateScore > 0) {
// dropInter -= 5;
// }
// };
// addSpeed();
let gameOver = function() {
clearInterval(gameLoop);
context.font = "2px Arial";
context.fillStyle = "#ffffff";
context.textAlign = "center";
context.textBaseline = "middle";
context.fillText("GAME OVER", (canvas.width / 20) / 2, (canvas.width / 20) / 2);
document.getElementById("start_game").disabled = false;
};
const colors = [
null,
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxEAAAsRAX9kX5EAAABASURBVFhH7dcxEQAgDATBgBpkRiZugBnQQJq96tNtm7ZOUdgF5Hjn53JGf7MsAAAAAAAAAAAAAAAAAIDi9zxiA/4+DjI3K6uXAAAAAElFTkSuQmCC",
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxEAAAsRAX9kX5EAAABFSURBVFhH7dehEQAgDATBh5ZoAEvF2DRATcAwqYE3d+rj1qbsm4w9QB8rz7/FbKq5bQEAAAAAAAAAAAAAAAAAAADm91w6cr4PMmFrragAAAAASUVORK5CYII=",
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxEAAAsRAX9kX5EAAABGSURBVFhH7dcxEQAgDATBB3FowAs1XqIBc8Aw0cA3d9Wn2zZl32TsAdboef6tzVDNbQsAAAAAAAAAAAAAAAAAAAAwv+fSAYyGDzIDc/xyAAAAAElFTkSuQmCC",
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAGLH901AAAACXBIWXMAAAsSAAALEgHS3X78AAAAa0lEQVR4nGP5//8/AwywAPGy01YIDooMgoOiB66BoB5kldhVUSiB7C4UCaw2U9lyKkrgCiuSTRrVQJEGXOkJpwaSYi3K9Nhg9PSohlENODSQWi6RBMjJDqSCUQtGLRi1YNSCEWMBsFClnQUAHyUliPhfuZ4AAAAASUVORK5CYII=",
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxEAAAsRAX9kX5EAAABESURBVFhH7dcxEQAgDATBB3lYAHnEAvaAYaKBb+6qT7dtyr7J2APMFnn+bayumtsWAAAAAAAAAAAAAAAAAAAAYH7PpQOPVg8yEVQxkwAAAABJRU5ErkJggg==",
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxEAAAsRAX9kX5EAAABFSURBVFhH7dehEQAgDATBhxLwSPovCBlPC8AwqYE3d+rj1qbsm4w9wOojz7+1mKq5bQEAAAAAAAAAAAAAAAAAAADm91w6YO4PMgLP8KUAAAAASUVORK5CYII=",
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAABCSURBVFhH7dcxEQAgDATBgAHc4L/GDQqAGdBAmr3q022bsk6R2AWM9s7P9Rn1zbQAAAAAAAAAAAAAAAAAAJLf84gNFUUOMkwQM24AAAAASUVORK5CYII="
];
const area = makeMatrix(14, 22);
const player = {
pos: {
x: 0,
y: 0
},
matrix: null,
score: 0
};
const move = 1;
let gameLoop;
let gameRun = false;
playerReset();
draw();
gameOver();
document.addEventListener('keydown', function(e) {
if (e.keyCode === 37) {
playerMove(-move);
} else if (e.keyCode === 39) {
playerMove(+move);
} else if (e.keyCode === 38) {
playerRotate(-move);
} else if (e.keyCode === 40) {
playerDrop();
}
});
document.getElementById("start_game").onclick = function() {
gameRun = true;
playerReset();
let t = 10;
gameLoop = setInterval(function() {
if (gameRun) {
update();
} else {
gameOver();
}
}, t);
this.disabled = false;
};
})();
body {
background-color: #737373;
}
* {
margin: 0;
padding: 0;
}
.canvas_wrap {
display: block;
margin: 0 auto;
padding-top: 25px;
}
.canvas_wrap>* {
display: block;
margin: 0 auto;
border: 1px solid #ffffff;
}
.canvas_wrap>button {
font-family: Arial, Helvetica, sans-serif;
font-size: 30px;
font-weight: bold;
border: none;
color: #ffffff;
background-color: #000000;
padding: 5px;
margin: 10px auto;
border: 1px solid #000000;
outline: none;
}
.canvas_wrap>button:hover {
cursor: pointer;
background-color: #ffffff;
color: #000000;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Tetris</title>
<link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAGLH901AAAACXBIWXMAAAsSAAALEgHS3X78AAAAa0lEQVR4nGP5//8/AwywAPGy01YIDooMgoOiB66BoB5kldhVUSiB7C4UCaw2U9lyKkrgCiuSTRrVQJEGXOkJpwaSYi3K9Nhg9PSohlENODSQWi6RBMjJDqSCUQtGLRi1YNSCEWMBsFClnQUAHyUliPhfuZ4AAAAASUVORK5CYII="
type="image/x-icon">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="canvas_wrap">
<canvas id="tetris" width="280" height="440"></canvas>
<button type="button" id="start_game">Start</button>
</div>
</body>
<script src="script.js"></script>
</html>
dropInter = Math.max(dropInter - 5, 20);
Имеет смысл рассмотреть вариант с переменным декрементом - уменьшающимся вместе с значением dropInter
.
"use strict";
(function() {
const canvas = document.getElementById("tetris");
const context = canvas.getContext("2d");
context.scale(20, 20);
let makeMatrix = function(w, h) {
const matrix = [];
while (h--) {
matrix.push(new Array(w).fill(0));
}
return matrix;
};
let makePiece = function(type) {
if (type === "i") {
return [
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0]
];
} else if (type === "j") {
return [
[0, 2, 0],
[0, 2, 0],
[2, 2, 0]
];
} else if (type === "l") {
return [
[0, 3, 0],
[0, 3, 0],
[0, 3, 3]
];
} else if (type === "o") {
return [
[4, 4],
[4, 4]
];
} else if (type === "s") {
return [
[0, 5, 5],
[5, 5, 0],
[0, 0, 0]
];
} else if (type === "t") {
return [
[0, 6, 0],
[6, 6, 6],
[0, 0, 0]
];
} else if (type === "z") {
return [
[7, 7, 0],
[0, 7, 7],
[0, 0, 0]
];
}
};
let points = function() {
let rowCount = 1;
outer: for (let y = area.length - 1; y > 0; --y) {
for (let x = 0; x < area[y].length; ++x) {
if (area[y][x] === 0) {
continue outer;
}
}
const row = area.splice(y, 1)[0].fill(0);
area.unshift(row);
/* *** */
dropInter = Math.max(dropInter - 10, 5);
console.log("dropInter =", dropInter);
++y;
player.score += rowCount;
}
}
let collide = function(area, player) {
const [m, o] = [player.matrix, player.pos];
for (let y = 0; y < m.length; ++y) {
for (let x = 0; x < m[y].length; ++x) {
if (m[y][x] !== 0 && (area[y + o.y] && area[y + o.y][x + o.x]) !== 0) {
return true;
}
}
}
return false;
};
let drawMatrix = function(matrix, offset) {
matrix.forEach((row, y) => {
row.forEach((value, x) => {
if (value !== 0) {
let imgTag = document.createElement("IMG");
imgTag.src = colors[value];
context.drawImage(imgTag, x + offset.x, y + offset.y, 1, 1);
}
});
});
};
let merge = function(area, player) {
player.matrix.forEach((row, y) => {
row.forEach((value, x) => {
if (value !== 0) {
area[y + player.pos.y][x + player.pos.x] = value;
}
});
});
};
let rotate = function(matrix, dir) {
for (let y = 0; y < matrix.length; ++y) {
for (let x = 0; x < y; ++x) {
[
matrix[x][y],
matrix[y][x]
] = [
matrix[y][x],
matrix[x][y],
]
}
}
if (dir > 0) {
matrix.forEach(row => row.reverse());
} else {
matrix.reverse();
}
};
let playerReset = function() {
const pieces = "ijlostz";
player.matrix = makePiece(pieces[Math.floor(Math.random() * pieces.length)]);
player.pos.y = 0;
player.pos.x = (Math.floor(area[0].length / 2)) - (Math.floor(player.matrix[0].length / 2));
if (collide(area, player)) {
area.forEach(row => row.fill(0));
player.score = 0;
gameRun = false;
}
};
let playerDrop = function() {
player.pos.y++;
if (collide(area, player)) {
player.pos.y--;
merge(area, player);
points();
playerReset();
}
};
let playerMove = function(dir) {
player.pos.x += dir;
if (collide(area, player)) {
player.pos.x -= dir;
}
};
let playerRotate = function(dir) {
const pos = player.pos.x;
let offset = 1;
rotate(player.matrix, dir);
while (collide(area, player)) {
player.pos.x += offset;
offset = -(offset + (offset > 0 ? 1 : -1));
if (offset > player.matrix[0].length) {
rotate(player.matrix, -dir);
player.pos.x = pos;
return;
}
}
};
let draw = function() {
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "#000000";
context.fillRect(0, 0, canvas.width, canvas.height);
updateScore();
drawMatrix(area, {
x: 0,
y: 0
});
drawMatrix(player.matrix, player.pos);
};
let dropInter = 100;
let time = 0;
let update = function() {
time++;
if (time >= dropInter) {
playerDrop();
time = 0;
}
draw();
};
let updateScore = function() {
context.font = "bold 1px Arial";
context.fillStyle = "#ffffff";
context.textAlign = "left";
context.textBaseline = "top";
context.fillText("Lines:" + player.score, 0.1, 0.1);
};
// let addSpeed = function() {
// if (updateScore > 0) {
// dropInter -= 5;
// }
// };
// addSpeed();
let gameOver = function() {
clearInterval(gameLoop);
context.font = "2px Arial";
context.fillStyle = "#ffffff";
context.textAlign = "center";
context.textBaseline = "middle";
context.fillText("GAME OVER", (canvas.width / 20) / 2, (canvas.width / 20) / 2);
document.getElementById("start_game").disabled = false;
};
const colors = [
null,
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxEAAAsRAX9kX5EAAABASURBVFhH7dcxEQAgDATBgBpkRiZugBnQQJq96tNtm7ZOUdgF5Hjn53JGf7MsAAAAAAAAAAAAAAAAAIDi9zxiA/4+DjI3K6uXAAAAAElFTkSuQmCC",
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxEAAAsRAX9kX5EAAABFSURBVFhH7dehEQAgDATBh5ZoAEvF2DRATcAwqYE3d+rj1qbsm4w9QB8rz7/FbKq5bQEAAAAAAAAAAAAAAAAAAADm91w6cr4PMmFrragAAAAASUVORK5CYII=",
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxEAAAsRAX9kX5EAAABGSURBVFhH7dcxEQAgDATBB3FowAs1XqIBc8Aw0cA3d9Wn2zZl32TsAdboef6tzVDNbQsAAAAAAAAAAAAAAAAAAAAwv+fSAYyGDzIDc/xyAAAAAElFTkSuQmCC",
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAGLH901AAAACXBIWXMAAAsSAAALEgHS3X78AAAAa0lEQVR4nGP5//8/AwywAPGy01YIDooMgoOiB66BoB5kldhVUSiB7C4UCaw2U9lyKkrgCiuSTRrVQJEGXOkJpwaSYi3K9Nhg9PSohlENODSQWi6RBMjJDqSCUQtGLRi1YNSCEWMBsFClnQUAHyUliPhfuZ4AAAAASUVORK5CYII=",
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxEAAAsRAX9kX5EAAABESURBVFhH7dcxEQAgDATBB3lYAHnEAvaAYaKBb+6qT7dtyr7J2APMFnn+bayumtsWAAAAAAAAAAAAAAAAAAAAYH7PpQOPVg8yEVQxkwAAAABJRU5ErkJggg==",
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxEAAAsRAX9kX5EAAABFSURBVFhH7dehEQAgDATBhxLwSPovCBlPC8AwqYE3d+rj1qbsm4w9wOojz7+1mKq5bQEAAAAAAAAAAAAAAAAAAADm91w6YO4PMgLP8KUAAAAASUVORK5CYII=",
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAABCSURBVFhH7dcxEQAgDATBgAHc4L/GDQqAGdBAmr3q022bsk6R2AWM9s7P9Rn1zbQAAAAAAAAAAAAAAAAAAJLf84gNFUUOMkwQM24AAAAASUVORK5CYII="
];
const area = makeMatrix(14, 22);
const player = {
pos: {
x: 0,
y: 0
},
matrix: null,
score: 0
};
const move = 1;
let gameLoop;
let gameRun = false;
playerReset();
draw();
gameOver();
document.addEventListener('keydown', function(e) {
if (e.keyCode === 37) {
playerMove(-move);
} else if (e.keyCode === 39) {
playerMove(+move);
} else if (e.keyCode === 38) {
playerRotate(-move);
} else if (e.keyCode === 40) {
playerDrop();
}
});
document.getElementById("start_game").onclick = function() {
gameRun = true;
playerReset();
let t = 10;
gameLoop = setInterval(function() {
if (gameRun) {
update();
} else {
gameOver();
}
}, t);
this.disabled = false;
};
})();
body {
background-color: #737373;
}
* {
margin: 0;
padding: 0;
}
.canvas_wrap {
display: block;
margin: 0 auto;
padding-top: 25px;
}
.canvas_wrap>* {
display: block;
margin: 0 auto;
border: 1px solid #ffffff;
}
.canvas_wrap>button {
font-family: Arial, Helvetica, sans-serif;
font-size: 30px;
font-weight: bold;
border: none;
color: #ffffff;
background-color: #000000;
padding: 5px;
margin: 10px auto;
border: 1px solid #000000;
outline: none;
}
.canvas_wrap>button:hover {
cursor: pointer;
background-color: #ffffff;
color: #000000;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Tetris</title>
<link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAGLH901AAAACXBIWXMAAAsSAAALEgHS3X78AAAAa0lEQVR4nGP5//8/AwywAPGy01YIDooMgoOiB66BoB5kldhVUSiB7C4UCaw2U9lyKkrgCiuSTRrVQJEGXOkJpwaSYi3K9Nhg9PSohlENODSQWi6RBMjJDqSCUQtGLRi1YNSCEWMBsFClnQUAHyUliPhfuZ4AAAAASUVORK5CYII="
type="image/x-icon">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="canvas_wrap">
<canvas id="tetris" width="280" height="440"></canvas>
<button type="button" id="start_game">Start</button>
</div>
</body>
<script src="script.js"></script>
</html>
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
В общем нужно записать отмеченные чекбоксыы (для отображения после перезагрузки)В интернете нашел решение, но не могу понять код (в основном...
Есть код синхронного запросаСинхронный используется потому, что нельзя отправлять параллельные запросы, сервер отвечает не чаще раза в секунду,...
При запуске кода изображения не изменяются - указывается ошибка
Учу Django, и осваиваю встроиные Django формыпроблема в том что у меня есть форма, которая должна либо создавать тег либо выводить ошибку(думаю...