我正在使用 Java Swing 编写俄罗斯方 block 。 Game 类围绕 JFrame(框架)展开,它由一个扩展方 block 落下的 JPanel(面板)的 TetrisPanel、一个 JLabel (pontok) 点计数器、一个显示高分的 JTextArea (rekord_text) 和另一个显示高分的 JPanel (kovi) 组成。下一个要掉落的方 block 。我的想法是游戏有 3 个难度级别,其中 block 以不同的速度下落。
我认为解决这个问题的最佳方法是使用上面的组件创建一个新的 JFrame,但 block 的速度设置不同。我能够关闭旧的 JFrame。但是,当新的 JFrame 打开时,它只是一个空白框架,并且不会响应关闭窗口。
我应该补充一点,TetrisPanel 正在运行一个线程,但我 90% 确定我用一个 volatile boolean 值来停止它。
Game 类的构造函数:
this.difSet(nehezseg); //this function sets the falling velocity
TetrisPanel.stopped = true; //this static member is the volatile boolean responsible for stopping the thread
new_game = false;
frame = new JFrame("Tetris_alpha");
frame.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
panel = new TetrisPanel();
TetrisPanel.stopped = false;
new Thread(panel).start();
frame.add(panel, c);
pontok = new JLabel ("0");
frame.add(pontok, c);
rekord_text = new JTextArea();
//i set up the area
frame.add(rekord_text, c);
kovi = new NextAktualPanel();
frame.add(kovi, c);
menu = new MyMenu(this);
frame.setJMenuBar(menu);
frame.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent e)
{
rekordok.add(panel.getPont());
rekordok.write(f);
e.getWindow().dispose();
System.exit(0);
}
}
);
frame.pack();
frame.setVisible(true);
}
包含游戏循环的 Game.start() 函数:
public void start()
{
//game_loop
while (!panel.GameOver() && !new_game)
{
if (panel.aktualLeertDetector())
{
panel.addAktualToBlocks();
panel.addNewAktual(next);
Elem temp = new Elem(0,0,rand.nextInt(7));
while (temp.getTipus() == next.getTipus())
temp = new Elem(0,0,rand.nextInt(7));
next = temp;
kovi.setNextAktual (next);
}
if (!paused)
pontok.setText(Integer.toString(panel.getPont()));
kovi.repaint();
panel.repaint();
}
打开新框架的函数:
Public void newGame (Game g)
{
Game.new_game = true;
g.frame.dispose();
Game new_game = new Game("easy");
g = new_game;
g.start();
}
以及TetrisPanel的run()函数:
public static volatile boolean stopped = false;
@Override
public void run() {
while (!stopped)
{
aktual.zuhan();
this.sorTeleAction();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
任何帮助,包括有关不同方法的想法,我们将不胜感激。
最佳答案
- 不要使用 volatile boolean 作为状态变量,而使用 AtomicBoolean 代替,volatile 不是做这种事情的正确方法,而且它也不会导致“立即变量更新”...这不是 volatile 的目的。里>
在主 AWT 线程上启动线程不是一个好主意,您仍然必须使用 SwingUtilities.invokeLater(Runnable runnableAction) 。您可以在启动 Gui 线程时使用类似的内容:
SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { new Thread(threadAction).start(); } catch (Exception e) { } } });
希望这能解决您的问题!
关于java - 创建和丢弃运行线程的 JFrame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59121641/