初级Java开发人员。尝试制作俄罗斯方块小程序作为我个人项目的一部分。

我的意思是可以在屏幕上绘制俄罗斯方块,但不能使其每秒垂直向下。

码:

 public class InitialScreen extends JApplet implements ActionListener {
 public JPanel cards = new JPanel();
 private JPanel introPanel = new JPanel();
 public CardLayout c1 = new CardLayout();

public void init() {
    initiateIntroScreen();
    //game();
    add(cards, BorderLayout.NORTH);
    setSize(500, 100);
}



private void initiateIntroScreen() {
    Frame title = (Frame)this.getParent().getParent();


    cards.setLayout(c1);

    JLabel centralWords = new JLabel("Click the following button options: 'Play' or 'Instructions'.");
    JButton playBtn = new JButton("Play!");
    JButton instructionsBtn = new JButton("Instructions!");

    introPanel.add(centralWords);
    introPanel.add(playBtn);
    introPanel.add(instructionsBtn);
    cards.add(introPanel,"1");

    playBtn.addActionListener(this);
    playBtn.addActionListener(new MainGame(cards,c1));


}

@Override
public void actionPerformed(ActionEvent e) {
    setSize(300,410);
    getContentPane().setBackground(Color.BLACK);
}


这是JApplet的初始屏幕。有两个按钮。当您按下“播放”按钮时,它将进入主游戏屏幕。

public class MainGame extends JApplet implements ActionListener {
private JPanel cards;
private CardLayout c1;
private JPanel gamePanel = new JPanel();

public MainGame(JPanel cards, CardLayout c1) {
    this.c1 = c1;
    this.cards = cards;
    gamePanel.add(new Tetris_Block(new int[10][20]));
}


@Override
public void actionPerformed(ActionEvent e) {
    JLabel scoreLbl = new JLabel("Score:");
    gamePanel.add(scoreLbl);
    cards.add(gamePanel,"game");
    c1.show(cards,"game");

}


这是玩俄罗斯方块的游戏画面。在构造函数中,它调用俄罗斯方块。

public class Tetris_Block extends JComponent implements ActionListener {
static Color[] colors =
        {darkGray, green, blue, red,
                yellow, magenta, pink, cyan};
int[][] a;
int w, h;
static int horizontalPos, verticalPos = 0;
static int size = 20;
private int verticalPos1 = 1;

public Tetris_Block(int[][] a) {
    this.a = a;
    w = a.length;
    h = a[0].length;
    square_Block();
    startTimer();
}

private void nextMove() {
    verticalPos++;
    verticalPos1++;
}

 public void square_Block(){ //Horizontal || Vertical || Colour

    //Horizontal never changes for this as I just want the blocks to go down.
    a[0][verticalPos] = 3;
    a[0][verticalPos1] = 3;
    a[1][verticalPos] = 3;
    a[1][verticalPos1] = 3;
}


@Override
public void actionPerformed(ActionEvent e) {
    nextMove();
    square_Block();
    System.out.println(verticalPos);
}


public void startTimer(){
    Timer timer = new Timer(1000,this);
    timer.start();
}


public void paintComponent(Graphics g) {
    for (int i = 0; i < w; i++) {
        for (int j = 0; j < h; j++) {
                g.setColor(colors[a[i][j]]);
                g.fill3DRect(i * size, j * size,
                        size, size, true);

            }
        }
    }


public Dimension getPreferredSize() {
    return new Dimension(w * size, h * size);
}


我的目标是使垂直位置每秒增加1(因此,它以秒为间隔从窗口向下移动。

我不认为Timer函数是问题。当我打印verticalPos时,它每秒都会打印出增加的值,但是,这只是在屏幕上显示新位置,这就是问题所在。

现在的窗口图片。

[img] http://i.imgur.com/au5fceO.png?1[/img]

最佳答案

首先在repaintactionPerformed方法中添加对Tetris_Block的调用

@Override
public void actionPerformed(ActionEvent e) {
    nextMove();
    square_Block();
    System.out.println(verticalPos);
    // This is important
    repaint();
}


这将在事件队列中安排一次绘画事件,最终将(间接)调用您的paintComponent方法

这将使块开始移动。您将遇到的下一个问题是您实际上并没有从先前的位置“移走”该块,因此它将继续在屏幕上流血/长大

java - 如何使俄罗斯方块每秒掉下来(错误)-LMLPHP

您可以通过将块的颜色传递给square_Block来解决此问题,例如...

public void square_Block(int color) { //Horizontal || Vertical || Colour

    //Horizontal never changes for this as I just want the blocks to go down.
    a[0][verticalPos] = color;
    a[0][verticalPos1] = color;
    a[1][verticalPos] = color;
    a[1][verticalPos1] = color;
}


然后“休息”当前位置的块,更新位置,然后设置新的块颜色;

@Override
public void actionPerformed(ActionEvent e) {
    square_Block(0);
    nextMove();
    square_Block(3);
    System.out.println(verticalPos);
    repaint();
}


java - 如何使俄罗斯方块每秒掉下来(错误)-LMLPHP

10-05 18:41