Reputation: 12718
I'm building Tetris in Java as a fun side project and am now working on rotations.
I was originally hard coding each rotation which was proving to be quite tedious.
That being said, I was then going to try Matrix Rotations using linear algebra, but someone on the Mathematics.SE recommended I try transposing. So given his description, I tried drawing it out. Did I get the drawings correct?
From that, I'm not trying to code the transpose, but now am completely lost in my code.
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;
}
This outputs a seemingly correct transposed graph?
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)
So my questions are:
1) Is my drawing above a correct interpretation of his description?
2) Am I correctly generating a transposed graph?
3) If so, how should I paint the rotated block... Should I just replace grid[row][col]
with 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);
}
}
}
}
}
Thanks!
Upvotes: 2
Views: 1353
Reputation: 7146
Transposing alone won't work for all of the normal tetris pieces. For example, take the piece shaped like this:
xx_
_xx
___
When you transpose it, you end up with this:
x__
xx_
_x_
So rather than think about a particular piece, think about what happens when you work with a square with the corners labeled:
a_b
___
d_c
This make it very clear if your rotation is good or not. So let's look at transpose:
a_d
___
b_c
In order to get the clockwise rotation, we can just flip it sideways:
d_a
___
c_b
Performing the same operation again should give us a full half rotation from where we started. Take the transpose:
d_c
___
a_b
And flip it:
c_d
___
b_a
So in order to do a clockwise rotation, simply take the transpose and flip it. What happens if we do the opposite, flip it and then take the transpose? Working from the previous orientation, this is what we get if we flip it:
d_c
___
a_b
Now take the transpose:
d_a
___
c_b
And we're back to what we had after one rotate - a counterclockwise rotation. So transposing alone won't work, but transposing combined with a horizontal flip does everything you need!
As for your questions,
I'm not sure your drawing is a correct interpretation. Based on the comments you left I suspect that I may have misunderstood them, which is why I made the drawings above to show what needs to happen.
Yes, that is a correctly transposed graph. You probably don't want to use gridTranspose[j].length-1
in the loops, as that cuts off one column.
To paint the rotated block, I would suggest having a separate variable for holding the current piece. If the piece were at x,y
, then you would put something like this in your paintComponent
method:
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);
}
}
}
Upvotes: 3