Java Tetris rotation

前提是你 提交于 2020-01-13 13:04:39

问题


I know this has been asked a lot but I'd like to know how to rotate a Tetris piece? I already made a long and bad solution (~170 lines of code) but there should be easier way to do it.

My tetris pieces consist of 4 blocks which all know their location (row and column) in the matrix. Matrix itself is char-typed, so 4 blocks are all letters. It looks like this for example:

......
..T...
.TTT..
......

I tried to simulate my matrix as coordinate system by counting the middle row and column and using it as an origo and then tried to apply this simple algorithm I found: 90 degree rotation (x,y) = (-y,x)

It appears that it works only if my piece is in the center of matrix. I have no idea what I should do, I've been thinking this all day. Here's my method:

public void rotatePiece(ArrayList<Block> random) {
        int distance = 0; // how far is the origo

        for (int i=0; i < 4; ++i)
            board[random.get(i).getRow()][random.get(i).getColumn()] = '.';  // erases the current location of the piece

        for (int i=0; i < 4; ++i) {
            distance = Math.abs(random.get(i).getColumn()-middleColumn);

            if (random.get(i).getColumn() < middleColumn)
                random.get(i).setColumn(random.get(i).getColumn()+(distance*2)); // "throws" the location of the block to the other side of the origo
            else
                random.get(i).setColumn(random.get(i).getColumn()-(distance*2));

            int help = random.get(i).getColumn();
            random.get(i).setColumn(random.get(i).getRow());  // (x, y) = (-y, x)
            random.get(i).setRow(help);
        }

         for (int i=0; i < 4; ++i)
            board[random.get(i).getRow()][random.get(i).getColumn()] = random.get(0).getStyle(); // saves the new location of the piece in the matrix

回答1:


I would recommend defining four states for each block-group.

enum ROTATION {
    UP, DOWN, LEFT, RIGHT;

    ROTATION rotateLeft() {
        switch(this) {
             case UP: return LEFT;
             case LEFT: return DOWN;
             case DOWN: return RIGHT;
             case RIGHT: return UP;
        }
        return null; // wont happen;
    }

    ROTATION rotateRight() {
        ROTATION r = this;
         // wow I'm lazy, but I've actually seen this in production code!
        return r.rotateLeft().rotateLeft().rotateLeft();
    }
}

abstract class Brick {
    Point centerPos;
    ROTATION rot;
    abstract List<Point> pointsOccupied();
}

class TBrick extends Brick {

    List<Point> pointsOccupied() {
        int x = centerPos.x();
        int y = centerPos.y();
        List<Point> points = new LinkedList<Point>();
        switch(rot) {
            case UP: points.add(new Point(x-1,y);
                     points.add(new Point(x,y);
                     points.add(new Point(x+1,y);
                     points.add(new Point(x, y+1);
                break;
            case Down: points.add(new Point(x-1,y);
                       points.add(new Point(x,y);
                       points.add(new Point(x+1,y);
                       points.add(new Point(x, y-1);
                break;
            // finish the cases
        }

   }

}



回答2:


You can use a rotation matrix.

You will need to set the origin of your rotation appropriately, which may mean translating the location of the piece with respect to the playing field (such that the origin is in the centre, for example), applying the rotation matrix and then translating it back to its correct location on the playing field coordinates.




回答3:


The easiest and computational fastest way to do this, would to use precompute them.

That means a tetris piece will look like

class TetrisBlock {

   String position[4];

   int curPos = 0;

   void rotateLeft() {
      curPos++;
      if (curPos > 3)
        curPos = 0;
   }
....
}

And then you could define something like

class TetrisTBlock extends TetrisBlock { 

...

// in constructor
position={"....\n.T..\nTTT.\n....",
          ".T..\nTT..\n.T..\n.....", 
// I guess you get the idea

...

You do this for every type of block and then you can also add members for adding/removing them from the board.

If you optimize you would go away from the chars....




回答4:


I think the best way is to hard-code it. Take into consideration that each figure is different and each of the figure's rotation phase is also different. And for each rotation phase - determine which parts of the grid you need to be free (avoid collision). For a visual representation check this



来源:https://stackoverflow.com/questions/5503290/java-tetris-rotation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!