2017-07-21 5 views
1

Ich bin neu zu Java und versuchen, einen einfachen Spieler gegen Computer "Tic-Tac-Toe" Spiel mit Swing- zu machen. In dem Code verwende ich paintComponent() Methode, um bestimmte Komponenten zu malen und rufen Sie die repaint() Methode, nachdem der Player oder Computer spielt. Das Problem ist, dass das Spiel nach dem dritten (manchmal dem zweiten) Mal einfriert, wenn ich mit der Maus klicke. In GameWindow class erstelle ich die Instanz Map Klasse. HierProbleme mit repaint() -Methode in java

public class GameWindow extends JFrame{ 

    private final int sizeX = 3; 
    private final int sizeY = 3; 

    public GameWindow(){ 

     setLocation(400,150); 
     setSize(406, 452); 
     setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     setResizable(false); 

     Map map = new Map(sizeX, sizeY); 
     add(map, BorderLayout.CENTER); 
     JPanel bottomPanel = new JPanel(); 
     bottomPanel.setLayout(new GridLayout(1, 2)); 
     add(bottomPanel, BorderLayout.SOUTH); 

     Button newGame = new Button("Новая игра"); 
     newGame.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("Начинаем новую игру"); 
      } 
     }); 
     Button exit = new Button("Выход"); 
     exit.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.exit(0); 
      } 
     }); 

     bottomPanel.add(newGame); 
     bottomPanel.add(exit); 

     setVisible(true); 
    } 
} 

ist der Hörer für die per Mausklick in der Map Klasse:

public class Map extends JPanel { 

private final int sizeX; 
private final int sizeY; 
private int cellWidth; 
private int cellHeight; 
private int cellX = -1; 
private int cellY = -1; 
private String lastPlayer = "nobody"; 

private String[][] table = new String[3][3]; 

public Map(int sizeX, int sizeY) { 

    this.sizeX = sizeX; 
    this.sizeY = sizeY; 
    setBackground(Color.WHITE); 

    for (int i = 0; i < table.length; i++) { 

     for (int j = 0; j < table.length; j++) { 

      table[i][j] = "empty"; 
     } 
    } 

    addMouseListener(new MouseAdapter() { 
     @Override 
     public void mouseReleased(MouseEvent e) { 
      super.mouseReleased(e); 

      cellX = e.getX()/cellWidth; 
      cellY = e.getY()/cellHeight; 

      if (!winOrDraw()) { 
       boolean playerProgress = playerProgress(); 
       if(playerProgress) { 
        botProgress(); 
       } 
      } 
     } 
    }); 
} 

Sowohl in playerProgress() und botProgress() Methoden I repaint() Methode aufrufen, neue Komponenten zum Bildschirm hinzuzufügen. Ich kann nicht wirklich herausfinden, was das Problem in diesem Code ist und warum das Programm nach dem tatsächlichen 6. Aufruf von repaint() Methode einfriert?

Hier sind winOrDraw(), playerProgress() und botProgress() Methoden:

private boolean winOrDraw(){ 

    for (int i = 0; i < table.length; i++) { 

     if(table[i][0] == table[i][1] && table[i][1] == table[i][2] && !table[i][0].equals("empty")) return true; 
     else if(table[0][i] == table[1][i] && table[1][i] == table[2][i] && !table[0][i].equals("empty")) return true; 
     else if(table[0][0] == table[1][1] && table[1][1] == table[2][2] && !table[0][0].equals("empty")) return true; 
     else if(table[2][0] == table[1][1] && table[1][1] == table[0][2] && !table[2][0].equals("empty")) return true; 
    } 

    int i, j = 0; 
    for (i = 0; i < table.length; i++) { 

     for (j = 0; j < table.length; j++) { 

      if(table[i][j].equals("empty")) break; 
     } 
    } 
    if(i == table.length && j == table.length) { lastPlayer = "nobody"; return true; } 
    else return false; 
} 

private boolean playerProgress(){ 

    if(!table[cellY][cellX].equals("empty")){ 
     System.out.println("This cell is not empty"); 
     return false; 
    } else { 
     lastPlayer = table[cellY][cellX] = "player"; 
     repaint(); 
     return true; 
    } 
} 

private void botProgress(){ 

    do{ 
     if(winOrDraw()){ 

      switch (lastPlayer) { 
       case "player": 

        System.out.println("You won!"); 
        System.exit(0); 
       case "bot": 

        System.out.println("Bot won"); 
        System.exit(0); 
       default: 

        System.out.println("Draw"); 
        System.exit(0); 
      } 
     } 
     Random random = new Random(); 
     cellX = random.nextInt(2); 
     cellY = random.nextInt(2); 

     if(table[cellY][cellX].equals("empty")) { 

      lastPlayer = table[cellY][cellX] = "bot"; 
      break; 
     } 
    }while (!table[cellY][cellX].equals("empty")); 

    System.out.println("Bot's turn"); 
    repaint(); 
} 
+0

Aktien winOrDraw() und botProgress() Methoden –

+0

@AndriiBugai Ich habe meine Frage bearbeitet und hinzugefügt früher diese Methoden –

+1

Für eine bessere Hilfe eine richtige [MCVE] veröffentlichen, müssen wir wissen, was im Inneren des 'paintcomponent ist()' – Frakcool

Antwort

0

Sie fügen Ihre Swing-Komponenten direkt an die JFrame-AWT-Container. Das solltest du nicht tun. Stattdessen sollten Sie Folgendes tun:

JPanel panel = new JPanel(); 
myFrame.setContentPane(panel); 

panel.setLayout(...) 
panel.add(...); 
panel.validate(); 

Dies sollte Ihr Problem lösen.