当尝试在 JPanel 上绘图时,JPanel 冻结了我的整个应用程序

发布于 2024-12-19 12:43:05 字数 2148 浏览 1 评论 0原文

我正在为一个学校项目编写俄勒冈小道的代码,并且正在实现狩猎迷你游戏。我们使用带有卡片布局的模型视图演示器。当 HuntingPanel 切换到它时,它会调用 run,并且 JOptionPane 出现,但随后整个应用程序冻结,我必须强制退出。我在一个单独的项目中对整个狩猎游戏进行了编码,现在将文件带到了 Oregon Trail 游戏中。它在自己的项目中使用自己的 JFrame 运行良好。我不知道该怎么办。

我称其为初始化面板、切换到它并运行游戏。

    public void initialize(int ammo) {
         player.setBullets(ammo);
         bulletLabel.setText("Bullets: "+player.getBullets());
         presenter.switchToPanel(OregonTrailPresenter.HUNTING_PANEL);
         run();
     }

这是我的运行方法。

public void run() {
    // starting message
    JOptionPane.showMessageDialog(null, "You have reached a nearby field to hunt. You will stay\nhere until " +
            "you run out of ammunition or click Return to Trail.");
    // while the player has bullets or doesn't click return to trail
    while (player.getBullets() > 0 && stillHunting) {
        // creates random animals
        checkForAnimal();
        // moves and updates screen
        repaint();
        update();

        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    endHunting();
}

这里还有其他使用的方法。

private void checkForAnimal() {
    int x = 0;
    int y = rand.nextInt(MAX_Y)-40;
    int rand1 = rand.nextInt(100);
    String str = null;
    if (rand1 < 50) {
        str = "left";
        x = MAX_X-40;
    }
    else if (rand1 >= 50) {
        str = "right";
        x = 0;
    }

    double gen = rand.nextGaussian(); // gen is a number from -inf to +inf
    gen = Math.abs(gen); // gen is now a number from 0 to inf       
    if (gen >= 1.9 && gen < 2.1) { //1.19%
        animalList.add(new Bunny(x,y,str));
    }
    if(gen >= 2.1 && gen < 2.2) {  //0.9%
        animalList.add(new Bear(x,y,str));
    }
    if (gen >= 2.2 && gen < 2.3) { 
        animalList.add(new Deer(x,y,str));
    } 

}

    public void update() {
    for (int i = 0; i < animalList.size(); i++) {
        animalList.get(i).move();
    }
}

I am coding Oregon Trail for a school project and I am implementing the hunting mini game. We are using model view presenter with a card layout. When the HuntingPanel gets switched to it calls run, and the JOptionPane comes up, but then the whole application freezes and I have to force quit. I coded the entire hunting game in a separate project, and just now brought the files over to the Oregon Trail game. It works fine in its own project with its own JFrame. I'm not sure what to do.

I call this to initialize the panel, switch to it, and run the game.

    public void initialize(int ammo) {
         player.setBullets(ammo);
         bulletLabel.setText("Bullets: "+player.getBullets());
         presenter.switchToPanel(OregonTrailPresenter.HUNTING_PANEL);
         run();
     }

This is my run method.

public void run() {
    // starting message
    JOptionPane.showMessageDialog(null, "You have reached a nearby field to hunt. You will stay\nhere until " +
            "you run out of ammunition or click Return to Trail.");
    // while the player has bullets or doesn't click return to trail
    while (player.getBullets() > 0 && stillHunting) {
        // creates random animals
        checkForAnimal();
        // moves and updates screen
        repaint();
        update();

        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    endHunting();
}

And here are other method used.

private void checkForAnimal() {
    int x = 0;
    int y = rand.nextInt(MAX_Y)-40;
    int rand1 = rand.nextInt(100);
    String str = null;
    if (rand1 < 50) {
        str = "left";
        x = MAX_X-40;
    }
    else if (rand1 >= 50) {
        str = "right";
        x = 0;
    }

    double gen = rand.nextGaussian(); // gen is a number from -inf to +inf
    gen = Math.abs(gen); // gen is now a number from 0 to inf       
    if (gen >= 1.9 && gen < 2.1) { //1.19%
        animalList.add(new Bunny(x,y,str));
    }
    if(gen >= 2.1 && gen < 2.2) {  //0.9%
        animalList.add(new Bear(x,y,str));
    }
    if (gen >= 2.2 && gen < 2.3) { 
        animalList.add(new Deer(x,y,str));
    } 

}

    public void update() {
    for (int i = 0; i < animalList.size(); i++) {
        animalList.get(i).move();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不弃不离 2024-12-26 12:43:05

您必须实现 javax.swing.Timer 而不是 < code>Thread.sleep(int),因为此代码行在 EDT 直到 Thread.sleep(int) 结束。以下是演示,如果 GUI 在 EDT 期间被 Thread.sleep(int) 延迟,会发生什么情况

You have to implement javax.swing.Timer instead of Thread.sleep(int), because this code line freezes all GUI during EDT until Thread.sleep(int) ends. Here is demonstrations what happens if the GUI is delayed during EDT by Thread.sleep(int)

凯凯我们等你回来 2024-12-26 12:43:05

您的程序“冻结”,因为您没有为 while 循环启动新线程。由于面板更新和重绘是在主线程中处理的,因此您可以防止它们发生。要解决此问题,您必须启动一个新线程。您可以通过使您的类实现可运行并使用 new Thread(this).start() 来运行循环来做到这一点。

class HuntingGame extends JPanel implements Runnable {
    public void initialize(int x) {
        //...
        new thread(this).start();// This will run your 'run()' method in a new thread.
    }
}

Your program "freezes" because you did not start a new thread for the while loop. Since the panel updates and redraws are handled in the main thread, you are preventing them from happening. To fix this problem you have to start a new thread. You can do this by making your class implement runnable and use new Thread(this).start() to run your loop.

class HuntingGame extends JPanel implements Runnable {
    public void initialize(int x) {
        //...
        new thread(this).start();// This will run your 'run()' method in a new thread.
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文