2014-01-25 104 views
0

我想開發一個棋盤給予類和學校的代碼模板。我得到了棋盤,但沒有繪製出適量的棋子。應該有7個紅色和9個黑色棋子,但每次運行程序時都會繪製不同的數量。棋盤沒有繪製正確數量的棋子

import java.applet.Applet; 
import java.awt.*; 
import java.util.Random; 
import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.event.*; 

public class Checkers extends JApplet 
{ 
private final int MAX_SIZE = 8; 
private final int APP_WIDTH = 400; 
private final int APP_HEIGHT = 400; 
private final int MAXSIZE = 8; 

Square[][] sq; 

public void paint(Graphics page) 
    { 
    setBackground(Color.white); 
    fillBoard(page); // draws the method that will draw the checkers   
    placeCheckers(page, 7, Color.red); //method to place the red checkers 
    placeCheckers(page, 9, Color.black); //method to draw black checkers 
    CheckJumps(page); //check if checkers can jump  
    setSize (APP_WIDTH,APP_HEIGHT); 

    } 

public void fillBoard(Graphics page) 
{ 
    sq = new Square[8][8]; 

    int x,y; 
    Color rb; 

    for (int row = 0; row < MAXSIZE; row++) 
     for (int col = 0; col < MAXSIZE; col++) 
     { 
     x = row * (APP_WIDTH/MAXSIZE); 
     y = col * (APP_HEIGHT/MAXSIZE); 
     if ((row % 2) == (col % 2)) 
      rb = Color.red; 
     else 
      rb = Color.black; 
     sq[row][col] = new Square (x, y, rb); 
     } 

    for (int row = 0; row < 8; row++) 
     for (int col = 0; col < 8; col++) 
      sq[row][col].draw(page); 
} 

public void placeCheckers (Graphics page, int num_checkers, Color ncolor) 
    { 
    int count, row, col; 
    int x, y; 
    Circle c; 

    Random rand = new Random(); 

    for (count = 0; count < num_checkers; count++) 
    { 
     do 
     { 
     row = rand.nextInt(8); 
     col = rand.nextInt(8); 
     } while (sq[row][col].getOccupy() || ncolor == sq[row][col].getColor()); 

     x = row * (APP_WIDTH/MAXSIZE); 
     y = col * (APP_HEIGHT/MAXSIZE); 

     c = new Circle (x, y, 50, ncolor); 

     c.draw(page); 

     sq[row][col].setOccupy(true); 
    }  
    } 

class Square 
{ 

private int x, y = 0; 
private Color c; 
private boolean occupied; 

public Square (int x, int y, Color c) 
{ 
    this.x = x; 
    this.y = y; 
    this.c = c; 
} 

public void setX (int x) 
{ 
    x = this.x; 
} 

public int getX() 
{ 
    return x; 
} 

public void setY (int y) 
{ 
    y= this.y; 
} 

public int getY() 
{ 
    return y; 
} 

public void setColor (Color c) 
{ 
    c = this.c; 
} 

public Color getColor() 
{ 
    return c; 
} 

public void setOccupy (boolean occupied) 
{ 
    occupied = this.occupied; 
} 

public boolean getOccupy() 
{ 
    return occupied; 
} 

public String toString() 
{ 
    return ("X coordinate: " + x + "\nY coordinate:" + y + "\nSquare color: " + c); 
} 

public void draw (Graphics page) 
    { 
     page.setColor(c); 
     page.fillRect(x, y, 50, 50);  
    } 
} 

class Circle 
{ 


    private int x,y; 
    private int diameter; 
    private Color c; 

    public Circle (int x, int y, int diameter, Color c) 
    { 
     this.x = x; 
     this.y = y; 
     this.diameter = diameter; 
     this.c = c; 
    } 


    public void setX (int x) 
    { 
     x = this.x; 
    } 

    public int getX() 
    { 
     return x; 
    } 

    public void setY (int y) 
    { 
     y= this.y; 
    } 

    public int getY() 
    { 
     return y; 
    } 

    public void setColor (Color c) 
    { 
     c = this.c; 
    } 

    public Color getColor() 
    { 
     return c; 
    } 

    public void setDiameter (int x) 
    { 
     diameter = x; 
    } 


public void draw (Graphics page) 
{ 
    page.setColor(c); 
    page.fillOval(x, y, diameter, diameter); 
} 
} 
+0

有一個讀不要從任何paint方法中調用的setSize ... – MadProgrammer

+0

我註釋掉的setSize,但問題仍然存在。 –

+0

它不會解決手頭的問題,但會解決消耗CPU的提示性衝突的問題。 – MadProgrammer

回答

2

如果你遵循一些從previous question你可能已經避免了這個問題的建議。

就我所知,你的問題是你不打電話super.paint,這是負責(其中很多事情)準備Graphics上下文繪畫。它通過清除之前曾經塗過的東西來做到這一點。

而是壓倒一切的JAppletpaint,當小程序的更新,這將導致閃爍的,你應該像一個JPanel開始,並覆蓋它的paintComponent方法。 JPanel是雙緩衝,這將防止發生任何閃爍。不要忘記撥打super.paintComponent

您不應該每次調用fillBorder時都會調用paint,這在很多級別上都是浪費的,相反,您只應在需要時調用它。使用更巧妙的設計,您可以從構造函數中調用它,但我沒有時間重新編寫整個程序。

小程序的大小由包含它的HTML頁面定義,而不是小程序本身,依靠幻數(如APP_WIDTHAPP_HEIGHT)是一個壞主意。相反,您應該依賴已知的值,如getWidthgetHeight。這當然假設你希望能夠調整可播放區域的大小,並避免人們使用錯誤的大小部署你的applet;

雖然,我猜placeCheckers是一種測試方法,你應該知道,任何數量的原因都可以調用油漆,其中很多原因是你不能控制的,這意味着每次調用paint時,檢查器都會隨機化。相反,您應該考慮創建一個虛擬板,其中包含有關遊戲狀態的信息並根據需要進行更新。然後您可以簡單地使用繪畫過程來反映這個模型。

的我怎麼可能「開始」的例子......

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.util.Random; 
import javax.swing.JApplet; 
import javax.swing.JPanel; 

public class Checkers extends JApplet { 

    @Override 
    public void init() { 
     add(new Board()); 
    } 

    public class Board extends JPanel { 

     private final int APP_WIDTH = 400; 
     private final int APP_HEIGHT = 400; 
     private final int MAXSIZE = 8; 

     Square[][] sq; 

     @Override 
     public void invalidate() { 
      fillBoard(); 
      super.invalidate(); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); //To change body of generated methods, choose Tools | Templates. 
      for (int row = 0; row < 8; row++) { 
       for (int col = 0; col < 8; col++) { 
        sq[row][col].draw(g); 
       } 
      } 
      setBackground(Color.white); 
      placeCheckers(g, 7, Color.red); //method to place the red checkers 
      placeCheckers(g, 9, Color.black); //method to draw black checkers 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(APP_WIDTH, APP_HEIGHT); 
     } 

     public void fillBoard() { 
      sq = new Square[8][8]; 

      int x, y; 
      Color rb; 

      int gridSize = Math.min(getWidth(), getHeight()); 
      int size = gridSize/MAXSIZE; 

      for (int row = 0; row < MAXSIZE; row++) { 
       for (int col = 0; col < MAXSIZE; col++) { 
        x = row * (gridSize/MAXSIZE); 
        y = col * (gridSize/MAXSIZE); 
        if ((row % 2) == (col % 2)) { 
         rb = Color.red; 
        } else { 
         rb = Color.black; 
        } 
        sq[row][col] = new Square(x, y, rb, size); 
       } 
      } 

     } 

     public void placeCheckers(Graphics page, int num_checkers, Color ncolor) { 
      int count, row, col; 
      int x, y; 
      Circle c; 

      int gridSize = Math.min(getWidth(), getHeight()); 
      int size = gridSize/MAXSIZE; 

      Random rand = new Random(); 

      for (count = 0; count < num_checkers; count++) { 
       do { 
        row = rand.nextInt(8); 
        col = rand.nextInt(8); 
       } while (sq[row][col].getOccupy() || ncolor == sq[row][col].getColor()); 

       x = row * (gridSize/MAXSIZE); 
       y = col * (gridSize/MAXSIZE); 

       c = new Circle(x, y, size, ncolor); 

       c.draw(page); 

       sq[row][col].setOccupy(true); 
      } 
     } 

    } 

    class Square { 

     private int x, y = 0; 
     private Color c; 
     private boolean occupied; 
     private int size; 

     public Square(int x, int y, Color c, int size) { 
      this.x = x; 
      this.y = y; 
      this.c = c; 
      this.size = size; 
     } 

     public void setX(int x) { 
      x = this.x; 
     } 

     public int getX() { 
      return x; 
     } 

     public void setY(int y) { 
      y = this.y; 
     } 

     public int getY() { 
      return y; 
     } 

     public void setColor(Color c) { 
      c = this.c; 
     } 

     public Color getColor() { 
      return c; 
     } 

     public void setOccupy(boolean occupied) { 
      occupied = this.occupied; 
     } 

     public boolean getOccupy() { 
      return occupied; 
     } 

     public String toString() { 
      return ("X coordinate: " + x + "\nY coordinate:" + y + "\nSquare color: " + c); 
     } 

     public void draw(Graphics page) { 
      page.setColor(c); 
      page.fillRect(x, y, size, size); 
     } 
    } 

    class Circle { 

     private int x, y; 
     private int diameter; 
     private Color c; 

     public Circle(int x, int y, int diameter, Color c) { 
      this.x = x; 
      this.y = y; 
      this.diameter = diameter; 
      this.c = c; 
     } 

     public void setX(int x) { 
      x = this.x; 
     } 

     public int getX() { 
      return x; 
     } 

     public void setY(int y) { 
      y = this.y; 
     } 

     public int getY() { 
      return y; 
     } 

     public void setColor(Color c) { 
      c = this.c; 
     } 

     public Color getColor() { 
      return c; 
     } 

     public void setDiameter(int x) { 
      diameter = x; 
     } 

     public void draw(Graphics page) { 
      page.setColor(c); 
      page.fillOval(x, y, diameter, diameter); 
     } 

    } 
} 

更新

這那些有我抓我的頭一會兒。基本上,經過一些額外的檢查後,我發現檢查者被允許佔用已被佔用的空間。撲我的頭撞在do-while環後,我檢查setOccupy方法和發現......

public void setOccupy(boolean occupied) { 
    occupied = this.occupied; 
} 

你assiging的Squareoccupied狀態恢復到您傳遞的價值,這對任何事情沒有影響

相反,它應該看起來更像...

public void setOccupy(boolean occupied) { 
    this.occupied = occupied; 
} 

您可能還喜歡通過Why CS teachers should stop teaching Java applets

+0

再一次,非常感謝您在這個問題和最後一個問題之間的幫助,並花時間向我展示什麼是好代碼。不幸的是,我相信我不得不堅持目前的代碼實現。但是,我試着運行你的代碼,同樣的問題仍然存在,我試過調試但都無濟於事。如果您對如何解決這個問題有其他想法,那將非常感激。我猜測它與placeCheckers中的邏輯有關。 –

+0

什麼,你的意思是因爲你每次畫的時候都隨機化這個位置? – MadProgrammer

+0

嗯,項目要求棋子放在棋盤上的隨機方塊中,這就是爲什麼我將它們隨機放在棋盤上的原因。問題是大多數時候只有一些所需的檢查器會出現。我每次運行它時都會繪製9個黑色和7個紅色,但通常每個繪製的軌跡數少於1-2個。有時它會爲一個而不是另一個提供正確的金額。有時它會爲兩者都提供正確的金額,但是對此沒有任何模式。 –