Ball (unendlich)

Java20134

Bekanntes Mitglied
Hallo,

Ich habe ein kleines Programm entwickelt, wo der Ball immer am Frame Ende in die andere Richtung geht, so sieht der Code aus:
Java:
import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JOptionPane;;

public class Ball extends JFrame implements Runnable {

	private static final long serialVersionUID = -7732404558283274691L;
	private double x = 225, y = 275, radius = 20; 
	private double speedY = 5.0; 

	public static void main(String[] args){
		Ball frame = new Ball();
		frame.setVisible(true);
		
		new Thread(frame).start();
	}
	
	public Ball(){
		setTitle("Ball");
		setBounds(100,100,500,600); 
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	public void paint(Graphics g){
		g.setColor(Color.RED);
		g.fillOval((int) x, (int) y, (int) radius*2, (int) radius*2);
	}

	public void run() {
		while(true){
			try{
				y += speedY; 
				
				if(y >= getHeight()-radius*2){
					speedY = -speedY; 
				}
				
				repaint();
				
				Thread.sleep(20); //20ms
			}
			catch(InterruptedException e){
				JOptionPane.showMessageDialog(null, "Error: " +e, "Fehler!", JOptionPane.ERROR_MESSAGE);
			}
		}
	}
}
Mein Problem dabei ist, das der Ball immer wieder gezeichnet wird und der vorherige sozusagen nicht gelöscht wird, so dass man immer nur "einen" sieht. Warum???
 
Das sieht also so aus:
Java:
*
*
*
*
*
*
*
Ohne das sich der vorherige Ball (Stern) löscht.
 
Zuletzt bearbeitet:
Du könntest daraus

Java:
public void paint(Graphics g){
   g.setColor(Color.RED);
   g.fillOval((int) x, (int) y, (int) radius*2, (int) radius*2);
}

sowas machen:
Java:
public void paint(Graphics g){
   g.setColor(Color.White);
   g.fillRect(100, 100, 500, 600);
   g.setColor(Color.RED);
   g.fillOval((int) x, (int) y, (int) radius*2, (int) radius*2);
}

Die Maße musst du selber finden, habe da einfach deine Zahlen reingesetzt, aber in dieser Richtung wirst du glaub ich fündig!
 
Da entsteht ja aber der mal nur aller 20 ms bei mir. Das ist ja nicht das Ziel. Der Ball soll die ganze Zeit angezeigt werden, er soll sich sozusagen, so bewegen wie ein Ball sich ganz normal bewegt.
 
warte mal in deiner schleife kürzer, nur 12ms oder so. eine "flüssige" bewegung hätte unendlich viele einzelbilder. Man nähert sich dieser Zahl in dem man den Bildschirm so oft neuzeichnen lässt, dass das auge den unterschied (kaum) bemerkt
 
Das bringt nichts, desto kleiner die Zahl, desto schneller ist optisch das Programm. Und desto größer die Zahl ist, desto langsamer ist optisch das Programm.
 
ok, habs mal selber ausgeführt, du meinst das flimmern 😀
also ich hab das programm mal ganz bisschen umgeschrieben. und zwar wird deine animation nun in einem JPanel angezeigt, welches seine paintComponent Methode überschreibt. da funktioniert es plötzlich.
generell bietet es sich an solche sachen in einem eigenem Panel durchzuführen

mal der Code:
Java:
package hsBremerhaven;

    import java.awt.Color;
import java.awt.Graphics;
     

    import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
     
    public class Ball extends JPanel implements Runnable {
     
        private static final long serialVersionUID = -7732404558283274691L;
        private double x = 225, y = 275, radius = 20;
        private double speedY = 5.0;
       
     
        public static void main(String[] args){
            JFrame frame = new JFrame();
            Ball ball = new Ball();
            frame.add(ball);

            frame.setTitle("Ball");
            frame.setBounds(100,100,500,600);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
            frame.setVisible(true);
           
            new Thread(ball).start();
        }
       
        public Ball(){
        }
       
        @Override
        public void paintComponent(Graphics g){
        	super.paintComponent(g);
        	g.setColor(Color.WHITE);
        	g.fillRect(0, 0, 500, 600);
            g.setColor(Color.RED);
            g.fillOval((int) x, (int) y, (int) radius*2, (int) radius*2);
        }
     
        public void run() {
            while(true){
                try{
                    y += speedY;
                   
                    if(y >= getHeight()-radius*2){
                        speedY = -speedY;
                    }
                   
                    repaint();
                   
                    Thread.sleep(20); //20ms
                }
                catch(InterruptedException e){
                    JOptionPane.showMessageDialog(null, "Error: " +e, "Fehler!", JOptionPane.ERROR_MESSAGE);
                }
            }
        }
    }
 
Es funktioniert, vielen DANK! Eine Frage hätte ich aber noch. Was mach ich mit dieser Zeile, erstelle ich da ein Objekt oder was mache ich damit? Oder ist es das Panel?
Java:
Ball ball = new Ball();
 
Zuletzt bearbeitet:
Es funktioniert, vielen DANK! Eine Frage hätte ich aber noch. Was mach ich mit dieser Zeile, erstelle ich da ein Objekt oder was mache ich damit? Oder ist es das Panel?

Java:
Ball ball = new Ball();

Du erstellst ein Objekt vom Typ Ball, welches von JPanel erbt und das Interface Runnable implementiert. Also erstellst du das Objekt, welches aber auch ein Panel ist!
 
Zuletzt bearbeitet:
Ich habe es etwas weiter geschrieben und habe eine Frage. Das Rechteck soll sich bewegen, es funktioniert aber nicht, warum?
Java:
private double spielerX = 100;
	g.setColor(Color.GREEN);
	g.fillRect((int) (getWidth()*0.5), (int) (getHeight()-20), (int) spielerX, 20);
	public void keyPressed(KeyEvent e){
		if(e.getKeyCode() == KeyEvent.VK_LEFT){
			spielerX += 5; 
		}
		
		if(e.getKeyCode() == KeyEvent.VK_RIGHT){
			spielerX -= 5; 
		}
               repaint();
	}
Ich müsste ja einen ActionListener hinzufügen, gibt es das bei einer Zeichnung bzw. was würde man sonst noch für das Rechteck nehmen können, Button, Label, ...? Und wie müsste ich das dann schreiben?
 
Zuletzt bearbeitet:

Neue Themen


Zurück
Oben