0

我有一个问题我正在做一个台球游戏,当我模拟击球时我需要球做出反应,程序的工作原理是这样的,你点击击球的方向和力量,然后点击 go,go 按钮在创建我的标签的 GUI 类中,按钮从我的主类调用一个接收参数的方法,然后在其中一段时间​​,更改球的 X 和 Y,直到功率降低到 0,然后停止,代码正在运行,但球一直移动,直到 while 停止。所以while有效,当power int为0时,while熄灭,然后绘制新的X,Y。

这是按钮调用的函数,按钮发送所有参数

 public void golpe(int pbola, int pvelocidad, String pdireccion, JLabel[] listalabels) throws InterruptedException{

    listabolas[pbola].setVelocidad(pvelocidad);
    listabolas[pbola].setDireccion(pdireccion);

    while (listabolas[pbola].getVelocidad() > 0) {

        moverBola(pbola, listalabels);

        //System.out.println(listabolas[pbola].getPosX());
        //System.out.println(listabolas[pbola].getPosY());

        Thread.sleep(500);

        //This line is supposed to change the X and Y of the object over and over
        //but only does it till the end
        listalabels[pbola].setLocation(listabolas[pbola].getPosX(), listabolas[pbola].getPosY());
    }

}

这是函数 moverbola(),只复制了一个“if”,这样代码看起来不会太大

private void moverBola(int pbola, JLabel[] listalabels) {

    if (listabolas[pbola].getDireccion().equals("SE")) {

        int pposX = listabolas[pbola].getPosX();
        listabolas[pbola].setPosX(pposX + 1);


        int pposY = listabolas[pbola].getPosY();
        listabolas[pbola].setPosY(pposY + 1);


    }
4

1 回答 1

1

Swing 是一个单线程框架。也就是说,与 UI 的所有交互都应发生在单个线程中,称为事件调度线程。

阻止此线程的任何操作都将阻止 EDT 更新屏幕或处理任何新事件。

while-loop正在阻止 EDT,阻止它在while-loop完成之前绘制任何更新。

查看Swing 中的并发以获取更多详细信息。

您可以采取多种方法...

您可以使用Thread,但这会导致问题,因为您需要确保对 UI 所做的任何更改都重新同步回 EDT,这可能会变得混乱......

例如_

您可以使用javax.swing.Timer定期滴答作响的 a ,并且您可以从它的 assign 更新任何内部参数ActionListener。因为刻度事件发生在 EDT 中,所以可以保存以从其中更新屏幕。

例如_

您可以使用 aSwingWorker在后台运行任务。它具有将更新重新同步回 EDT 的方法,但出于您的目的可能有点过头了……

更新了一个可能的Timer例子

警告- 仅使用代码片段很难生成一个合理的示例,但是,这样的事情可能会奏效

public void golpe(final int pbola, int pvelocidad, String pdireccion, final JLabel[] listalabels) throws InterruptedException{

    listabolas[pbola].setVelocidad(pvelocidad);
    listabolas[pbola].setDireccion(pdireccion);

    Timer timer = new Timer(40, new ActionListener() {
        public void actionPerformed(ActionEvent evt) {

            if (listabolas[pbola].getVelocidad() == 0) {
                ((Timer)evt.getSource()).stop();
            } else {            
                moverBola(pbola, listalabels);
            }

        }
    });
    timer.setRepeats(true);
    timer.start();

}
于 2013-08-13T05:56:50.593 回答