Java俄罗斯方块旋转

3

我知道这个问题已经被问了很多次,但我想知道如何旋转俄罗斯方块?我已经写了一个冗长且糟糕的解决方案(约170行代码),但应该有更简单的方法。

我的俄罗斯方块由4个方块组成,它们都知道它们在矩阵中的位置(行和列)。矩阵本身是char类型的,所以4个方块都是字母。例如,它看起来像这样:

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

我尝试将我的矩阵模拟成坐标系,通过计算中间行和列并将其用作原点,然后尝试应用我找到的这个简单算法:

90度旋转(x,y)=(-y,x)

看起来只有当我的方块在矩阵的中心时才能正常工作。我不知道该怎么办,我已经思考了一整天。下面是我的方法:

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
4个回答

2
我建议为每个块组定义四种状态。
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
        }

   }

}

1

最简单且计算速度最快的方法是使用预先计算。

这意味着俄罗斯方块的形状将如下所示:

class TetrisBlock {

   String position[4];

   int curPos = 0;

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

然后你可以定义类似于这样的东西

class TetrisTBlock extends TetrisBlock { 

...

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

...

你需要为每种类型的方块做这件事,然后你还可以添加成员来添加/删除它们从板上。

如果你进行优化,你会远离字符....


1

你可以使用旋转矩阵

你需要适当设置旋转的原点,这可能意味着将棋子相对于游戏场地的位置进行平移(例如使原点位于中心),应用旋转矩阵,然后将其平移回到正确的游戏场地坐标位置。


你能详细说明一下吗?你能提供一个实现的例子吗? - user3871

0

我认为最好的方法是硬编码。要考虑到每个图形都不同,每个图形的旋转相位也不同。对于每个旋转相位,确定需要空闲哪些网格部分(避免碰撞)。 如需视觉表示,请查看this


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接