我正在尝试开发一个棋盘,给出一个类的模板和一些学校的代码。我让董事会出现了,但是没有抽出适量的棋子。应该有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 :(得分:2)
如果您已经按照previous question的一些建议进行了操作,那么您可能已经避免了这个问题。
尽我所知,你的问题是你没有打电话给super.paint
,Graphics
负责(在许多其他事情中)为绘画准备paint
背景。它通过清除之前绘制的内容来实现这一点。
而不是覆盖JApplet
的{{1}},这会在更新applet时导致闪烁,而应该从JPanel
开始,并覆盖它的paintComponent
方法。 JPanel
是双缓冲的,可以防止任何闪烁发生。不要忘记致电super.paintComponent
。
每次调用fillBorder
时都不应该调用paint
,这在多个级别上都是浪费,相反,您应该只在需要时调用它。通过更聪明的设计,您实际上可以从构造函数中调用它,但我没有时间重新编写整个程序。
applet的大小由包含它的HTML页面定义,而不是applet本身,依赖于幻数(如APP_WIDTH
和APP_HEIGHT
)是一个坏主意。相反,您应该依赖已知值,例如getWidth
和getHeight
。这当然假设您希望能够调整可播放区域的大小,并避免人们使用错误的大小部署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