Ball->Wand Kollision - Ball bleibt an Decke und Boden hängen

Jack159

Bekanntes Mitglied
Ich habe ein Programm mit einer GUI, auf der ein Kreis (Ball) ist und an den 4 Seiten der GUI ist jeweils eine schwarze Wand (Rechteck). Der Kreis ist mit den Pfeiltasten steuerbar. Wenn der Kreis kann nicht durch die Wände durch gehen.
Das funktioniert an der linken und rechten Wand problemlos. An der oberen und unteren Wand allerdings, bleibt der Kreis ab und zu hängen. Mit "hängen bleiben" meine ich, dass ich den Kreis nicht mehr von der Wand wegbewegen kann. Am besten probiert ihr das Programm selbst aus, dann seht ihr wie ich das meine.
Ich weiß absolut nicht, wo der Fehler liegt, da es an den seitlichen Wänden ja perfekt funktioniert und ich es an der oberen+unteren Wand genauso gemacht habe :bahnhof:

Java:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Ellipse2D;
 
import javax.swing.*;
 
public class Second extends JPanel implements ActionListener, KeyListener {
    
    Timer t = new Timer(5, this);
    int xk = 300, yk = 300, velx = 0, vely = 0;
    int xwl, ywl;
    int xwr = 775, ywr;
    int xwo, ywo;
    int xwu, ywu=555;
    boolean links = false;
    boolean rechts = false;
    boolean oben = false;
    boolean unten = false;
    boolean kollision = false;
    Rectangle kreisRec = new Rectangle(xk, yk, 40, 40);
    Rectangle wandLinksRec = new Rectangle(xwl, ywl, 10, 600);
    Rectangle wandRechtsRec = new Rectangle(xwr, ywr, 10, 600);
    Rectangle wandObenRec = new Rectangle(xwo, ywo, 800, 10);
    Rectangle wandUntenRec = new Rectangle(xwu, ywu, 800, 10);
    
    public Second() {
        t.start();
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
    }
    
    // Die 4 Wände werden gezeichnet
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.fill(new Ellipse2D.Double(xk, yk, 40, 40));
        g2.fill(new Rectangle.Double(xwl, ywl, 10, 600));
        g2.fill(new Rectangle.Double(xwr, ywr, 10, 600));
        g2.fill(new Rectangle.Double(xwo, ywo, 800, 10));
        g2.fill(new Rectangle.Double(xwu, ywu, 800, 10));
    }
    
    // Game-Loop
    public void actionPerformed(ActionEvent e) {
        
    
        
        
        
        if(oben) {
            vely = -4;
            velx = 0;
            
        }
    
        if(unten) {
            vely = 4;
            velx = 0;
        }
        
        if (links) {
            vely = 0;
            velx = -4;
        }
        
        if (rechts) {
            vely = 0;
            velx = 4;
        }
        
   
      
        
        if (kreisRec.intersects(wandRechtsRec)){ 
        	
        	velx = 0;
        	
        	if (links) {
        		velx = -4;
        	}
        }
        
        if (kreisRec.intersects(wandLinksRec)){ 
        	
        	velx = 0;
        	
        	if (rechts) {
        		velx = 4;
        	}
        }
        
        if (kreisRec.intersects(wandObenRec)){ 
        	
        	vely = 0;
        	
        	if (oben) {
        		vely = 4;
        	}
        }
        
        if (kreisRec.intersects(wandUntenRec)){ 
        	
        	vely = 0;
        	
        	if (unten) {
        		vely = -4;
        	}
        }
        
        xk +=velx;
        yk +=vely;
        kreisRec.x = xk;
        kreisRec.y = yk;
        wandLinksRec.x = xwl;
        wandLinksRec.y = ywl;
        wandRechtsRec.x = xwr;
        wandRechtsRec.y = ywr;
        wandObenRec.x = xwo;
        wandObenRec.y = ywo;
        wandUntenRec.x = xwu;
        wandUntenRec.y = ywu;
        
        repaint();
        velx = 0;
        vely = 0;
    }
    

    
    
    
 
 
    public void keyTyped(KeyEvent e) {
        
        
        
    }
    
    // KeyListener Code
    public void keyReleased(KeyEvent e) {
        int code = e.getKeyCode();
        if(code == KeyEvent.VK_UP){
            oben = false;
        }
        
        
        if(code == KeyEvent.VK_DOWN){
            unten = false;
        }
        
        
        if(code == KeyEvent.VK_RIGHT){
            rechts = false;
        }
        
        
        if(code == KeyEvent.VK_LEFT){
            links = false;
        }
        
        
    }
    public void keyPressed(KeyEvent e) {
    	int code = e.getKeyCode();
        if(code == KeyEvent.VK_UP){
            oben = true;
        }
        
        
        if(code == KeyEvent.VK_DOWN){
            unten = true;
        }
        
        
        if(code == KeyEvent.VK_RIGHT){
            rechts = true;
        }
        
        
        if(code == KeyEvent.VK_LEFT){
            links = true;
        }
    	
    }
}

Java:
import javax.swing.JFrame;

public class Macheads {

	public static void main(String[] args) {
		JFrame f = new JFrame();
		Second s = new Second();
		f.add(s);
		f.setVisible(true);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setSize(800, 600);
	}
}
 
Deine Kollisionsüberprüfung ist nicht ganz korrekt.
Du bewegst den Ball auf die Wand und im nächsten durchlauf prüfst du erst ob es eine Kollision gibt, wenn ja dann setzt du die Geschwindigkeit auf 0.
Prüfe VOR dem Bewegen ob es dann zu einer Kollision kommt, wenn ja, dann bewegst du den Ball nicht.
Und das "Abprallen" würde ich auch raus nehmen.
 

Zurück
Oben