class BallPanel
extends JPanel {
private ArrayList balls ;
public BallPanel(){
this.balls = new ArrayList();
this.setFocusable(true);
this.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent event){
moveBalls();
}
}
);
}
public void addBall(Ball b) {
this.balls.add(b);
} public void moveBalls() {
if(balls.size()==0)
return ;
for (int i = 0; i < balls.size(); i++) {
Ball b = (Ball) balls.get(i);
b.move();
}
repaint();
} public void paintComponent(Graphics g) {
super.paintComponents(g);
Graphics2D g2 = (Graphics2D) g;
System.out.println("size is :" + balls.size());
for (int i = 0; i < balls.size(); i++) {
Ball b = (Ball) balls.get(i);
b.draw(g2);
}
}
}class Ball {
private int x = 0;
private int y = 0;
private int xBound = 400;
private int yBound = 400;
public final int XSIZE = 10; //球宽度
public final int YSIZE = 10; //球高度
public int dx = 10;//横向位移距离
public int dy = 10; //纵向位移距离
public Ball(int x, int y, int xBound, int yBound) {
this.x = x;
this.y = y;
this.xBound = xBound;
this.yBound = yBound;
}
public void move() {
x += dx;
y += dy;
if (x < 0) {
x = 0;
dx = -dx;
}
if (x + XSIZE >= xBound) {
x = xBound - XSIZE;
dx = -dx;
}
if (y < 0) {
y = 0;
dy = -dy;
}
if (y + YSIZE >= yBound) {
y = yBound - YSIZE;
dy = -dy;
}
} public void draw(Graphics2D g2) {
g2.fill(new Ellipse2D.Double(x, y, XSIZE, YSIZE));
}
}class BallShowThread extends Thread{
private BallPanel bPanel;
public BallShowThread(BallPanel bPanel){
this.bPanel = bPanel;
}
public void run(){
try {
for(int i=0;i<1000;i++){
this.bPanel.moveBalls();
Thread.sleep(5);
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
extends JPanel {
private ArrayList balls ;
public BallPanel(){
this.balls = new ArrayList();
this.setFocusable(true);
this.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent event){
moveBalls();
}
}
);
}
public void addBall(Ball b) {
this.balls.add(b);
} public void moveBalls() {
if(balls.size()==0)
return ;
for (int i = 0; i < balls.size(); i++) {
Ball b = (Ball) balls.get(i);
b.move();
}
repaint();
} public void paintComponent(Graphics g) {
super.paintComponents(g);
Graphics2D g2 = (Graphics2D) g;
System.out.println("size is :" + balls.size());
for (int i = 0; i < balls.size(); i++) {
Ball b = (Ball) balls.get(i);
b.draw(g2);
}
}
}class Ball {
private int x = 0;
private int y = 0;
private int xBound = 400;
private int yBound = 400;
public final int XSIZE = 10; //球宽度
public final int YSIZE = 10; //球高度
public int dx = 10;//横向位移距离
public int dy = 10; //纵向位移距离
public Ball(int x, int y, int xBound, int yBound) {
this.x = x;
this.y = y;
this.xBound = xBound;
this.yBound = yBound;
}
public void move() {
x += dx;
y += dy;
if (x < 0) {
x = 0;
dx = -dx;
}
if (x + XSIZE >= xBound) {
x = xBound - XSIZE;
dx = -dx;
}
if (y < 0) {
y = 0;
dy = -dy;
}
if (y + YSIZE >= yBound) {
y = yBound - YSIZE;
dy = -dy;
}
} public void draw(Graphics2D g2) {
g2.fill(new Ellipse2D.Double(x, y, XSIZE, YSIZE));
}
}class BallShowThread extends Thread{
private BallPanel bPanel;
public BallShowThread(BallPanel bPanel){
this.bPanel = bPanel;
}
public void run(){
try {
for(int i=0;i<1000;i++){
this.bPanel.moveBalls();
Thread.sleep(5);
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
我觉得你应该在
repaint();
前面将前面的小球清除掉现在的结果是这个小球的运行痕迹
if(balls.size()==0)
return ;
for (int i = 0; i < balls.size(); i++) {
//for (int i = 0; i < 1; i++) {
Ball b = (Ball) balls.get(i);
b.move();
}
//updateUI();
//paint();
repaint();
} public void paintComponent(Graphics g) {
super.paintComponents(g);
Graphics2D g2 = (Graphics2D) g;
System.out.println("size is :" + balls.size());
for (int i = 0; i < balls.size(); i++) {
Ball b = (Ball) balls.get(i);
b.draw(g2);
}
}目前肯定这段代码有问题
try {
for(int i=0;i<1000;i++){
this.bPanel.moveBalls();
repaint();------------------------------加上这句
Thread.sleep(5);
}
}
catch (Exception ex) {
ex.printStackTrace();
}
} 能达到你要的效果,每次移动球时要去掉以前的球的轨迹
但是,我想不明白为什么。
请高手指点原理,为什么alickma(零缺点)的办法可行。
//-----记录小球的原始位置--------
private int xOld = 0;
private int yOld = 0;
private int x = 0;
private int y = 0;
private int xBound = 400;
private int yBound = 400;
public final int XSIZE = 10; //球宽度
public final int YSIZE = 10; //球高度
public int dx = 10;//横向位移距离
public int dy = 10; //纵向位移距离
public Ball(int x, int y, int xBound, int yBound) {
this.x = x;
this.y = y;
this.xBound = xBound;
this.yBound = yBound;
}
public void move() {
//--记录小球的原始位置----
xOld = x;
yOld = y;
x += dx;
y += dy;
if (x < 0) {
x = 0;
dx = -dx;
}
if (x + XSIZE >= xBound) {
x = xBound - XSIZE;
dx = -dx;
}
if (y < 0) {
y = 0;
dy = -dy;
}
if (y + YSIZE >= yBound) {
y = yBound - YSIZE;
dy = -dy;
}
}
public void draw(Graphics2D g2) {
// 擦除原来位置上的小球
g2.setXORMode(g2.getBackground());
g2.fill(new Ellipse2D.Double(xOld, yOld, XSIZE, YSIZE));
// 重画新位置的小球
g2.fill(new Ellipse2D.Double(x, y, XSIZE, YSIZE));
}
}
这个用这个 class Ball 替换你的 原来的Ball。这段代码还有问题,主要是 xOld,yOld
记录的值,有时候不是小球的上一此出现的坐标,你调试调试,原理就是这样的。