开发者

Java Tetris rotation

开发者 https://www.devze.com 2023-02-20 21:45 出处:网络
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.

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开发者_JAVA技巧).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


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
        }

   }

}


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.


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....


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

0

精彩评论

暂无评论...
验证码 换一张
取 消