初学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时,它每秒打印出递增的值,但它只是在屏幕上显示新的位置 - 这就是问题。
现在窗口的图像。
答案 0 :(得分:4)
首先,在repaint
actionPerformed
方法中添加对Tetris_Block
的调用
@Override
public void actionPerformed(ActionEvent e) {
nextMove();
square_Block();
System.out.println(verticalPos);
// This is important
repaint();
}
这将在事件队列上安排一个paint事件,最终将调用paintComponent
方法(间接)
这将使块开始移动。你将遇到的下一个问题是你实际上并没有&#34;删除&#34;从它的前一个位置开始阻止,所以它将继续在屏幕上流血/长大
您可以通过将块的颜色传递给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;
}
然后&#34;休息&#34;当前位置的块,更新位置,然后设置新的块颜色;
@Override
public void actionPerformed(ActionEvent e) {
square_Block(0);
nextMove();
square_Block(3);
System.out.println(verticalPos);
repaint();
}
答案 1 :(得分:0)
您的设计可能有问题。你需要有一个在一个单独的线程中运行的游戏循环。它必须是与主线程分开的线程,因此用户仍然可以单击按钮。一旦你在单独的线程中有一个循环,你需要有一个方法,你可以为每个游戏滴答调用。在那种方法中,您可以更新块的坐标。
游戏循环的工作方式如下: 1.阅读游戏状态并绘制块 2.处理用户输入。 3.更新游戏状态
我知道这是抽象的,但我希望它有所帮助。 Google关于java游戏和游戏循环。