用户界面-在Java纸牌游戏中,在每一张牌都发到一只手上后,我该如何短暂地暂停



我正在使用netbeans中的swing用java创建一个21点游戏。牌是按顺序发给玩家的多只手牌和发牌人的。每发一张牌时,带有牌图像的JLabels都会变成jLayerdPanes。我想在发完每一张牌后稍作停顿。目前,你只看到它们同时被处理。这是发放的前四张牌的代码。

    if(hand1.handIsInPlay()==true){
       dealCard(jLPaneHand1,hand1);
       pause();
    }
    if(hand2.handIsInPlay()==true){
       dealCard(jLPaneHand2,hand2);
       pause();
    }
    if(hand3.handIsInPlay()==true){
       dealCard(jLPaneHand3,hand3);
       pause();
    }
    dealCard(jLPaneDealerHand,dealerHand);

这是我尝试过的暂停方法:

public void pause(){
    try {
      Thread.sleep(1000);
    } 
    catch(InterruptedException ex) {
        Thread.currentThread().interrupt();
    }
}

这是我尝试过的第二种暂停方法:

public void pause(){
    try {
        TimeUnit.MILLISECONDS.sleep(1000);
    } 
    catch (InterruptedException e) {
        //Handle exception
    }
}

两者都没有达到预期效果。看起来发生的情况是,如果有三只手在玩,那么程序将总计3x1000ms,等待这个长度,然后一次发完所有的牌。

如何在发完每一张牌后使程序暂停?

您需要记住Thread.sleep是在当前线程中调用的。在带有Swing的Java中,当您触发一个操作时,通常至少会有两个线程——主线程和Swing线程——调用相应的侦听器并执行它的方法——只要这个方法仍在运行,它就不能继续执行其他任务,如。例如重新绘制卡片。

因此,基本上你需要将这个暂停动作移动到其他线程,该线程将命令用例如SwingUtilities.invokeLater绘制卡片的动作,然后等待一段时间,然后再次命令重新绘制,等等

基本上,您需要确保GUI线程没有被阻塞,并且可以一直工作,并且订单来自其他线程,并且它们可以在不打扰用户的情况下休眠。

在您的情况下,所有这些都发生在一个线程中,所以当您调用sleep时,GUI线程会休眠,无法执行任何操作,如绘制您希望它绘制的内容,它会耐心等待,直到您在Swing线程中编写代码停止执行。

编辑:

快速示例-了解确切的需求和代码将使其运行得更好。。。

在听众呼叫中,例如:

new Thread(new CardDealing()).start(); // delegates task to the new thread

而任务看起来像:

public CardDealing extends Runnable {
    // inner data, methods and so on
    public void run() {
        if(hand1.handIsInPlay()==true){
            dealCard(jLPaneHand1,hand1);
            pause();
        }
        if(hand2.handIsInPlay()==true){
            dealCard(jLPaneHand2,hand2);
            pause();
        }
        if(hand3.handIsInPlay()==true){
            dealCard(jLPaneHand3,hand3);
            pause();
        }
        dealCard(jLPaneDealerHand,dealerHand);
    }
    public void dealCards(...) {
         // this part will be run in a non-gui thread - make sure that
         // all calculations and changes in model are made here
         SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                 // this will be run in a swing thread
                 // - make sure that only code dealing directly
                 // with GUI is called here
                 guiDealCards(jPane,hand);
             }
         });
    }
}

当然,根据您的需求,CardDealing类可能会接受参数、包含对某些数据的引用等等,但这是整体设计的问题。GUI和工作线程之间的通信或多或少应该是这样工作的。在这种特殊情况下,您也可以尝试invokeAndWait——只需确保pause()没有在GUI线程内调用(自定义Swing组件、您委托的Runnablespaint方法等)。

编辑2:

您可能会发现这个链接很有帮助——它将帮助您理解Swing是如何工作的,以及为什么您应该将逻辑至少分为两部分:GUI和非GUI。然后不管怎样与dealCards方法中的GUI位置没有直接关系,而guiDealCards中所有与GUI相关的东西-我不知道你在那里到底在做什么,所以我不能为你做这些。

相关内容

  • 没有找到相关文章

最新更新