как повернуть матрицу на javascript в игре тетрис?
уже долго сижу и не могу понять как сделать поворот матрицы. Прошу помощи. код с поворотом писать в функцию rotate. Заранее спасибо.
<html>
<head>
<meta charset="utf-8">
<title>Тетрис</title>
<link rel="stylesheet" href="css.css">
</head>
<body>
<!-- рисуем поле для игры -->
<canvas width="320" height="640" id="game"></canvas>
<script src="script.js"></script>
</body>
</html>
*{
height: 100%;
margin: 0;
}
body {
background: black;
display: flex;
align-items: center;
justify-content: center;
}
canvas {
border: 1px solid white;
}
const canvas = document.getElementById('game');
const context = canvas.getContext('2d');
const grid = 32;
//послед.фигур
let tetrominoSequence = [];
//поле
let playfield = [];
//заполняем фигурами
for (let row = -2; row < 20; row++) {
playfield[row] = [];
for (let col = 0; col < 10; col++) {
playfield[row][col] = 0;
}
}
//сами фигуры в виде двумерного массива
const tetrominos = {
'I': [
[0,0,0,0],
[1,1,1,1],
[0,0,0,0],
[0,0,0,0],
],
'J': [
[1,0,0],
[1,1,1],
[0,0,0],
],
'L': [
[0,0,1],
[1,1,1],
[0,0,0],
],
//квадрат если ч0
'O': [
[1,1],
[1,1],
],
'S': [
[0,1,1],
[1,1,0],
[0,0,0],
],
'Z': [
[1,1,0],
[0,1,1],
[0,0,0],
],
'T': [
[0,1,0],
[1,1,1],
[0,0,0],
]
};
//цвет для фигур
//рандомный, кста
const colors = {
'I': '#' + (Math.random().toString(16) + '000000').substring(2,8).toUpperCase(),
'O': '#' + (Math.random().toString(16) + '000000').substring(2,8).toUpperCase(),
'T': '#' + (Math.random().toString(16) + '000000').substring(2,8).toUpperCase(),
'S': '#' + (Math.random().toString(16) + '000000').substring(2,8).toUpperCase(),
'Z': '#' + (Math.random().toString(16) + '000000').substring(2,8).toUpperCase(),
'J': '#' + (Math.random().toString(16) + '000000').substring(2,8).toUpperCase(),
'L': '#' + (Math.random().toString(16) + '000000').substring(2,8).toUpperCase()
};
let count = 0;
// фигура, которая сейчас
let tetromino = getNextTetromino();
//кадры
let rAF = null;
// обозначение конца игры
let gameOver = false;
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
//фигуры, которые будут в игре (их последовательность)
function generateSequence() {
const sequence = ['I', 'J', 'L', 'O', 'S', 'T', 'Z'];
while (sequence.length) {
const rand = getRandomInt(0, sequence.length - 1);
const name = sequence.splice(rand, 1)[0];
tetrominoSequence.push(name);
}
}
//получение фигуры
function getNextTetromino() {
if (tetrominoSequence.length === 0) {
generateSequence();
}
//отбираем у массива первую фигуру
const name = tetrominoSequence.pop();
//создание матрицы
const matrix = tetrominos[name];
const col = playfield[0].length / 2 - Math.ceil(matrix[0].length / 2);
const row = name === 'I' ? -1 : -2;
param_fig = {
name: name,
matrix: matrix,
row: row,
col: col
};
return param_fig;
}
console.log(param_fig);
// поворот фигуры
function rotate(param_fig){
}
// не вылазила за поле фигура
function isValidMove(matrix, cellRow, cellCol) {
for (let row = 0; row < matrix.length; row++) {
for (let col = 0; col < matrix[row].length; col++) {
if (matrix[row][col] && (
//если всё же за полем
cellCol + col < 0 || cellCol + col >= playfield[0].length || cellRow + row >= playfield.length ||
// при пересечении с другими фигурами
playfield[cellRow + row][cellCol + col])
) {
return false;
}
}
}
return true;
}
// когда фигура окончательна встала на своё место
function placeTetromino() {
for (let row = 0; row < tetromino.matrix.length; row++) {
for (let col = 0; col < tetromino.matrix[row].length; col++) {
if (tetromino.matrix[row][col]) {
//если за поле, то игра закончена
if (tetromino.row + row < 0) {
return showGameOver();
}
// если не за полемы
playfield[tetromino.row + row][tetromino.col + col] = tetromino.name;
}
}
}
// заполненные ряды очищены
for (let row = playfield.length - 1; row >= 0; ) {
// если ряд полон
if (playfield[row].every(cell => !!cell)) {
// очищаем его и опускаем всё вниз на одну клетку
for (let r = row; r >= 0; r--) {
for (let c = 0; c < playfield[r].length; c++) {
playfield[r][c] = playfield[r-1][c];
}
}
}
else{
row--;
}
}
//получение следующей фигуры
tetromino = getNextTetromino();
}
// Сам цикл с игрой
function loop() {
//начало анимации
rAF = requestAnimationFrame(loop);
context.clearRect(0,0,canvas.width,canvas.height);
//отрисовка поля
for (let row = 0; row < 20; row++) {
for (let col = 0; col < 10; col++) {
if (playfield[row][col]) {
const name = playfield[row][col];
context.fillStyle = colors[name];
// рисуем всё на один пиксель меньше, чтобы получился эффект «в клетку»
context.fillRect(col * grid, row * grid, grid-1, grid-1);
}
}
}
// отрисовка текущей фигуры
if (tetromino){
if (++count > 35) {
tetromino.row++;
count = 0;
// при окончании движение
//проверка можно ли удалить строку
if (!isValidMove(tetromino.matrix, tetromino.row, tetromino.col)) {
tetromino.row--;
placeTetromino();
}
}
//для того, давать цвет фигуры
context.fillStyle = colors[tetromino.name];
// отрисовка фигуры
for (let row = 0; row < tetromino.matrix.length; row++) {
for (let col = 0; col < tetromino.matrix[row].length; col++) {
if (tetromino.matrix[row][col]) {
// и снова рисуем на один пиксель меньше
context.fillRect((tetromino.col + col) * grid, (tetromino.row + row) * grid, grid-1, grid-1);
}
}
}
}
}
// следим за нажатиями на клавиши
document.addEventListener('keydown', function(e) {
// стрелки влево и вправо
if (e.which === 37 || e.which === 39) {
const col = e.which === 37
// если влево, то уменьшаем индекс в столбце, если вправо — увеличиваем
? tetromino.col - 1
: tetromino.col + 1;
// если так ходить можно, то запоминаем текущее положение
if (isValidMove(tetromino.matrix, tetromino.row, col)) {
tetromino.col = col;
}
}
//кнопка для поворота
if (e.which === 32) {
rotate(param_fig);
}
// ускорение падения фигуры
if(e.which === 40) {
const row = tetromino.row + 1;
if (!isValidMove(tetromino.matrix, row, tetromino.col)) {
tetromino.row = row - 1;
placeTetromino();
return;
}
tetromino.row = row;
}
});
rAF = requestAnimationFrame(loop);
Ответы (1 шт):
Автор решения: Владислав
→ Ссылка
function rt(param_fig){
let newMatrix = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]];
let N = param_fig.matrix.length;
//для фигур
for(let y = 0; y < N; y++){
for(let x = 0; x < N; x++){
newMatrix[x][N-y-1] = param_fig.matrix[y][x];
}
}
return newMatrix;}