我在使用俄罗斯方块时遇到了一些问题。所以首先,我有一个 Shape 类,然后是每个形状类型的 Shape 子类。这是 Shape 子类的样子:
public class SquareShape extends Shape {
public SquareShape(){
coords = squareShapeCoords;
shape = SQUARESHAPE;
}
}
在 Shape 类中,我有一个旋转方法,如下所示:
protected void setX(int i, int x) { coords[i][0] = x; }
protected void setY(int i, int y) { coords[i][1] = y; }
public int x(int i) { return coords[i][0]; }
public int y(int i) { return coords[i][1]; }
public Shape rotate(){
if (this.getShape().equals(SQUARESHAPE)) return this;
Shape newShape = new Shape();
newShape.shape = this.shape;
for (int i = 0; i < 4; i++) {
newShape.setX(i, y(i));
newShape.setY(i, -x(i));
}
return newShape;
}
请注意,我将每个形状的坐标存储在二维数组中。另外,这是我的游戏引擎类:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GameEngine extends JPanel implements ActionListener{
private final int HEIGHT = 15;
private final int WIDTH = 10;
private int score;
int coordX = 0;
int coordY = 0;
Timer timer;
boolean isFinishedFalling = false;
boolean isRunning = false;
boolean isPaused = false;
Shape block;
String[] shapes;
public GameEngine(){
setFocusable(true);
block = new Shape();
timer = new Timer(600, this);
timer.start();
addMouseListener(new MAdapter());
addMouseWheelListener(new WheelAdapter());
addKeyListener(new KAdapter());
setBackground(Color.BLACK);
shapes = new String[WIDTH * HEIGHT];
clearShapes();
}
int squareWidth() { return (int) getSize().getWidth() / WIDTH; }
int squareHeight() { return (int) getSize().getHeight() / HEIGHT; }
String shapeAt(int x, int y) { return shapes[(y * WIDTH) + x]; }
public int getScore() {return score;}
public void actionPerformed(ActionEvent e){
if(isFinishedFalling){
isFinishedFalling = false;
newBlock();
} else moveDown();
}
private boolean move(Shape newShape, int newCoordX, int newCoordY)
{
for (int i = 0; i < 4; ++i) {
int x = newCoordX + newShape.x(i);
int y = newCoordY - newShape.y(i);
if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) return false;
if (!shapeAt(x, y).equals(Shape.DEFAULTSHAPE)) return false;
}
block = newShape;
coordX = newCoordX;
coordY = newCoordY;
repaint();
return true;
}
private boolean moveLeft() { return move(block, coordX-1, coordY);}
private boolean moveRight() { return move(block, coordX+1, coordY);}
private boolean moveDown(){
if(!move(block, coordX, coordY-1)){
blockIsDown();
return false;
} else return true;
}
private void dropDown(){
int y = coordY;
while(y>0){
if(!move(block, coordX, y-1)) break;
y -= 1;
}
blockIsDown();
}
private boolean rotate() { return move(block.rotate(), coordX, coordY);}
private void blockIsDown(){
for(int i=0; i<4; i++){
int a = coordX + block.x(i);
int b = coordY - block.y(i);
shapes[b * WIDTH + a] = block.getShape();
}
clearFullLines();
if(!isFinishedFalling) newBlock();
}
private void clearFullLines(){
int fullLines = 0;
for(int i = HEIGHT-1; i>=0; i--){
boolean lineFull = true;
for(int j=0; j<WIDTH; j++){
if(shapeAt(j, i).equals(Shape.DEFAULTSHAPE)){
lineFull = false;
break;
}
}
if(lineFull){
fullLines++;
for(int m=i; m<HEIGHT-1; m++){
for(int n=0; n<WIDTH; n++)
shapes[(m*WIDTH) + n] = shapeAt(n, m+1);
}
}
}
if(fullLines>0){
score += fullLines*100;
isFinishedFalling = true;
block.setShape(Shape.DEFAULTSHAPE);
repaint();
}
}
private void newBlock()
{
block = new RandomShape();
coordX = WIDTH / 2 + 1;
coordY = HEIGHT - 1 + block.minY();
if (!move(block, coordX, coordY)) {
block.setShape(Shape.DEFAULTSHAPE);
timer.stop();
isRunning = false;
}
}
private void clearShapes(){
for(int i=0; i< WIDTH * HEIGHT; i++) shapes[i] = Shape.DEFAULTSHAPE;
}
private void drawSquare(Graphics g, int x, int y, String shape){
Color color = Color.BLACK;
if(shape.equals(Shape.ZSHAPE)) color = Color.GREEN;
if(shape.equals(Shape.SSHAPE)) color = Color.RED;
if(shape.equals(Shape.LINESHAPE)) color = Color.CYAN;
if(shape.equals(Shape.TSHAPE)) color = Color.BLUE;
if(shape.equals(Shape.SQUARESHAPE)) color = Color.YELLOW;
if(shape.equals(Shape.LSHAPE)) color = Color.MAGENTA;
if(shape.equals(Shape.MIRROREDLSHAPE)) color = Color.ORANGE;
g.setColor(color);
g.fillRect(x + 1, y + 1, squareWidth() - 2, squareHeight() - 2);
g.setColor(color.brighter());
g.drawLine(x, y + squareHeight() - 1, x, y);
g.drawLine(x, y, x + squareWidth() - 1, y);
g.setColor(color.darker());
g.drawLine(x + 1, y + squareHeight() - 1, x + squareWidth() - 1, y + squareHeight() - 1);
g.drawLine(x + squareWidth() - 1, y + squareHeight() - 1, x + squareWidth() - 1, y + 1);
}
public void paint(Graphics g){
super.paint(g);
Dimension size = getSize();
int top = (int) size.getHeight() - HEIGHT * squareHeight();
for(int i=0; i<HEIGHT; i++){
for(int j=0; j<WIDTH; j++){
String s = shapeAt(j, HEIGHT-i-1);
if(!s.equals(Shape.DEFAULTSHAPE))
drawSquare(g, j * squareWidth(), top + i * squareHeight(), s);
}
}
if(!block.getShape().equals(Shape.DEFAULTSHAPE)){
for(int i=0; i<4; i++){
int x = coordX + block.x(i);
int y = coordY - block.y(i);
drawSquare(g, x * squareWidth(), top + (HEIGHT - y - 1) * squareHeight(), block.getShape());
}
}
}
public void start(){
if(isPaused) return;
isRunning = true;
isFinishedFalling = false;
score = 0;
clearShapes();
newBlock();
timer.start();
}
private void pause(){
if(!isRunning) return;
isPaused = !isPaused;
if(isPaused){
timer.stop();
} else{
timer.start();
}
repaint();
}
class MAdapter extends MouseAdapter{
public void mouseClicked(MouseEvent e){
if (!isRunning || block.getShape().equals(Shape.DEFAULTSHAPE) || isPaused) return;
int buttonPressed = e.getButton();
if(buttonPressed == MouseEvent.BUTTON1) moveLeft();
if(buttonPressed == MouseEvent.BUTTON2) rotate();
if(buttonPressed == MouseEvent.BUTTON3) moveRight();
}
}
class WheelAdapter implements MouseWheelListener{
public void mouseWheelMoved(MouseWheelEvent e){
if (!isRunning || block.getShape().equals(Shape.DEFAULTSHAPE) || isPaused) return;
int wheelRotation = e.getWheelRotation();
if(wheelRotation == 1) moveDown();
if(wheelRotation == -1) dropDown();
}
}
class KAdapter extends KeyAdapter{
public void keyPressed(KeyEvent e){
if (!isRunning || block.getShape().equals(Shape.DEFAULTSHAPE) || isPaused) return;
int key = e.getKeyCode();
if(key == KeyEvent.VK_SPACE) pause();
}
}
}
我的问题如下:当我尝试旋转积木时,第一次效果很好,但如果我第二次尝试旋转它们,它就会完全混乱。
这应该是我的线条形状:
这是我的 L 形(黄色):
请注意,这不仅仅是一个图形错误,游戏将元素分别视为一个或两个正方形。我一直在寻找我的代码几个小时来查看问题可能是什么,但我没有运气。任何帮助,将不胜感激