2013-04-18 6 views
2

Я строю Тетрис на Java в качестве веселого проекта, и теперь я работаю на поворотах.Java Tetris - использование транспонирования для поворота фигуры

Я изначально был жестко кодировал каждую ротацию, которая оказалась довольно утомительной.

Это, как говорится, я попытался использовать Matrix Rotations, используя линейную алгебру, но кто-то из Mathematics.SE рекомендовал попробовать транспонирование. Поэтому, учитывая его описание, я попытался вытащить его. Правильно ли я получил чертежи?

enter image description here

От того, я не пытаюсь кодировать транспонирование, но теперь я полностью потерял в своем коде.

public void getTranspose() { 
    Tile[][] gridTranspose = transpose(); 
    System.out.println(); 
    System.out.println("B`:"); 
    for (int j = 0; j < gridTranspose.length; j++) { 
     for (int i = 0; i < gridTranspose[j].length-1; i++) { 
      System.out.print("(" + i + ", " + j + ") "); 
     } 
     System.out.println(); 
    } 
} 

public Tile[][] transpose() { 
    Tile gridT[][]; 
    gridT = new Tile[width][height]; 
    System.out.println("B:"); 
    for(int i = 0; i < grid.length; i++) { 
     for(int j = 0; j < grid[i].length-1; j++) { 
      System.out.print("(" + i + ", " + j + ") "); 
      gridT[j][i] = grid[i][j]; 
     } 
     System.out.println(); 
    } 
    return gridT; 
} 

Это выводит, по-видимому, правильный транспонированный граф?

B:

(0, 0) (0, 1) (0, 2) (0, 3) (0, 4) (0, 5) (0, 6) (0, 7) (0, 8) 
(1, 0) (1, 1) (1, 2) (1, 3) (1, 4) (1, 5) (1, 6) (1, 7) (1, 8) 
(2, 0) (2, 1) (2, 2) (2, 3) (2, 4) (2, 5) (2, 6) (2, 7) (2, 8) 
(3, 0) (3, 1) (3, 2) (3, 3) (3, 4) (3, 5) (3, 6) (3, 7) (3, 8) 
(4, 0) (4, 1) (4, 2) (4, 3) (4, 4) (4, 5) (4, 6) (4, 7) (4, 8) 
(5, 0) (5, 1) (5, 2) (5, 3) (5, 4) (5, 5) (5, 6) (5, 7) (5, 8) 
(6, 0) (6, 1) (6, 2) (6, 3) (6, 4) (6, 5) (6, 6) (6, 7) (6, 8) 
(7, 0) (7, 1) (7, 2) (7, 3) (7, 4) (7, 5) (7, 6) (7, 7) (7, 8) 
(8, 0) (8, 1) (8, 2) (8, 3) (8, 4) (8, 5) (8, 6) (8, 7) (8, 8) 
(9, 0) (9, 1) (9, 2) (9, 3) (9, 4) (9, 5) (9, 6) (9, 7) (9, 8) 

B`:

(0, 0) (1, 0) (2, 0) (3, 0) (4, 0) (5, 0) (6, 0) (7, 0) (8, 0) 
(0, 1) (1, 1) (2, 1) (3, 1) (4, 1) (5, 1) (6, 1) (7, 1) (8, 1) 
(0, 2) (1, 2) (2, 2) (3, 2) (4, 2) (5, 2) (6, 2) (7, 2) (8, 2) 
(0, 3) (1, 3) (2, 3) (3, 3) (4, 3) (5, 3) (6, 3) (7, 3) (8, 3) 
(0, 4) (1, 4) (2, 4) (3, 4) (4, 4) (5, 4) (6, 4) (7, 4) (8, 4) 
(0, 5) (1, 5) (2, 5) (3, 5) (4, 5) (5, 5) (6, 5) (7, 5) (8, 5) 
(0, 6) (1, 6) (2, 6) (3, 6) (4, 6) (5, 6) (6, 6) (7, 6) (8, 6) 
(0, 7) (1, 7) (2, 7) (3, 7) (4, 7) (5, 7) (6, 7) (7, 7) (8, 7) 
(0, 8) (1, 8) (2, 8) (3, 8) (4, 8) (5, 8) (6, 8) (7, 8) (8, 8) 
(0, 9) (1, 9) (2, 9) (3, 9) (4, 9) (5, 9) (6, 9) (7, 9) (8, 9) 

Так что мои вопросы:

1) Является ли мой рисунок выше правильной интерпретации его описания?

2) Я правильно генерирую транспонированный граф?

3) Если да, то как мне покрасить вращающийся блок ... Должен ли я просто заменить grid[row][col] на transpose()?

public void paintComponent(Graphics g) { 
    g.setColor(Color.black); 
    g.fillRect(0, 0, getWidth(), getHeight()); 
    for(int row = 0; row < grid.length; row++) { 
     for(int col = 0; col < grid[row].length; col++) { 
      if(grid[row][col] != null) { 
       //if there is a non-null space, that is a Tetris piece.. fill it red 
       if (grid[row][col].getColor() != null) { 
        g.setColor(grid[row][col].getColor()); 
        g.fillRect(row * tilesize, col * tilesize, tilesize, tilesize); 
        g.setColor(Color.WHITE); 
        g.drawString("(" + row + ", " + col + ")", row * tilesize, col * tilesize+10); 
       }   
      } 
     } 
    } 
} 

Спасибо!

+0

возможный дубликат http://stackoverflow.com/questions/5503290/java-tetris-rotation? – jsedano

+0

Что представляет собой 'grid'? Вся игровая площадка, включая ранее размещенные предметы? Или просто текущий кусок? –

+0

@RobWatts всей игровой площадки. 'grid = new Tile [width] [height];', и я устанавливаю места на нулевой сетке, если в этом (x, y) месте нет плитки ... В начале кода я инициализирую новую часть, которая состоящий из 4-х плиток, 'newPiece = new Piece (это,« Bar »);' ... поскольку у них есть места в сетке, paintComponent увидит, что они не являются нулевыми и нарисовали их. – Growler

ответ

3

Транспонирование само по себе не будет работать для всех обычных кусочков тетриса. Например, возьмите кусок формы, как это:

xx_ 
_xx 
___ 

Когда вы транспонировать, вы в конечном итоге с этим:

x__ 
xx_ 
_x_ 

Так, а не думать о конкретной части, подумайте о том, что происходит, когда вы работа с квадратом с углами с пометками:

a_b 
___ 
d_c 

Это очень ясно, если ваше вращение хорошее или нет. Итак, давайте посмотрим на транспонированной:

a_d 
___ 
b_c 

Для того, чтобы получить вращение по часовой стрелке, можно просто перевернуть его в сторону:

d_a 
___ 
c_b 

Выполнение ту же операцию снова должна дать нам полную половину поворота, откуда мы начал.Возьмите транспонирование:

d_c 
___ 
a_b 

И переверните его:

c_d 
___ 
b_a 

Так что для того, чтобы сделать вращение по часовой стрелке, просто возьмите транспонирование и перевернуть его. Что произойдет, если мы сделаем противоположное, перевернем его, а затем возьмем транспонирование? Исходя из предыдущей ориентации, это то, что мы получаем, если перевернуть его:

d_c 
___ 
a_b 

Теперь возьмите транспонирование:

d_a 
___ 
c_b 

И мы вернулись к тому, что мы имели после одного поворота - против часовой стрелки вращение. Так что транспонирование в одиночку не сработает, но перенос в сочетании с горизонтальным флипом делает все, что вам нужно!

Что касается ваших вопросов,

  1. Я не уверен, что ваш рисунок является правильной интерпретацией. Исходя из комментариев, которые вы оставили, я подозреваю, что, возможно, неправильно понял их, поэтому я сделал рисунки выше, чтобы показать, что должно произойти.

  2. Да, это правильно транспонированный граф. Вероятно, вы не хотите использовать gridTranspose[j].length-1 в циклах, так как это отсекает один столбец.

  3. Чтобы покрасить вращающийся блок, я предлагаю иметь отдельную переменную для удерживания текущей детали. Если кусок были в x,y, то вы бы поставить что-то вроде этого в вашем методе paintComponent:

    for(int row = 0; row < piece.length(); row++) { 
        for(int col = 0; col < piece.width(); piece++) { 
         if(piece.hasBlockAt(row, col) { 
          g.setColor(piece.getColorAt(row, col)); 
          g.fillRect((row+x) * tilesize, (col+y) * tilesize, tilesize, tilesize); 
         } 
        } 
    } 
    
+0

Хорошо, тогда вы можете помочь мне понять, как я могу использовать повороты матрицы? http://en.wikipedia.org/wiki/Rotation_matrix#Common_rotations – Growler

+0

Роб, зеркалирование - это то, о чем говорил лэвеллен в ссылке Mathematics.SE, которую я предоставил. Я это понимаю, но мне было трудно его реализовать. EDIT: Это ваше объяснение о Matrix вращениях, о которых я спрашивал? Я не понимаю, как Sin и Cos играют в него, хотя – Growler

+0

Нет, это не использует вращения матрицы –