0

我正在编写一个简单的纸牌游戏。当你点击一副牌时,它会抽一张牌,然后它应该会弹出一个消息对话框,说明轮到玩家 2 了。但是,被移除并涂到玩家 1 手上的牌会被 JOptionPane 消息对话框打断,它会创建一个工件(我的意思是它会涂上手中的牌,但也会在牌组和你的牌组之间随机绘制手。)在 AI 响应和 JOptionPane.showMessageDialog 上的 SwingUtilities.invokeLater 似乎是合乎逻辑的选择,但它会导致代码执行两次,让玩家 2(一个 AI)两个回合。使用 invokeAndWait 会引发错误,因为它是从 EDT 调用的,所以我没有选择。我将如何摆脱工件?http://i1065.photobucket.com/albums/u400/mfgravesjr/go%20fish%20screenshot_zpsxav4hn59.png

这是每一堆卡片中的鼠标监听器。它是我命名为 Stack 的类的一部分。mouseReleased 中有一个 if 语句,用于查看卡片是否被拖动。如果不是,它将执行 StackRuleConstraints.stackClickAction(),它在下一个代码块中定义。

     private MouseAdapter ml = new MouseAdapter()
     {
        public void mousePressed(MouseEvent e)
        {
           targetCardTable = (CardTable)SwingUtilities.getAncestorOfClass(CardTable.class,selfReference);
           if((rules&INACCESSIBLE)==0)
           {
              if((rules&RECEPTACLE)>0)
              {
                 reasonForRejection = "This stack abides by the RECEPTACLE rule. You cannot draw cards from this pile.";
                 if(printRuleRejections)System.out.println(reasonForRejection);
                 return;
              }
              xOrigin = e.getXOnScreen();
              yOrigin = e.getYOnScreen();

              for(int i = 0; i < cards.size(); i++)
              {
                 if(cards.get(i).getLocationOnScreen().x<xOrigin
                    &&xOrigin<cards.get(i).getLocationOnScreen().x+50
                    &&cards.get(i).getLocationOnScreen().y<yOrigin
                    &&yOrigin<cards.get(i).getLocationOnScreen().y+70)
                    {
                       cardsToRemove.clear();
                       groupedCards = null;
                       if(i!=cards.size()-1)
                       {
                          if((rules&GRAB_FROM_TOP)>0)continue;
                          if((rules&GRAB_BY_GROUP)>0&&i!=cards.size()-1)
                          {
                             groupedCards = new Card[cards.size()-1-i];
                             for(int j = i+1; j < cards.size(); j++)
                             {
                                groupedCards[j-i-1] = cards.get(j);
                                cardsToRemove.add(cards.get(j));
                             }
                          }
                       }
                       if((rules&DRAW_PILE)==0&&!cards.get(i).isSelected())//if the card you clicked is facedown
                       {
                          if(i!=cards.size()-1)
                          {
                             continue; //if it's not the top card, return
                          }
                          else if((rules&FLIPPABLE)>0)//otherwise flip it faceup
                          {
                             cards.get(i).setSelected(true);
                             repaint();
                             return;
                          }
                       }
                       cardOrigin = cards.get(i).getLocationOnScreen();
                       selectedCard = cards.get(i);
                       draggedCardXOffset = xOffset;
                       draggedCardYOffset = yOffset;
                    }
              }
           }
           else
           {
              reasonForRejection = "This stack abides by the INACCESSIBLE rule. You cannot manipulate the cards in this stack.";
              if(printRuleRejections)System.out.println(reasonForRejection);
           }
        }

        public void mouseDragged(MouseEvent e)
        {
           if(!dragging&&selectedCard!=null)
           {
              remove(selectedCard);
              if(cardsToRemove.size()>0)for(int i = 0; i < cardsToRemove.size(); i++){remove(cardsToRemove.get(i));}
              dragging = true;
           }
           mouseX = e.getXOnScreen();
           mouseY = e.getYOnScreen();
           ((CardTable)SwingUtilities.getAncestorOfClass(CardTable.class,selfReference)).repaint();
        }

        public void mouseReleased(MouseEvent e)
        {
           if(dragging)ADDING_CARD_TO_STACK:
           {
              for(Component c: getParent().getComponents())
              {
                 if(c instanceof Stack
                    &&e.getXOnScreen()>c.getLocationOnScreen().x
                    &&e.getXOnScreen()<c.getLocationOnScreen().x+c.getWidth()
                    &&e.getYOnScreen()>c.getLocationOnScreen().y
                    &&e.getYOnScreen()<c.getLocationOnScreen().y+c.getHeight()
                    &&selectedCard!=null)
                    {
                       if((((Stack)c).rules&DRAW_PILE)>0)
                       {
                          reasonForRejection = "This stack abides by the DRAW_PILE rule. You cannot place a card here.";
                          if(printRuleRejections)System.out.println(reasonForRejection);
                          break;
                       }
                       if((((Stack)c).rules&INACCESSIBLE)>0)
                       {
                          reasonForRejection = "This stack abides by the INACCESSIBLE rule. You cannot manipulate the cards in this stack.";
                          if(printRuleRejections)System.out.println(reasonForRejection);
                          break;
                       }
                       if((((Stack)c).rules&AUTO_FACEUP)==0&&!selectedCard.isSelected())
                       {
                          reasonForRejection = "This stack does not abide by the AUTO_FACEUP rule. Cards placed on this stack must be faceup.";
                          if(printRuleRejections)System.out.println(reasonForRejection);
                          break;
                       }
                       if((((Stack)c).rules&ASCENDING)>0&&(((Stack)c).cards.size()>0&&((Stack)c).cards.get(((Stack)c).cards.size()-1).getRank()!=selectedCard.getRank()-1)||(((Stack)c).cards.size()==0&&selectedCard.getRank()!=1&&(((Stack)c).rules&ASCENDING)>0))
                       {
                          reasonForRejection = "This stack abides by the ASCENDING rule. Cards placed on this pile must have a rank equal to one plus the rank of the card below it.";
                          if(printRuleRejections)System.out.println(reasonForRejection);
                          break;
                       }

                       if(((((Stack)c).rules&DESCENDING)>0&&((Stack)c).cards.size()>0&&((Stack)c).cards.get(((Stack)c).cards.size()-1).getRank()!=selectedCard.getRank()+1)||(((Stack)c).cards.size()==0&&selectedCard.getRank()!=13&&(((Stack)c).rules&DESCENDING)>0))
                       {
                          reasonForRejection = "This stack abides by the DESCENDING rule. Cards placed on this pile must have a rank equal to the rank of the card below it, minus one.";
                          if(printRuleRejections)System.out.println(reasonForRejection);
                          break;
                       }
                       if((((Stack)c).rules&SAME_SUITS)>0&&(((Stack)c).cards.size()>0&&((Stack)c).cards.get(((Stack)c).cards.size()-1).getSuit()!=selectedCard.getSuit()))
                       {
                          reasonForRejection = "This stack abides by the SAME_SUITS rule. Cards played on this stack must have the same suit as the card below it.";
                          if(printRuleRejections)System.out.println(reasonForRejection);
                          break;
                       }
                       if((((Stack)c).rules&ALTERNATING_COLORS)>0&&(((Stack)c).cards.size()>0&&((Stack)c).cards.get(((Stack)c).cards.size()-1).getColor()==selectedCard.getColor()))
                       {
                          reasonForRejection = "This stack abides by the ALTERNATING_COLORS rule. Cards played on this stack must have a different color than the card below it.";
                          if(printRuleRejections)System.out.println(reasonForRejection);
                          break;
                       }
                       if(ruleConstraints!=null)if(ruleConstraints.restrictedTo.size()>0)if((rules&RESTRICTED_STACK)>0&&!ruleConstraints.restrictedTo.contains((Stack)c))
                       {
                          reasonForRejection = "The stack you drew this card from abides by the RESTRICTED_STACK rule. The stack you are playing this card on is not contained within the restrictedTo list from the StackRuleConstraints object.";
                          if(printRuleRejections)System.out.println(reasonForRejection);
                          break;
                       }
                       if(((Stack)c).ruleConstraints!=null)if(((Stack)c).ruleConstraints.restrictedFrom.size()>0)if((((Stack)c).rules&RESTRICTED_STACK)>0&&!((Stack)c).ruleConstraints.restrictedFrom.contains(selfReference))
                       {
                          reasonForRejection = "This stack abides by the RESTRICTED_STACK rule. The stack you drew from is not contained within this stack's restrictedFrom list from the StackRuleConstraints object.";
                          if(printRuleRejections)System.out.println(reasonForRejection);
                          break;
                       }

                       ((Stack)c).add(selectedCard);
                       if(groupedCards!=null)for(Card card: groupedCards)((Stack)c).add(card);
                       if((((Stack)c).rules&STACK_ACTION)>0&&((Stack)c).ruleConstraints!=null){((Stack)c).ruleConstraints.stackDropAction();}
                       break ADDING_CARD_TO_STACK;
                    }
              }
              if(dragging&&selectedCard!=null){add(selectedCard);if(groupedCards!=null)for(Card card: groupedCards)add(card);}
           }
           else 
           {
              if((rules&INACCESSIBLE)==0)
              {
                 if((rules&DRAW_PILE)>0&&ruleConstraints!=null)
                 {
                    if(ruleConstraints.recyclePile!=null)
                    {  
                       if(cards.size()==0&&(ruleConstraints.recyclePile.rules&RECYCLABLE)>0)
                       {
                          for(int i = ruleConstraints.recyclePile.cards.size()-1; i >= 0; i--)
                          {
                             Card c = ruleConstraints.recyclePile.cards.get(i);
                             c.setSelected(false);
                             add(c);
                          }
                          ruleConstraints.recyclePile.cards.clear();
                       }
                    }
                    else
                    {
                       reasonForRejection = "This stack abides by the RECYCLABLE rule, but does not have a recycle pile set up to do that.";
                       if(printRuleRejections)System.out.println(reasonForRejection);
                    }
                    if(ruleConstraints.dropPile!=null)
                    {
                       if(cards.size()>0)
                       {
                          if(selectedCard!=null)selectedCard.setSelected(true);
                          else return;
                          dealTo(selectedCard,ruleConstraints.dropPile,true);
                          // remove(selectedCard);
  //                         ruleConstraints.dropPile.add(selectedCard);
                       }
                    }
                    else
                    {
                       reasonForRejection = "This stack abides by the DROP_PILE rule, but does not have a StackRuleConstraints dropPile set up to do that.";
                       if(printRuleRejections)System.out.println(reasonForRejection);
                    }
                 }

                 if((rules&STACK_ACTION)>0&&ruleConstraints!=null)ruleConstraints.stackClickAction();
              }
              else
              {
                 reasonForRejection = "This stack abides by the INACCESSIBLE rule. You cannot manipulate the cards in this stack.";
                 if(printRuleRejections)System.out.println(reasonForRejection);
              }
           }
           selectedCard = null;
           groupedCards = null;
           cardsToRemove.clear();
           dragging = false;

           targetCardTable = (CardTable)SwingUtilities.getAncestorOfClass(CardTable.class,selfReference);
           targetCardTable.repaint();
           if(!targetCardTable.isGameOver())
           {
              if(targetCardTable.isGameWon()){targetCardTable.performGameWonAction();targetCardTable.endGame();}
              if(targetCardTable.isGameLost()){targetCardTable.performGameLostAction();targetCardTable.endGame();}
           }
        }
     };

这是我的 GoFish 游戏的构造函数。

  public GoFish()
  {
     super("Go Fish");
     inquireDialog.setLayout(new GridBagLayout());
     JPanel pnl = new JPanel();
     pnl.setLayout(new GridBagLayout());
     GridBagConstraints gbc = new GridBagConstraints();
     gbc.anchor = gbc.CENTER;
     gbc.weightx = 1;
     gbc.gridy = 1;
     gbc.gridx = 1;
     gbc.gridwidth = 2;
     gbc.insets = new Insets(10,10,10,10);
     pnl.add(spinnerLbl,gbc);
     gbc.gridx = 1;
     gbc.gridwidth = 1;
     gbc.gridy = 2;
     gbc.anchor = gbc.EAST;
     spinner.setPreferredSize(new Dimension(spinner.getPreferredSize().width+15,spinner.getPreferredSize().height));
     tf = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField();
     tf.setEditable(false);
     tf.addKeyListener(ka);
     pnl.add(spinner,gbc);
     gbc.gridx = 2;
     gbc.anchor = gbc.WEST;
     pnl.add(inquireButton,gbc);
     inquireButton.addActionListener(this);
     inquireDialog.add(pnl);
     inquireDialog.setSize(400,150);
     WindowPositioner.setLocation(inquireDialog,WindowPositioner.CENTER,false);
     inquire.add(inquireLbl);
     inquire.addActionListener(this);
     ws = getWorkspace();
     ws.setLayout(new BorderLayout());
     player1PairLbl.setForeground(Color.WHITE);
     player2PairLbl.setForeground(Color.WHITE);
     player1SidePnl.setLayout(new BorderLayout());
     player2SidePnl.setLayout(new BorderLayout());
     centerPnl.setLayout(new GridBagLayout());
     player2Hand.setStackRules(Stack.INACCESSIBLE);
     src = new StackRuleConstraints()
     {
        public void stackClickAction()
        {
           // SwingUtilities.invokeLater(new Runnable(){public void run(){

              deck.setStackRules(Stack.INACCESSIBLE);
              if(player1Hand.cards.get(player1Hand.cards.size()-1).getRankText().equals(inquireText))
              {
                 inquire.setEnabled(true);
                 player1Hand.setStackRules(player1HandStackRules);
              }
              else
              {
                 status.setStatus("Player 2's turn.");
                 JOptionPane.showMessageDialog(null,"Player 2's turn.");
                 while(true)
                 {
                    for(int rank = 1; rank <= 13; rank++)
                    {
                       int cardCount = 0;
                       Card[] pair = new Card[2];
                       for(Card c: player2Hand.cards)
                       {
                          if(c.getRank()==rank)cardCount++;
                       }
                       if(cardCount>=2)
                       {
                          int i = 0;
                          for(Card c: player2Hand.cards)
                          {
                             if(c.getRank()==rank){pair[i] = c;i++;}
                             if(i==2){for(Card c2: pair)player2Hand.dealTo(c2,playStack2,true);break;}
                          }
                       }
                    }
                    if(isGameWon())performGameWonAction();
                    if(isGameLost())performGameLostAction();
                    if(isGameWon()||isGameLost())endGame();
                    if(isGameOver()) return;
                    //EASY
                    if(difficultySetting==0)try{
                    String cardInquiry = player2Hand.cards.get(new Random().nextInt(player2Hand.cards.size())).getRankText();
                    JOptionPane.showMessageDialog(null,"Player 2 is fishing for "+cardInquiry+(cardInquiry.equals("Six")?"e":"")+"s.");
                    CHECKING:
                    {
                       for(int i = 0; i < player1Hand.cards.size(); i++)
                       {
                          if(player1Hand.cards.get(i).getRankText().equals(cardInquiry)){player1Hand.dealTo(player1Hand.cards.get(i),player2Hand,false);break CHECKING;}
                       }
                       deck.dealTo(player2Hand,false);
                       if(!player2Hand.cards.get(player2Hand.cards.size()-1).getRankText().equals(cardInquiry))
                       {
                          status.setStatus("Player 1's turn.");
                          inquire.setEnabled(true);
                          player1Hand.setStackRules(player1HandStackRules);
                          JOptionPane.showMessageDialog(null,"Player 1's turn.");
                          return;
                       }
                    }}
                    catch(IllegalArgumentException e){}
                    //NORMAL
                    else if(difficultySetting==1)
                    {
                       int player2AskCount=Integer.MAX_VALUE;
                       int player1AskCount=0;
                       int player1MaximumCardIndex = -1;
                       int player2MinimumCardIndex = -1;
                       for(int i = 1; i <= 13; i++)
                       {
                          for(Card c: player2Hand.cards)
                          {
                             if(Card.getRankText(i).equals(c.getRankText())&&player1CardTracker[i]>player1AskCount)
                             {
                                player1AskCount = player1CardTracker[i];
                                player1MaximumCardIndex = i;
                             }
                             if(Card.getRankText(i).equals(c.getRankText())&&player2CardTracker[i]<player2AskCount)
                             {
                                player2AskCount = player2CardTracker[i];
                                player2MinimumCardIndex = i;
                             }
                          }
                       }
                       String cardInquiry;
                       if(player1MaximumCardIndex!=-1)
                       {
                          cardInquiry = Card.getRankText(player1MaximumCardIndex);
                       }
                       else
                       {
                          cardInquiry = Card.getRankText(player2MinimumCardIndex);
                          player2CardTracker[player2MinimumCardIndex]++;
                       }
                       JOptionPane.showMessageDialog(null,"Player 2 is fishing for "+cardInquiry+(cardInquiry.equals("Six")?"e":"")+"s.");
                       CHECKING:
                       {
                          for(int i = 0; i < player1Hand.cards.size(); i++)
                          {
                             if(player1Hand.cards.get(i).getRankText().equals(cardInquiry)){player1Hand.dealTo(player1Hand.cards.get(i),player2Hand,false);break CHECKING;}
                          }
                          deck.dealTo(player2Hand,false);
                          if(!player2Hand.cards.get(player2Hand.cards.size()-1).getRankText().equals(cardInquiry))
                          {
                             status.setStatus("Player 1's turn.");
                             inquire.setEnabled(true);
                             player1Hand.setStackRules(player1HandStackRules);
                             JOptionPane.showMessageDialog(null,"Player 1's turn.");
                             return;
                          }
                       }
                    }
                 }
              }
          //  }});
        }
     };
     src.dropPile = player1Hand;
     deckStackRules = deck.getStackRules()|Stack.STACK_ACTION;
     deck.setStackRules(Stack.INACCESSIBLE,src);
     setMainPile(deck);
     src = new StackRuleConstraints()
     {
        public void stackDropAction()
        {
           deck.getStackRuleConstraints().stackClickAction();
        }
     };
     player1Hand.setStackRules(0,src);
     src = new StackRuleConstraints()
     {
        @Override
        public void stackDropAction()
        {
           if(playStack1.cards.size()==2)
           {
              if(playStack1.cards.get(0).getRank()==playStack1.cards.get(1).getRank())
              {
                 addPair(true);
              }
              else
              {
                 playStack1.dealTo(player1Hand,true);
                 playStack1.dealTo(player1Hand,true);
              }
           }
        }
     };
     src.restrictedFrom.add(player1Hand);
     playStack1.setStackRules(Stack.STACK_ACTION|Stack.RESTRICTED_STACK,src);
     src = new StackRuleConstraints()
     {
        @Override
        public void stackDropAction()
        {
           if(playStack2.cards.size()==2)
           {
              if(playStack2.cards.get(0).getRank()==playStack2.cards.get(1).getRank())
              {
                 addPair(false);
              }
              else
              {
                 playStack2.dealTo(player2Hand,false);
                 playStack2.dealTo(player2Hand,false);
              }
           }
        }
     };
     src.restrictedFrom.add(player2Hand);
     playStack2.setStackRules(Stack.STACK_ACTION|Stack.RESTRICTED_STACK,src);
     player1SidePnl.add(player1PairLbl,BorderLayout.NORTH);
     player2SidePnl.add(player2PairLbl,BorderLayout.NORTH);
     player1SidePnl.add(player1CardPairs,BorderLayout.CENTER);
     player2SidePnl.add(player2CardPairs,BorderLayout.CENTER);
     ws.add(player2SidePnl,BorderLayout.WEST);
     gbc.weighty = 1;
     gbc.anchor = gbc.NORTH;
     gbc.insets = new Insets(0,0,10,0);
     gbc.gridy = 0;
     centerPnl.add(player2Hand,gbc);
     gbc.anchor = gbc.CENTER;
     gbc.gridy = 1;
     centerPnl.add(playStack2,gbc);
     gbc.gridy = 2;
     centerPnl.add(deck,gbc);
     gbc.gridy = 3;
     centerPnl.add(playStack1,gbc);
     gbc.anchor = gbc.SOUTH;
     gbc.gridy = 4;
     centerPnl.add(player1Hand,gbc);
     ws.add(centerPnl,BorderLayout.CENTER);
     ws.add(player1SidePnl,BorderLayout.EAST);
     getContentPane().add(status,BorderLayout.SOUTH);
     status.add(inquire,BorderLayout.EAST);
     player1HandStackRules = player1Hand.getStackRules();
     setVisible(true);
     init();
  }

您可以在此处查看完整代码:www.github.com/mfgravesjr 查看名为 projects-in-progress 的存储库。

4

0 回答 0