我正在尝试开发一个棋盘格,给定类(class)模板和一些学校代码。我让棋盘出现,但没有绘制适量的棋子。应该有 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);
}
}
最佳答案
如果您已遵循 previous question 中的一些建议您可能已经避免了这个问题。
据我所知,您的问题是您没有调用 super.paint
,它负责(以及许多其他事情)准备图形
> 绘画的背景。它通过清除之前绘制的内容来实现此目的。
您应该从 JPanel
之类的东西开始,而不是覆盖 JApplet
的 paint
(这会在小程序更新时导致闪烁)重写它的 paintComponent
方法。 JPanel
是双缓冲的,这将防止发生任何闪烁。不要忘记调用 super.paintComponent
。
您不应该在每次调用 paint
时都调用 fillBorder
,这在很多层面上都是浪费,相反,您应该仅在需要时调用它。通过更巧妙的设计,您实际上可以从构造函数中调用它,但我没有时间重新编码整个程序。
小程序的大小是由包含它的 HTML 页面定义的,而不是小程序本身,依赖魔数(Magic Number)(例如 APP_WIDTH
和 APP_HEIGHT
)是一个坏主意。相反,您应该依赖已知值,例如 getWidth
和 getHeight
。当然,这是假设您希望能够调整可玩区域的大小,并避免人们以错误的大小部署您的小程序时可能出现的问题;)
虽然,我猜测 placeCheckers
是一种测试方法,但您应该知道,paint 可以出于多种原因被调用任意多次,其中许多原因是您无法控制的,这意味着每次调用 paint
时,跳棋都会被随机化。
相反,您应该考虑创建一个虚拟板,其中包含有关游戏状态的信息并根据需要进行更新。然后,您只需使用绘画过程来反射(reflect)该模型。
我如何“开始”的一个例子......
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
的占用
状态分配回您传递的值,这对任何事情都没有影响
相反,它应该看起来更像......
public void setOccupy(boolean occupied) {
this.occupied = occupied;
}
关于java - 棋盘未绘制正确数量的棋子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21355769/