Нужно реализовать увеличение скорости падения фигуры с каждым убранным уровнем. Кажется уже всё перепробовал, уже глаза замылились. Кто поможет, тому буду безмерно благодарен.
"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>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
В общем нужно записать отмеченные чекбоксыы (для отображения после перезагрузки)В интернете нашел решение, но не могу понять код (в основном...
Есть код синхронного запросаСинхронный используется потому, что нельзя отправлять параллельные запросы, сервер отвечает не чаще раза в секунду,...
При запуске кода изображения не изменяются - указывается ошибка
Учу Django, и осваиваю встроиные Django формыпроблема в том что у меня есть форма, которая должна либо создавать тег либо выводить ошибку(думаю...