我正在研究一個簡單的「彈跳球」 - Java中的動畫。這個想法是,它首先會產生一個直線移動的球,直到碰到面板邊界,這會導致它像預期的那樣反彈。然後,您可以用鼠標點擊x,y位置產生更多的球。到現在爲止還挺好。如何用多個線程同時繪製雙緩衝Java動畫?
我的問題是,每個球開始自己的線程,並且每個線程以自己的間隔單獨繪製到面板中,導致面板像瘋了似的閃爍。我知道這樣的問題可以通過實施雙緩衝來解決,我已經讀過,但從來沒有用過我自己。
我想知道如何在這裏使用雙緩衝,如果有多個線程同時繪製可能是一個問題(或相反,甚至是常態)?
非常感謝!
下面的代碼:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
class MyCanvas extends JPanel
{
MyCanvas()
{
setBackground(Color.white);
setForeground(Color.black);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
}
public Dimension getMinimumSize()
{
return new Dimension(300,300);
}
public Dimension getPreferredSize()
{
return getMinimumSize();
}
}
public class BouncingBalls extends JFrame // main class
{
MyCanvas m_gamefield;
public BouncingBalls()
{
setLayout(new BorderLayout());
m_gamefield = new MyCanvas();
add("Center",m_gamefield);
m_gamefield.addMouseListener(new MeinMausAdapter());
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public void letsgo()
{
Ball first = new Ball(m_gamefield,200,50);
first.start();
}
class MeinMausAdapter extends MouseAdapter
{
public void mousePressed(MouseEvent e)
{
Ball next = new Ball(m_gamefield,e.getX(),e.getY());
next.start();
}
}
public static void main(String[] args)
{
BouncingBalls test = new BouncingBalls();
test.setVisible(true);
test.pack();
test.letsgo();
}
}
class Ball extends Thread
{
JPanel m_display;
int m_xPos,m_yPos;
int m_dx = 2; // Steps into direction x or y
int m_dy = 2;
Ball(JPanel c,int x,int y)
{
m_display = c;
m_xPos = x;
m_yPos = y;
}
public void run()
{
paintBall(); // Paint at starting position
while(isInterrupted() == false)
{
moveBall();
try
{
sleep(20);
}
catch(InterruptedException e)
{
return;
}
}
}
void paintBall()
{
Graphics g = m_display.getGraphics();
g.fillOval(m_xPos, m_yPos, 20, 20);
g.dispose();
}
void moveBall()
{
int xNew, yNew;
Dimension m;
Graphics g;
g = m_display.getGraphics();
m = m_display.getSize();
xNew = m_xPos + m_dx;
yNew = m_yPos + m_dy;
// Collision detection with borders, "bouncing off":
if(xNew < 0)
{
xNew = 0;
m_dx = -m_dx;
}
if(xNew + 20 >= m.width)
{
xNew = m.width - 20;
m_dx = -m_dx;
}
if(yNew < 0)
{
yNew = 0;
m_dy = -m_dy;
}
if(yNew + 20 >= m.height)
{
yNew = m.height - 20;
m_dy = -m_dy;
}
g.setColor(m_display.getBackground()); // Erases last position by
g.fillRect(m_xPos-2, m_yPos-2, m_xPos+22, m_yPos+22); // painting over it in white
m_xPos = xNew;
m_yPos = yNew;
paintBall(); // paint new position of Ball
g.dispose();
}
}
由調用'做的getGraphics()'上'Component'在一個形式或其他遲早會打破任何繪畫。這根本不是你在AWT/Swing中繪畫的方式。你應該閱讀http://docs.oracle。com/javase/tutorial/uiswing/painting /。除此之外:每個球的一個線程是一個總的矯枉過正。一個線程可以處理1000個球。也許你應該解釋你想用這些線程來實現什麼。他們在這裏不會帶來任何好處。如果你有,也許,100000個球,並想通過10個線程來做*運動,那麼OK。但繪畫仍然由一個線程完成。 – Marco13