Нужно реализовать увеличение скорости падения фигуры с каждым убранным уровнем. Кажется уже всё перепробовал, уже глаза замылились. Кто поможет, тому буду безмерно благодарен.
"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>
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости