棋盘没有绘制正确数量的棋子

时间:2014-01-25 20:20:40

标签: java object paint

我正在尝试开发一个棋盘,给出一个类的模板和一些学校的代码。我让董事会出现了,但是没有抽出适量的棋子。应该有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);
}
}

1 个答案:

答案 0 :(得分:2)

如果您已经按照previous question的一些建议进行了操作,那么您可能已经避免了这个问题。

尽我所知,你的问题是你没有打电话给super.paintGraphics负责(在许多其他事情中)为绘画准备paint背景。它通过清除之前绘制的内容来实现这一点。

而不是覆盖JApplet的{​​{1}},这会在更新applet时导致闪烁,而应该从JPanel开始,并覆盖它的paintComponent方法。 JPanel是双缓冲的,可以防止任何闪烁发生。不要忘记致电super.paintComponent

每次调用fillBorder时都不应该调用paint,这在多个级别上都是浪费,相反,您应该只在需要时调用它。通过更聪明的设计,您实际上可以从构造函数中调用它,但我没有时间重新编写整个程序。

applet的大小由包含它的HTML页面定义,而不是applet本身,依赖于幻数(如APP_WIDTHAPP_HEIGHT)是一个坏主意。相反,您应该依赖已知值,例如getWidthgetHeight。这当然假设您希望能够调整可播放区域的大小,并避免人们使用错误的大小部署applet时出现问题;)

虽然,我猜测placeCheckers是一种测试方法,你应该知道,出于各种原因,可以多次调用paint,其中许多是你无法控制的,这意味着每次调用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;
}

您正在将Square的{​​{1}}州指定给您正在传递的值,这对任何事都没有影响

相反,它应该看起来更像......

occupied

您可能还想阅读Why CS teachers should stop teaching Java applets