Wie kann ich eine collision detection für die Paddles in meinem Pong Programm hinzufügen?

NadimArazi

Neues Mitglied
Code:

import javax.swing.*;
import java.awt.*;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import java.applet.Applet;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.Color;
import java.lang.Math;
import java.util.Random;
import java.lang.Thread;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.*;

public class Pong extends Frame implements MouseListener, KeyListener {
static int breite=1280,hoehe=1024,punkte;
int max_zahl = 1;
int trefferspieler1=0;
int trefferspieler2=0;
public static int x = 60; //X-Position (Paddle 1)
public static int y = 420; //Y-Position (Paddle 1)
public static int x1 = 1210; //X-Position (Paddle 2)
public static int y1 = 420; //Y-Position (Paddle 2)
int xb = 512;
int yb = 400;

Ball b;
private Image dbImage;
private Graphics dbg;

public static void main(String args[]){
Pong f = new Pong("Pong - Informatik Wb - Projekt Marcel");
f.setSize(breite,hoehe);
f.setBackground(Color.black);
f.setVisible(true);
}

public void update(Graphics g) {
if(dbImage==null)
{
dbImage=createImage(this.getSize().width, this.getSize().height);
dbg=dbImage.getGraphics();
}

dbg.setColor(getBackground());
dbg.fillRect(0,0,this.getSize().width, this.getSize().height);
dbg.setColor(getForeground());
paint(dbg);
g.drawImage(dbImage,0,0,this);
}

public Pong(String s){
super(s);
this.addWindowListener (new WindowAdapter(){ //Interaktion mit dem Fenster (schließen)
public void windowClosing(WindowEvent e){
dispose();
System.exit(0);
}
});

Color farbe=Color.RED;
b = new Ball(this,xb,yb,14,farbe); //Startposition Ball (x, y, Größe, farbe)
addMouseListener(this);
addKeyListener(this);
}

//Punktestand (verbuggt)
public void paint(Graphics f){
b.maleball(f);
b.collision();
f.setColor(Color.white);
f.drawString("Punktestand Spieler 1: "+ trefferspieler1,breite/2-400, hoehe-40); //Punktestand position
f.drawString("Punktestand Spieler 2: "+ trefferspieler2,breite/2+250, hoehe-40); //Punktestand position
f.fillRect(breite/2, 0, 8, hoehe); //Mittellinie
f.setColor(Color.blue);
f.fillRect(x, y, 8, 150); //Paddle 1
f.fillRect(x1, y1, 8, 150); //Paddle 2 (x, y , Breite, Länge)
}

public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}

public void keyTyped(KeyEvent e) {
if (e.getKeyChar()=='w') { // Paddle 1 nach oben
System.out.println("Taste w gedrückt");
y = y - 50;
repaint();
if (y < 10){
y = y + 50;
repaint();
}
}

if (e.getKeyChar()=='s') { // Paddle 1 nach unten
System.out.println("Taste s gedrückt");
y = y + 50;
repaint();
if (y > 900){
y = y - 50;
repaint();
}
}

if (e.getKeyChar()=='o') { // Paddle 2 nach oben
System.out.println("Taste a gedrückt");
y1 = y1 - 50;
repaint();
if (y1 < 10){
y1 = y1 + 50;
repaint();
}
}

if (e.getKeyChar()=='l') { // Paddle 2 nach unten
System.out.println("Taste d gedrückt");
y1 = y1 + 50;
repaint();
if (y1 > 900){
y1 = y1 - 50;
repaint();
}
}

if (e.getKeyChar()=='r') { // Reset der beiden Paddles
System.out.println("Taste r gedrückt");
trefferspieler1 = 0;
trefferspieler2 = 0;
y = 420;
y1 = 420;
repaint();
}
}

public void keyPressed(KeyEvent e) {
System.out.println("KeyReleased: ");
if(e.getKeyCode() == KeyEvent.VK_SPACE){
System.out.println("Programmabbruch!");
System.exit(0);
}
System.out.println("Taste: " + e.getKeyChar() + ", Code: " + e.getKeyCode());
System.out.println("---");
}

public void keyReleased(KeyEvent e) {
}
}

//Bewegung des Balls
class Ball extends Thread{
int x,y,r,xr=2,yr=3;
int xb = 512;
int yb = 400;
private int p = Pong.x;
private int p1 = Pong.y;

Color farbe;
boolean sichtbar=true;
Pong b;

public Ball(Pong e,int xk,int yk,int rk,Color kfarbe){
farbe=kfarbe;
b=e;
r=rk;
xb=xk;
yb=yk;
this.start();
}

public void maleball(Graphics g){ //Draw Ball
if (sichtbar==true){
g.setColor(farbe);
g.fillOval(xb,yb,r*3,r*3); //Position vom Ball (Draw)
}
}

public void collision(){
for(;😉{
System.out.println(p);
break;
}
if(xb <= 0){ //Links respawn
xb=512;
yb=420;
b.repaint();
}

if(xb == p){
xb=xb+xr;
yb=yb+yr;
b.repaint();
}

if(xb >= 1230){ //Rechts respawn
xb=512;
yb=420;
b.repaint();
}
}

// Bewegung des Balls + Einfallswinkel = Ausfallswinkel + Geschwindigkeit
public void run(){
for(;😉{
try {this.sleep(6);} //Geschwindigkeit des Balls
catch(InterruptedException e){}
xb=xb-xr;
yb=yb-yr;
if( (xb<=0) || (xb>=(b.breite-2*r)) ) xr = -xr; // Breite X (Border)
if( (yb<=20) || (yb>=(b.hoehe-2*r)) ) yr = -yr; // Höhe Y (Border)
b.repaint();
}
}
}
 
Code bitte immer in Code-Tags posten (also über den Knopf </> links oberhalb des Eingabebereichs) da sonst Teile interpretiert werden und die Einrückung verloren geht.

Dann ggf. als erstes den Code besser strukturieren - das ist so schon extrem schwer verständlich, was Du da überhaupt machen willst.

Und dann ist es nie eine gute Idee, uns einfach sowas hin zu werfen. Wir werden Deine Aufgaben nicht machen. Also die Antwort auf:

Wie kann ich eine collision detection für die Paddles in meinem Pong Programm hinzufügen?​

ist aus meiner Sicht ganz einfach zu beantworten:
Pass den Code einfach entsprechend an! Also ganz einfach:
- Code in einem Editor oder einer Entwicklungsumgebung öffnen
- Mit der Tastatur den Text ("Java Code") so anpassen, dass eine Collision mit den Paddles erkannt und darauf entsprechend reagiert wird.

Sorry, aber:
- Was hast Du probiert?
- Was für Ergebnisse hast Du bekommen? Auf was für Probleme bist Du gestoßen?
 
Aber mal etwas Feedback zu dem Code selbst:

a) Sinnvolle Namen! x, y, x1, y1, xb, yb, b, e, ... Sorry, aber bit so variablen ist Dein Code kaum lesbar. paddle1X wäre z.B. deutlich besser um zu wissen, dass etwas die X-Koordinate von paddle1 ist .. (Nicht wirklich durchdacht - nur einfach eine idee die ganz spontan kommt. Wenn einem etwas besseres einfällt, dann benennt man etwas um.

b) Wieso sind einige Elemente des Paddle static? Das sieht direkt schlecht aus. Versuche, wirklich nur die main Methode und Konstanten static zu haben (Letztere sind dann auch final!).

c) Abhängigkeiten evtl. besser trennen. Irgendwie brauchen beide Klassen Wissen zu der jeweils anderen. Das sieht schon nicht gut aus. Dass ggf. etwas trennen. Genau überlegen, was welche Instanz wirklich wissen muss.

d) Der ganze Aufbau ist wenig durchdacht. Ständige redraw() Aufrufe sind ein Zeichen für schlechten Aufbau.

Was hast Du denn?
a) Du hast diverse Objekte. Diese haben eine Form und werden auf dem Spielfeld dargestellt.
b) Du hast natürlich das Spielfeld. Das kennt alle Objekte.
c) Du hast eine Oberfläche, diese kann das Spielfeld darstellen und Nutzereingaben auswerten.

Die Logik muss man da dann etwas eingliedern: Die Tasten können die Paddle Objekte anpassen. Das ist eine einfache Positionänderung. Die Oberfläche gibt das aber einfach an das Spielfeld, also sowas wie "Spieler Eins Paddle hoch" - und dann kann das Spielfeld schauen, ob das Objekt Paddle vom Spieler 1 noch hoch gehen kann oder nicht... Da ist dann die Logik.

So Spiele haben auch in der Regel genau EINE! Loop. Und die steuert das Spiel. Das kann eine eigene Klasse sein oder auch gerne im Spielfeld sein.
Dies
- führt also alle Bewegungen aus.
- prüft Kollisionen
- aktualisiert ein Bild
- Stellt das Bild dann der Oberfläche zur Verfügung (da wäre dann ein Repaint-Event). Hier dann auch unterschiedliche Bilder nutzen, also es wird ein Bild gerade angezeigt und ein anderes wird gemalt. Es ist blöd, wenn das Bild, das gerade erstellt wird, auch gerade gemalt wird oder wenn Du bei der Anzeige erst alles mögliche rechnest und malst.

Das wäre dann ein möglicher Aufbau.

Generell beim Code sind dann gewisse Dinge anzumerken:
Java:
        for(;;){
            System.out.println(p);
            break;
        }
Ok, Endlosschleife - war wohl ein Versuch der Collisionsberechnung. Aber du rufst das im paint auf! Das muss schnell gehen. So eine Schleife ist ein absolutes NO GO!
Und das ist natürlich auch keine Schleife - hast ja sofort ein break;

Java:
        if (e.getKeyChar()=='l') { // Paddle 2 nach unten
            System.out.println("Taste d gedrückt");
            y1 = y1 + 50;
            repaint();
            if (y1 > 900){
                y1 = y1 - 50;
                repaint();
            }
        }
Was rufst Du ständig überall repaint() auf? Wenn die Taste gedrückt wurde, dann mach was zu tun ist und am Ende rufst Du einmal repaint() auf. Das muss man nicht spammen! (Also so wie da ggf. zwei Mal aufrufen). Aber das entfällt dann hoffentlich mit einer Umstrukturierung wie oben angedeutet.

Ball ist keine public class - hast Du die mit in der anderen Datei drin? Bitte so Klassne eine eigene Datei gönnen. Das ist aber nur eine Kleinigkeit und nicht so wichtig. Aber ist auch etwas aufgefallen. (Ob public oder nicht ist egal - bei public wäre dies nur von java erzwungen worden.)

Das wäre so ein Feedback von meiner Seite.
 

Neue Themen


Zurück
Oben