Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 俄罗斯方块旋转算法不工作_Java_Android_Algorithm - Fatal编程技术网

Java 俄罗斯方块旋转算法不工作

Java 俄罗斯方块旋转算法不工作,java,android,algorithm,Java,Android,Algorithm,我正在使用俄罗斯方块旋转算法。不久前,我在另一个winforms应用程序中使用了该算法,效果很好。现在我想用Android编写一个俄罗斯方块游戏,所以我再次用Java编写算法 然而,这一次它不起作用。我很久以前写过这个算法,当时我还是一个初学者,所以代码有点糟糕。以下是Java中的算法: public static final int CLOCKWISE = 1; public static final int ANTICLOCKWISE = -1; public static Point r

我正在使用俄罗斯方块旋转算法。不久前,我在另一个winforms应用程序中使用了该算法,效果很好。现在我想用Android编写一个俄罗斯方块游戏,所以我再次用Java编写算法

然而,这一次它不起作用。我很久以前写过这个算法,当时我还是一个初学者,所以代码有点糟糕。以下是Java中的算法:

public static final int CLOCKWISE = 1;
public static final int ANTICLOCKWISE = -1;

public static Point rotateClockwise (int x, int y) {
    int temp;
    temp = y;
    y = x;
    x = -temp;
    return new Point (x, y);
}

public static Point rotateAnticlockwise (int x, int y) {
    int temp;
    temp = x;
    x = y;
    y = -temp;
    return new Point (x, y);
}

public static boolean tryRotateTetrimino (Tetrimino tetrimino,
        int rotationPointBlockIndex, int direction) {

    //Local variable declarations
    boolean a, b, c, d;
    TetrisBlock rotationBlock = tetrimino.blocks[rotationPointBlockIndex];
    int X1, Y1, X2, Y2, X3, Y3, X4, Y4;

    //Assign coordinates relative to the centre of rotation.
    X1 = tetrimino.blocks[0].getX () - rotationBlock.getX ();
    Y1 = tetrimino.blocks[0].getY () - rotationBlock.getY ();
    X2 = tetrimino.blocks[1].getX () - rotationBlock.getX ();
    Y2 = tetrimino.blocks[1].getY () - rotationBlock.getY ();
    X3 = tetrimino.blocks[2].getX () - rotationBlock.getX ();
    Y3 = tetrimino.blocks[2].getY () - rotationBlock.getY ();
    X4 = tetrimino.blocks[3].getX () - rotationBlock.getX ();
    Y4 = tetrimino.blocks[3].getY () - rotationBlock.getY ();

    //Rotate the coordinates.
    if (direction == CLOCKWISE) {
        X1 = rotateClockwise (X1, Y1).x;
        Y1 = rotateClockwise (X1, Y1).y;
        X2 = rotateClockwise (X2, Y2).x;
        Y2 = rotateClockwise (X2, Y2).y;
        X3 = rotateClockwise (X3, Y3).x;
        Y3 = rotateClockwise (X3, Y3).y;
        X4 = rotateClockwise (X4, Y4).x;
        Y4 = rotateClockwise (X4, Y4).y;
    } else {
        X1 = rotateAnticlockwise (X1, Y1).x;
        Y1 = rotateAnticlockwise (X1, Y1).y;
        X2 = rotateAnticlockwise (X2, Y2).x;
        Y2 = rotateAnticlockwise (X2, Y2).y;
        X3 = rotateAnticlockwise (X3, Y3).x;
        Y3 = rotateAnticlockwise (X3, Y3).y;
        X4 = rotateAnticlockwise (X4, Y4).x;
        Y4 = rotateAnticlockwise (X4, Y4).y;
    }

    //Declares two arrays of absolute x and y coordinates.
    int[] xArray = new int[] { rotationBlock.getX() + X1,
            rotationBlock.getX() + X2,
            rotationBlock.getX() + X3,
            rotationBlock.getX() + X4 };
    int[] yArray = new int[] { rotationBlock.getY() + Y1,
            rotationBlock.getY() + Y2,
            rotationBlock.getY() + Y3,
            rotationBlock.getY() + Y4 };

    //Check if the coordinates are valid
    a = tetrimino.checkPositionValid (xArray[0], yArray[0]);
    b = tetrimino.checkPositionValid (xArray[1], yArray[1]);
    c = tetrimino.checkPositionValid (xArray[2], yArray[2]);
    d = tetrimino.checkPositionValid (xArray[3], yArray[3]);

    //If the coordinates are valid, assign them to each of the blocks.
    if (a && b && c && d) {
        for (int i = 0 ; i < 4 ; i++) {
            tetrimino.blocks[i].setX (xArray[i]);
            tetrimino.blocks[i].setY (yArray[i]);
        }
        return true;
    }
    return false;

}
请注意,setX和setY方法将改变俄罗斯方块的物理位置

我做的和以前完全一样,但就是不起作用。 例如:

O
O
O O
旋转,然后变成

O
  O
    O
看起来两个俄罗斯方块重叠了

如果你认为我的算法是错误的,并且想建议另一个,你能用Tetrimino类和TetrisBlock类来解释它吗

Tetrimino.java

public abstract class Tetrimino {
public TetrisBlock[] blocks;

protected int interval = 1000;
protected boolean paused = false;
protected Handler handler;
protected TetrisBlock[][] tetrisBlockMatrix;
protected ArrayList<ITetrisEventListener> landedEventListeners;
protected Runnable task = new TimerTask () {
    @Override
    public void run() {
        if (!paused) {
            moveDown ();
            if (handler != null)
                handler.postDelayed (task, interval);
        }
    }
};

public static final int LEFT = -1;
public static final int RIGHT = 1;

protected abstract TetrisBlock[] getTouchingSides();

protected void landed () {
    for (int i = 0 ; i < landedEventListeners.size () ; i++) {
        landedEventListeners.get (i).onLanded (this);
    }
}

public void registerLandedListeners (ITetrisEventListener listener) {
    landedEventListeners.add (listener);
}

public void moveDown () {
    if (!checkLanded ()) {
        for (TetrisBlock block:blocks) {
            block.moveDown ();
        }
    } else {
        handler = null;
        landed ();
    }
}

protected boolean checkLanded () {
    TetrisBlock[] touchingSides = getTouchingSides ();
    for (TetrisBlock block:touchingSides) {
        if (block.getY () >= 21) {
            return true;
        }

        if (tetrisBlockMatrix[block.getX ()][block.getY () + 1] != null) {
            return true;
        }
    }
    return false;
}

public boolean checkPositionValid (int x, int y) {
    if (x < 0 || y < 0 ||
            x > 15 || y > 21)
        return false;
    if (tetrisBlockMatrix[x][y] == null)
        return true;
    return false;
}

public void move (int side) {
    if (side == 1 || side == -1) {
        for (TetrisBlock block:blocks) {
            block.setX (block.getX () + side);
        }

        for (TetrisBlock block:blocks) {
            if (!checkPositionValid (block.getX (), block.getY ())) {
                if (side == LEFT)
                    move (RIGHT);
                else
                    move (LEFT);
            }
        }
    } else {
        throw new IllegalArgumentException ();
    }
}

public void addTetrisBlocksToMatrix (TetrisBlock[][] matrix) {
    for (TetrisBlock block:blocks) {
        if (matrix[block.getX ()][block.getY ()] == null) {
            matrix[block.getX ()][block.getY ()] = block;
        } else {
            throw new IllegalArgumentException ();
        }
    }
}

public void setTimerEnabled (boolean value) {
    if (value && paused) {
        handler.post (task);
    } else {
        paused = true;
    }
}

public void setTimerInterval (int milliseconds) {
    interval = milliseconds;
}

protected Tetrimino (TetrisBlock[][] matrix, TetrisActivity activity) {
    this.tetrisBlockMatrix = matrix;
    handler = new Handler ();
    handler.post (task);
    landedEventListeners = new ArrayList<> ();
    blocks = new TetrisBlock[4];
}

问题是,旋转时,将X坐标设置为新值并覆盖旧值,而第二次调用旋转函数时仍然需要该值。例如,当您应该传递原始值时,将X1的旋转值传递给此处的第二个调用
rotateClockwise

X1 = rotateClockwise (X1, Y1).x;
Y1 = rotateClockwise (X1, Y1).y;
只需调用一次,然后将x和y值分配给变量:

Point point1 = rotateClockwise (X1, Y1);
X1 = point1.x; Y1 = point1.y;

哦,是的,我明白了!非常感谢你!我试试看。
X1 = rotateClockwise (X1, Y1).x;
Y1 = rotateClockwise (X1, Y1).y;
Point point1 = rotateClockwise (X1, Y1);
X1 = point1.x; Y1 = point1.y;