我已被指派制作黑杰克游戏。我希望在圆形结束时按下按钮可重放。我已经设置了它,所以我有一个名为initGame()的方法,每个玩家和经销商各自玩一张牌,并启用玩家[]按钮。然后它运行runGame(),它应该检查玩家是否完成了游戏(超过21 /按住)。
当所有玩家都被取消时,然后将运行设置为false,启用resetbutton,然后运行initGame()。我有点希望它像这样循环。但是,当initNewGame()工作正常时,游戏第二次运行runGame()时冻结。
private void initNewGame(){
dealer.addCard();
for(int i = 0; i < numberofplayers; i++){
players[i].addCard(); //draws card, adds score and paints card to the board
players[i].setStatus(false); //makes the buttons usable in the players[] class
}
runGame();
}
/*
* runGame() is meant to check if the players all have played out their hand, to then allow the dealer to play his. After that it sets running = false, allowing the player to either use the shuffle button or start a new game
*/
private void runGame(){
while(running){
int count=0;
for(int i = 0; i<numberofplayers; i++){ //loops through all the player checking their status
if(players[i].getStatus()) count++;
}
if(count==numberofplayers){ //checks if all players have >=21 or have pressed stay
dealer.addCard(); //plays the dealers hand
if(dealer.getPoints() >=19){ //stops when dealer have >=19
running = false; //stops entire loop
}
}
}
}
class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e){
if(!running){ //won't allow players to reset while a round is playing
if(e.getSource().equals(resetbutton)){ //Checks for rese/new game button
System.out.println("reset");
dealer.setPoints(0); //sets dealers hand to 0
dealer.paintText(); //updates delaers painted score
dealer.clearCards(); //clear the painted cards
for(int i = 0; i < numberofplayers; i++){
players[i].setPoints(0);
players[i].clearCards();
players[i].paintText();
}
gui.repaint();
running = true; //allows the runGame() to start
initNewGame(); //this one works the second time
}else if(e.getSource().equals(shufflebutton)){
d1.shuffleDeck();
System.out.println(running);
}
}
}
}
答案 0 :(得分:3)
您的问题是由于您的while循环阻止了GUI的事件线程,冻结了GUI。但更重要的是......
你看起来像是一个Swing GUI(你不能告诉我们,所以我根据有一个ActionListener来猜测)。如果是这样,您需要重新考虑您的程序流程和结构,以使其符合事件驱动的编程原则。你应该摆脱那个while (running)
循环,而是让你的班为其轮到的玩家提供一个字段,并让程序在每个玩家转弯后更改该字段的值。
举一个非常简单的例子,这里有一个小型GUI,一次显示一个活跃的玩家。如果单击活动播放器,则下一个播放器变为活动状态。没有涉及while循环,而是在需要时更改程序的状态:
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;
@SuppressWarnings("serial")
public class CardGameGui extends JPanel {
public static final String[] PLAYER_NAMES = {"John", "Bill", "Frank", "Andy"};
private static final Color ACTIVE_BG = Color.pink;
// a Map that allows us to associate a JLabel with a CardPlayer
private Map<CardPlayer, JLabel> playerLabelMap = new HashMap<CardPlayer, JLabel>();
private CardPlayers cardPlayers = new CardPlayers(PLAYER_NAMES);
public CardPlayer currentPlayer = cardPlayers.getCurrentPlayer();
public CardGameGui() {
setLayout(new GridLayout(1, 0, 5, 0));
for (CardPlayer cardPlayer : cardPlayers) {
JLabel playerLabel = createPlayerLabel(cardPlayer);
playerLabelMap.put(cardPlayer, playerLabel);
add(playerLabel);
}
playerLabelMap.get(currentPlayer).setBackground(ACTIVE_BG);
cardPlayers.addPropertyChangeListener(new CardPlayersListener());
}
private JLabel createPlayerLabel(CardPlayer player) {
JLabel label = new JLabel(player.getName());
label.setOpaque(true);
int ebGap = 15;
label.setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
label.addMouseListener(new PlayerLabelListener());
return label;
}
public void activateCurrentLabel(CardPlayer currentPlayer) {
for (CardPlayer cardPlayer : cardPlayers) {
playerLabelMap.get(cardPlayer).setBackground(null);
}
playerLabelMap.get(currentPlayer).setBackground(ACTIVE_BG);
}
private class CardPlayersListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (CardPlayers.CARD_PLAYER.equals(evt.getPropertyName())) {
currentPlayer = cardPlayers.getCurrentPlayer();
System.out.println(currentPlayer);
activateCurrentLabel(currentPlayer);
}
}
}
private class PlayerLabelListener extends MouseAdapter {
@Override
public void mousePressed(MouseEvent mEvt) {
JLabel playerLabel = (JLabel) mEvt.getSource();
JLabel currentPlayerLabel = playerLabelMap.get(currentPlayer);
if (playerLabel == currentPlayerLabel) {
cardPlayers.incrementPlayerIndex();
}
}
}
private static void createAndShowGui() {
CardGameGui mainPanel = new CardGameGui();
JFrame frame = new JFrame("CardGame");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class CardPlayers implements Iterable<CardPlayer> {
public static final String CARD_PLAYER = "card player";
private List<CardPlayer> playerList = new ArrayList<>();
private int currentPlayerIndex = 0;
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(
this);
public CardPlayers(String[] playerNames) {
for (String playerName : playerNames) {
playerList.add(new CardPlayer(playerName));
}
}
public CardPlayer getCurrentPlayer() {
return playerList.get(currentPlayerIndex);
}
public void incrementPlayerIndex() {
CardPlayer oldValue = getCurrentPlayer();
currentPlayerIndex++;
currentPlayerIndex %= playerList.size();
CardPlayer newValue = getCurrentPlayer();
pcSupport.firePropertyChange(CARD_PLAYER, oldValue, newValue);
}
@Override
public Iterator<CardPlayer> iterator() {
return playerList.iterator();
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
}
class CardPlayer {
private String name;
public CardPlayer(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "CardPlayer: " + name;
}
}
答案 1 :(得分:0)
问题是你调用了initNewGame();从事件处理程序代码中。 您应该使用与第一个initNewGame调用中相同的线程或创建一个新线程。