2016-03-19 8 views
0

Java Swing’de yeniyim ve GameRoom’a sahip bir sunucu üzerinden çok oyunculuları destekleyen Connect 4 Oyunu oluşturmaya çalışıyorum. Neredeyse 2 gün boyunca bu özel problem üzerinde çalışıyorum ve çözerken Thread.sleep kullanımını durdurma ve Game nesnesinin sunucuya doğru ve sunucudan aktarıldığını iyice test ettim.Java Swing 2K Döşeme Zamanlayıcıları ile yeniden boyama değil Panellerin Ardışıklığı

Yapım şeklim, her hareketin modelin taşıma komutu aracılığıyla gönderilmesidir. GUI'yi yenilemek için sunucu yeni bir Game nesnesini modele geri gönderir ve 'setRepaint' denetleyici özniteliğini true olarak işaretler. Ardından, bir zamanlayıcı bu özniteliğin doğru olup olmadığını periyodik olarak kontrol eder ve repaintGrid() yöntemini çağırır.

Çalışmaya çalışmak için saatlerce çalıştıktan sonra, oyun panellerinin yeniden boyamasını sağlayamıyorum. yardımcı olabilecek

bazı noktalar: Ben uygulamadan çıkın Eğer

  • ve bunu zaten hamle olan bir oyun nesnesi ile yeniden başlatın, paneller boyanır. Sorun, yeniden boyama yöntemidir.

  • Model statiktir ve her zaman Connect4App.model.getGameFromServer() çağrıldığında Game özniteliği güncelleştirilir. Bunun sorunlara neden olabileceğinden emin değilim, ancak kırmızı/mavi olarak yeniden boyanmış olan panelleri yazdırıyorsam, oyun nesnesinin her yinelemede sunucu tarafından başarıyla güncellendiğini doğrulayabilirim.

  • Çerçeve hiyerarşisi şu şekildedir: guiMain, her biri bir GridPanel paneli tarafından doldurulan bir gridlayout'a sahip olan gamePanel için bir kapsayıcıdır. Izgara paneller esas Connect4 Oyunu simgeleri için yuvaları vardır ve bu ben Herhangi bir yardım mutluluk duyacağız

    import java.awt.GridLayout; 
    import java.awt.event.ActionEvent; 
    import java.awt.event.ActionListener; 
    import java.awt.event.MouseAdapter; 
    import java.awt.event.MouseEvent; 
    import javax.swing.JPanel; 
    import javax.swing.Timer; 
    
    public class GameController { 
    
    MouseAdapter me; 
    private JPanel gamePanel; 
    private boolean setRepaint = false; 
    
    /** 
    * Constructor for the Game Controller. Takes in a view and a model 
    * 
    * @param view 
    * @param model 
    */ 
    public GameController() { 
        setupGridPanels(); 
        setupMouseAdapter(); 
        Connect4App.frame.setContentPane(Connect4App.guiMain); 
        Connect4App.frame.setTitle("Game View"); 
        goIntoTimer(); 
    
    } 
    
    /** 
    * Repaint Boolean used by timer. Set to true by external program 
    */ 
    public void setRepaint() { 
        this.setRepaint = true; 
    } 
    
    /** 
    * Swing Timer which checks if it needs to repaint every 8 seconds and if 
    * so, calls repaintGrid 
    */ 
    private void goIntoTimer() { 
        Timer timer = new Timer(50, new ActionListener() { 
         @Override 
         public void actionPerformed(ActionEvent e) { 
          Connect4App.model.getGameFromServer(); 
    
          if (setRepaint == true) { 
           repaintGrid(); 
           setRepaint = false; 
          } 
    
         } 
        }); 
        timer.setRepeats(true); 
        timer.setDelay(8000); 
        timer.start(); 
    
    } 
    
    /** 
    * Sets up the Initial Game Panels in the Connect4App.guiMain panel 
    */ 
    private void setupGridPanels() { 
        this.gamePanel = new JPanel(); 
        this.gamePanel.removeAll(); 
    
        // setting up the layout for, the game board. 
        this.gamePanel.setLayout(new GridLayout(0, Connect4App.model.getGame().getGrid()[0].length)); 
    
        int numberOfRows = Connect4App.model.getGame().getGrid().length; 
        int numberOfColumns = Connect4App.model.getGame().getGrid()[0].length; 
    
        for (int r = 0; r < numberOfRows; r++) { 
         for (int c = 0; c < numberOfColumns; c++) { 
          Connect4App.guiMain.setCircleArc(r, c, new GridPanel(r, c)); 
          this.gamePanel.add(Connect4App.guiMain.getCircleArcs()[r][c]); 
         } 
        } 
        Connect4App.guiMain.add(this.gamePanel); 
    } 
    
    /** 
    * Sets up the mouse pressed event handleres for every panel 
    */ 
    private void setupMouseAdapter() { 
        MouseAdapter mc = new MouseAdapter() { 
    
         @Override 
         public void mousePressed(MouseEvent mc) { 
    
          GridPanel cell = (GridPanel) mc.getSource(); 
    
          // this is the column that should go in the MakeMove message 
          int column = cell.getColumn(); 
          int row = cell.getRow(); 
    
          if (Connect4App.model.getGame().getGrid()[row][column].getState() == 0) { 
           System.out.println("attempting to make move"); 
           Connect4App.model.makeMove(column); 
          } 
         } 
        }; 
    
        for (int r = 0; r < Connect4App.model.getGame().getGrid().length; r++) { 
         for (int c = 0; c < Connect4App.model.getGame().getGrid()[0].length; c++) { 
          Connect4App.guiMain.getCircleArcs()[r][c].addMouseListener(mc); 
         } 
        } 
    } 
    
    void repaintGrid() { 
    
        // --> This is supposed to be working 
        System.out.println("repainting"); 
    
        for (int r = 0; r < Connect4App.model.getGame().getGrid().length; r++) { 
         for (int c = 0; c < Connect4App.model.getGame().getGrid()[0].length; c++) { 
          Connect4App.guiMain.getCircleArcs()[r][c].validate(); 
          Connect4App.guiMain.getCircleArcs()[r][c].repaint(); 
         } 
        } 
    } 
    } 
    

repaintGrid yönteminde güncellemeyi deneyin olanlardır :-D

+0

Bir sorun olabilecek statik kullanımı yapılmış gibi görünüyor. – MadProgrammer

+0

durum değişkenini okuyan/yazan iş parçacıkları arasında da bir sorun olabilir. Cevabınız @MadProgrammer için teşekkürler. Test ettim ve bu durum, paintComponent yönteminin yeniden boyamakla çağrıldığı noktada düzgün olarak güncelleniyor gibi görünüyor: -s – mageofzema

+0

Döngülerin içinde bir hata ayıklama mesajı yazdırabilir misiniz? (Ayrıca, yanılıyor olabilirim ama emin misiniz? Validate() 'doğrudur? Nasıl revalidate()' veya 'invalidate() 'hakkında? Bu böyle bir şey yaptıktan sonra bir süre var.) –

cevap

0

Aynı nesneyi geri gönderirken bir sorunla karşılaştım ve dördünüzü tekrarlamayarak objectoutputstreams (oyun durumu) ve bu da istemcinin tüm zamanları güncellememesine neden oluyordu. Yukarıdaki repainting kodu çalışıyordu. İpliği kapatmak, tekrar teşekkürler.