简体   繁体   English

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

[英]Checkerboard not drawing correct amount of checkers

I am trying to develop a checkerboard given a template of classes and some code for school. 我正在尝试开发一个棋盘,给出一个类的模板和一些学校的代码。 I got the board to appear but the right amount of checkers are not being drawn. 我让董事会出现了,但是没有抽出适量的棋子。 There are supposed to be 7 red and 9 black checkers but each time I run the program a different amount of each is drawn. 应该有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);
}
}

If, you have followed some of the advice from your previous question you may have avoided this issue. 如果您已经遵循了上一个问题的一些建议,那么您可能已经避免了这个问题。

As near as I can tell, your problem is you're not calling super.paint , which is responsible for (amongst a lot of other things) preparing the Graphics context for painting. 就像我所知,你的问题是你不是在调用super.paint ,它负责(在很多其他事情中)为绘画准备Graphics上下文。 It does this, by clearing what ever was painted on it previously. 它通过清除以前在其上绘制的内容来实现此目的。

Instead of overriding paint of JApplet , which will cause flicker when the applet is updated, you should start with something like a JPanel and override it's paintComponent method. 而不是覆盖JApplet paint ,这会在更新applet时导致闪烁,你应该从像JPanel这样的东西开始并覆盖它的paintComponent方法。 JPanel is double buffered, which will prevent any flicker from occuring. JPanel是双缓冲的,可以防止任何闪烁发生。 Don't forget to call super.paintComponent . 别忘了调用super.paintComponent

You shouldn't be calling fillBorder every time paint is called, this is wasteful on a number of levels, instead, you should only call it when you need to. 你不应该叫fillBorder每次paint被调用,这是在多个层面的浪费,相反,你应该只当你需要调用它。 With a little bit more clever design, you could actually get away with calling it from the constructor, but I don't have the time to re-code your entire program. 通过更聪明的设计,您实际上可以从构造函数中调用它,但我没有时间重新编写整个程序。

The size the applet is defined by the HTML page which contains it, not the applet itself, relying on magic numbers (like APP_WIDTH and APP_HEIGHT ) is a bad idea. applet的大小由包含它的HTML页面定义,而不是applet本身,依赖于幻数(如APP_WIDTHAPP_HEIGHT )是一个坏主意。 You should, instead, rely on known values, like getWidth and getHeight . 相反,您应该依赖已知值,例如getWidthgetHeight This of course assumes you'd like to be able to resize the playable area and avoid possible issues with people deploying your applet with the wrong size ;) 这当然假设您希望能够调整可播放区域的大小,并避免人们使用错误的大小部署applet时可能出现的问题;)

While, I'm guessing that placeCheckers is a test method, you should know, paint can be called any number of times for any number of reasons, many of which you don't control, this means that the checkers will be randomized each time paint is called. 虽然,我猜测placeCheckers是一种测试方法,你应该知道,绘画可以因任何原因被调用任意次数,其中许多是你无法控制的,这意味着每次都会随机化棋子paint被称为。

Instead, you should consider creating a virtual board which contains the information about the state of the game and update this as required. 相反,您应该考虑创建一个虚拟板,其中包含有关游戏状态的信息并根据需要进行更新。 You would then simply use the painting process to reflect this model. 然后,您只需使用绘画过程来反映此模型。

An example of how I might "start"... 我如何“开始”的一个例子......

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);
        }

    }
}

Updated 更新

This ones had me scratching me head for a while. 这些让我抓了我一会儿。 Basically, after some additional checking I discovered that the checkers where being allowed to occupy space that was suppose to be already taken. 基本上,在经过一些额外的检查之后,我发现了那些被允许占据空间的检查器,这些空间被认为已经被占用了。 After bashing me head against the do-while loop, I check the setOccupy method and found... 在我反对do-while循环后,我检查了setOccupy方法,发现...

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

You're assiging the Square 's occupied state back to the value you are passing, which has no effect on anything 你将Squareoccupied状态归还给你所经过的价值,这对任何事都没有影响

Instead, it should look more like... 相反,它应该看起来更像......

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

You may also like to have a read through Why CS teachers should stop teaching Java applets 您可能还想阅读为什么CS教师应该停止教Java小程序

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM