Java 爪哇俄罗斯方块旋转
我知道有人问了很多,但我想知道如何旋转俄罗斯方块? 我已经提出了一个冗长而糟糕的解决方案(大约170行代码),但应该有更简单的方法来实现 我的俄罗斯方块由4个方块组成,所有方块都知道它们在矩阵中的位置(行和列)。矩阵本身是字符类型的,所以4个块都是字母。例如,它看起来像这样:Java 爪哇俄罗斯方块旋转,java,matrix,rotation,tetris,Java,Matrix,Rotation,Tetris,我知道有人问了很多,但我想知道如何旋转俄罗斯方块? 我已经提出了一个冗长而糟糕的解决方案(大约170行代码),但应该有更简单的方法来实现 我的俄罗斯方块由4个方块组成,所有方块都知道它们在矩阵中的位置(行和列)。矩阵本身是字符类型的,所以4个块都是字母。例如,它看起来像这样: ...... ..T... .TTT.. ...... 我试图通过计算中间的行和列并将其用作origo来模拟我的矩阵作为坐标系,然后尝试应用我发现的这个简单算法: 90度旋转(x,y)=(-y,x) 似乎只有当我的作品在
......
..T...
.TTT..
......
我试图通过计算中间的行和列并将其用作origo来模拟我的矩阵作为坐标系,然后尝试应用我发现的这个简单算法:
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
public void rotatePice(ArrayList random){
int distance=0;//猎户座有多远
对于(int i=0;i<4;++i)
board[random.get(i).getRow()][random.get(i).getColumn()]='。;//擦除工件的当前位置
对于(int i=0;i<4;++i){
距离=Math.abs(random.get(i).getColumn()-middleColumn);
if(random.get(i).getColumn()
您可以使用
您需要适当地设置旋转原点,这可能意味着平移工件相对于运动场的位置(例如,原点位于中心),应用旋转矩阵,然后将其转换回其在运动场坐标上的正确位置。最简单、计算速度最快的方法是使用预计算 这意味着俄罗斯方块看起来像
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
您可以对每种类型的块执行此操作,然后还可以添加成员,以便在板上添加/删除它们
如果进行优化,您将不再使用字符…我建议为每个块组定义四种状态
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
}
}
}
枚举旋转{
上、下、左、右;
旋转{
开关(本){
案例:返回左侧;
案例左:返回向下;
案例:返回权;
案例权利:返回;
}
返回null;//不会发生;
}
旋转右(){
旋转r=这个;
//哇,我很懒,但实际上我在生产代码中看到了这一点!
返回r.rotateLeft().rotateLeft().rotateLeft();
}
}
抽象类砖{
Point centerPos;
旋转腐烂;
抽象列表点占用();
}
类TBrick扩展了Brick{
列表点被占用(){
int x=中心位置x();
int y=中心位置y();
列表点=新建LinkedList();
开关(rot){
案例:点。添加(新点(x-1,y);
点。添加(新点(x,y);
点。添加(新点(x+1,y);
点。添加(新点(x,y+1);
打破
降格:点。添加(新点(x-1,y);
点。添加(新点(x,y);
点。添加(新点(x+1,y);
点。添加(新点(x,y-1);
打破
//结案
}
}
}
我认为最好的方法是硬编码。考虑到每个图形不同,每个图形的旋转阶段也不同。对于每个旋转阶段,确定网格的哪些部分需要自由(避免碰撞)。
对于视觉表现检查您能详细说明一下吗?您能提供一个示例实现吗?