Guten Tag.
Ich habe das Bouncing Balls Programm geschrieben und es funktioniert auch. Die Bälle stoßen sich an den Wänden ab. (Gegeneinander noch nicht, aber das tut nichts zur sache)
Mein Programm sieht folgender maßen aus:
BallFrame
BallList
Ball
ShapePanel
Das Problem ist, wenn ich einen neuen Ball hinzufüge, erstelle ich einen neuen Thread, was ja Kontraproduktiv ist. Wie programmiere ich es am besten um, dass ich nur 1 Thread erzeuge?
Ich habe das Bouncing Balls Programm geschrieben und es funktioniert auch. Die Bälle stoßen sich an den Wänden ab. (Gegeneinander noch nicht, aber das tut nichts zur sache)
Mein Programm sieht folgender maßen aus:
Java:
public class BouncingBalls {
public static void main(String args[]) {
BallFrame bb = new BallFrame();
}
}
BallFrame
Java:
public class BallFrame extends JFrame{
private ShapePanel drawPanel;
private BallList ballList;
public BallFrame() {
setTitle("Bouncing Balls");
setSize(400, 400);
setLayout(new BorderLayout());
ballList=new BallList();
drawPanel=new ShapePanel(ballList, this);
//Liste mit den Bällen
add(drawPanel, BorderLayout.CENTER);
setVisible(true);
//mit 'X' beenden
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
);
//verschiedene Tasten und deren Funktionen
addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent e){
switch(e.getKeyChar()){
case '+': //Bälle hinzufügen
ballList.addBall(drawPanel);
break;
case '-': //Bälle entfernen
ballList.removeBall();
break;
case 'g': //Bälle größer machen
ballList.setSize(ballList.getSize()+5);
for (Ball b:ballList.getBalls()){
b.bigger();
}
break;
case 'k': //Bälle kleiner machen
ballList.setSize(ballList.getSize()-5);
for(Ball b:ballList.getBalls()){
b.smaller();
}
break;
case 's': //Bälle schneller machen
ballList.setSpeed(ballList.getSpeed()-5);
for(Ball b:ballList.getBalls()){
b.faster();
}
break;
case 'l': //Bälle langsamer machen
ballList.setSpeed(ballList.getSpeed()+5);
for(Ball b:ballList.getBalls()){
b.slower();
}
break;
}
}
}
);
}
//Getter und Setter Methoden
public ShapePanel getDrawPanel() {
return drawPanel;
}
public void setDrawPanel(ShapePanel drawPanel) {
this.drawPanel = drawPanel;
}
public BallList getBallList() {
return ballList;
}
public void setBallList(BallList ballList) {
this.ballList = ballList;
}
}
BallList
Java:
public class BallList extends Thread{
private ArrayList<Ball> balls;
private int speed=50;
private int size=50;
public BallList() {
balls=new ArrayList();
}
public synchronized void addBall(ShapePanel drawPanel){
Ball newBall = new Ball(drawPanel, size, speed);
balls.add(newBall);
newBall.start();
}
public synchronized void removeBall(){
balls.remove(balls.get(balls.size()-1));
}
public ArrayList<Ball> getBalls() {
return balls;
}
public void setBalls(ArrayList<Ball> balls) {
this.balls = balls;
}
public int getBallListSize(){
return this.balls.size();
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}
Ball
Java:
public class Ball extends Thread{
private ShapePanel drawPanel;
private Ellipse2D.Double thisBall;
private boolean ballStarted;
private int size, speed, deltax, deltay;
public Ball(ShapePanel dP, int sz, int sp) {
drawPanel=dP;
ballStarted=true; //benötigt für Dauerschleife
size=sz;
speed=sp; //benötigt für sleep von Thread
deltax=10; //Speed X Achse
deltay=10; //Speed Y Achse
int startx=(int)(Math.random()*300); //Start Position X&Y
int starty=(int)(Math.random()*300);
thisBall=new Ellipse2D.Double(startx, starty, size, size); //ertselle einen Ball
}
public void draw(Graphics2D g2d){ //Ball zeichenen
if(thisBall!=null){
g2d.setColor(Color.red);
g2d.fill(thisBall);
}
}
public void run(){
while(ballStarted){ //Endlosschleife
try{
Thread.sleep(speed); //verlangsamen
}catch (InterruptedException e){
}
int newx=(int)thisBall.getX()+deltax;
int newy=(int)thisBall.getY()+deltay;
if(newx+size>drawPanel.getWidth()||newx<0){ //Links oder rechts angestößen?
deltax= -deltax; //dann andere Richtung
}
if(newy+size>drawPanel.getHeight()||newy<0){ //Oben oder Unten angsetoßen?
deltay= -deltay; //Dann andere Richtung
}
thisBall.setFrame(newx, newy, size, size);
drawPanel.repaint();
}
}
public synchronized void bigger(){
this.setSize(this.getSize()+5);
}
public synchronized void smaller(){
this.setSize(this.getSize()-5);
}
public synchronized void slower(){
this.setSpeed(this.getSpeed()+5);
}
public synchronized void faster(){
this.setSpeed(this.getSpeed()-5);
}
Getter und Setter Methoden
...
ShapePanel
Java:
public class ShapePanel extends JPanel{
private int wid, ht;
private BallList bb;
public ShapePanel(BallList b2, BallFrame f) {
this.wid = f.getWidth();
this.ht = f.getHeight();
bb=b2;
}
public void paintComponent(Graphics g){ //Bälle im JPanel zeichnen
super.paintComponent(g);
Graphics2D g2d=(Graphics2D)g;
for(int i=0; i<bb.getBalls().size(); i++){
bb.getBalls().get(i).draw(g2d);
}
}
//Getter und Setter Methoden
Das Problem ist, wenn ich einen neuen Ball hinzufüge, erstelle ich einen neuen Thread, was ja Kontraproduktiv ist. Wie programmiere ich es am besten um, dass ich nur 1 Thread erzeuge?